Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2e121d84cc | |||
| f49fd117ac | |||
| 4d7021b101 | |||
| ec1a2963f6 | |||
| 43ee26b856 | |||
| 7079b150a8 | |||
| e94b78610d | |||
| 32433caccf | |||
| 90ca422b15 | |||
| c41b69badf | |||
| 4fc3cd5e7e | |||
| 091685af50 | |||
| e4f405ea9d | |||
| 9b140e85b3 | |||
| ed794d66a0 | |||
| 7f475584d6 | |||
| fe80dbbb73 | |||
| a9fba6c5c3 | |||
| 3f3de726c2 | |||
| 8cbd686f47 | |||
| 1223a705c0 | |||
| eaa9c399be | |||
| 585b508578 | |||
| 36b2b2162c | |||
| 4dcb0dd89e | |||
| 226d61b041 | |||
| 8de2daa716 | |||
| 17b7ef23a1 | |||
| 6e978bfed8 | |||
| 46a159a3bc | |||
| 4893a04f49 | |||
| fbde0c2073 | |||
| 9ef9549f2d | |||
| 55c6f7b05d | |||
| 89b8ea88c1 | |||
| 56e3d37879 | |||
| 889d9cbcbd | |||
| 5033547534 | |||
| e351f57be4 | |||
| dc63b543ac | |||
| 7b7565d5d4 | |||
| 2ed8742f3b | |||
| d5e1fc4300 | |||
| 5393257d93 | |||
| a65a183ee4 | |||
| e4b5992266 | |||
| 351025b4f2 | |||
| f37481627a | |||
| 3230356cd6 | |||
| 62f3d252d8 | |||
| c22cf39ba9 | |||
| 9a7f4f7c67 | |||
| 436680207f | |||
| 390dd63e21 | |||
| c97ca5f21a | |||
| 5a83968813 | |||
| 9f596f30b2 | |||
| c331da5114 | |||
| ecd9de4d4e | |||
| ac03b78708 | |||
| 4e1c1cd6f0 | |||
| b7e65d9100 | |||
| 33bf835b7f | |||
| 0f6a2e21eb | |||
| 81c7a720f5 | |||
| f03f8640d4 | |||
| defc9ca4b5 | |||
| a954d7f90a | |||
| 1b1a7092e5 | |||
| d7282dc33b | |||
| 3ca2518c5c | |||
| bd9aadf0cf | |||
| c6af96b6bc | |||
| 3f8fa6b34e | |||
| fdaaa357d4 | |||
| ea80396828 | |||
| c0735d1d63 | |||
| 5471ea6283 | |||
| 7408616909 | |||
| bf306daea6 |
74
CHANGELOG.md
74
CHANGELOG.md
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: CHANGELOG.md -->
|
<!-- file: CHANGELOG.md -->
|
||||||
<!-- version: 5 -->
|
<!-- version: 22 -->
|
||||||
|
|
||||||
# Changelog Project Governance Rules
|
# Changelog Project Governance Rules
|
||||||
|
|
||||||
@@ -7,6 +7,78 @@ 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.
|
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.5
|
||||||
|
|
||||||
|
- clarifie la sémantique normative de PGR : `MUST / MUST NOT` restent obligatoires, `SHOULD / SHOULD NOT` expriment explicitement une forte recommandation non obligatoire et `MAY` reste une possibilité neutre ;
|
||||||
|
- aligne l’adoption et la validation afin qu’un simple écart à un `SHOULD / SHOULD NOT` ne crée à lui seul ni non-conformité, ni `FAIL` de gate, ni `OVERRIDE` ou justification obligatoire ;
|
||||||
|
- formalise l’autonomie après instanciation/adoption : la baseline locale et ses owners deviennent l’autorité des sessions/releases suivantes, tandis qu’un réalignement PGR futur reste une opération explicite et bornée fondée sur un snapshot choisi ;
|
||||||
|
- fixe la frontière PGR / SaseDev Knowledge : PGR reste auto-suffisant pour ses contrats normatifs, tandis que howtos, recettes, snippets, exemples, dépannage et variantes pratiques peuvent vivre dans une base de connaissances séparée sans devenir une dépendance de PGR ;
|
||||||
|
- réconcilie transversalement les owners concernés sans réécriture mécanique des recommandations existantes et corrige la référence vivante à l’adoption Games vers `0.1.6` ;
|
||||||
|
- confirme par revue d’horizon que l’adoption réelle de `sasedev-games` reste la cible `0.1.6`, suivie de KSP `0.1.7` puis des audits Rust/Clippy `0.1.8`, sans réserver `0.1.9`.
|
||||||
|
|
||||||
|
## 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 ;
|
||||||
|
- renforce le profil Rust/Cargo des nouveaux projets contrôlés avec Rust 2024, chemins explicites, façade crate-root, contrats de suffixes de crates, séparation bibliothèque/exécutable, erreurs explicites et ownership du tracing ;
|
||||||
|
- ajoute et sépare les validations Rust structurelles utiles : complétude des réexports/chemins `crate::Item`, espacement des items, ordre des modules, blocs d'imports de traits et blocs de réexports, tout en conservant les contrôles à ordre sémantique comme opt-in ;
|
||||||
|
- active les profils framework et Tauri 2, avec host Rust direct, frontière frontend explicite, TS-RS pour les DTO partagés, plugins/capabilities gouvernés, versions produit classifiées et exception Tauri encadrée au principe de séparation `lib`/`bin` ;
|
||||||
|
- enregistre le skeleton Tauri contrôlé comme trajectoire `DEFER` jusqu'à matérialisation d'owners Web suffisants, sans créer de skeleton décoratif ni réserver une release ;
|
||||||
|
- réconcilie les décisions avec les corpus KSP/Games, conserve leurs architectures métier locales hors du noyau PGR et prépare le prompt de reprise `006` vers la première baseline réutilisable `0.1.0`.
|
||||||
|
|
||||||
|
## 0.0.4
|
||||||
|
|
||||||
|
- définit un contrat transversal de skeleton specifications pour sélectionner et composer règles, profils, templates, décisions destinataire, overrides et validation sans dupliquer les propriétaires normatifs ;
|
||||||
|
- ajoute une fondation composable de gouvernance locale pour initialiser version, documentation minimale, workflow retenu et validation proportionnée d'un projet utilisant PGR ;
|
||||||
|
- ajoute une spécialisation Rust/Cargo workspace composant la fondation avec les profils `500 + 510` et les cinq templates Rust/Cargo existants ;
|
||||||
|
- explicite les décisions à adapter avant instanciation, notamment version, édition/toolchain, membres, métadonnées, dépendances/features, `Cargo.lock`, lints, chemins d'artefacts et audits facultatifs ;
|
||||||
|
- conserve Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles insuffisamment matérialisées comme domaines différés plutôt que créer des skeletons prématurés.
|
||||||
|
|
||||||
## 0.0.3
|
## 0.0.3
|
||||||
|
|
||||||
- fournit cinq fichiers modèles Rust/Cargo : `rustfmt.toml`, `clippy.toml`, `.cargo/config.toml`, un manifest workspace et un manifest de crate membre, avec instructions d'adaptation ;
|
- fournit cinq fichiers modèles Rust/Cargo : `rustfmt.toml`, `clippy.toml`, `.cargo/config.toml`, un manifest workspace et un manifest de crate membre, avec instructions d'adaptation ;
|
||||||
|
|||||||
20
README.md
20
README.md
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: README.md -->
|
<!-- file: README.md -->
|
||||||
<!-- version: 6 -->
|
<!-- version: 34 -->
|
||||||
|
|
||||||
# Project Governance Rules
|
# Project Governance Rules
|
||||||
|
|
||||||
@@ -11,9 +11,9 @@ Le dépôt officiel est `https://git.sasedev.com/Sasedev/pgr`.
|
|||||||
|
|
||||||
## Statut
|
## Statut
|
||||||
|
|
||||||
PGR est actuellement en phase de fondation `0.0.x`.
|
La stable autoritaire courante est `0.1.5`. Elle stabilise les trois contrats transversaux réconciliés : `SHOULD / SHOULD NOT` est une forte recommandation non obligatoire, la baseline locale d’un projet devient son autorité après instanciation/adoption avec réalignement PGR uniquement explicite, et PGR reste auto-suffisant face aux contenus pratiques externes possibles de SaseDev Knowledge. La revue d’horizon de clôture confirme qu’aucun nouveau prérequis transversal ne doit précéder l’adoption Games : `0.1.6` reste la prochaine release, suivie de KSP `0.1.7` puis des audits Rust/Clippy `0.1.8`, sans réservation de `0.1.9`.
|
||||||
|
|
||||||
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 série `0.0.x` se poursuit avec les spécifications de skeletons prévues pour `0.0.4`.
|
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. La release `0.1.5` stabilise la sémantique `MUST / SHOULD / MAY`, l’autorité de la baseline locale après adoption et le réalignement PGR volontaire, ainsi que la frontière PGR / SaseDev Knowledge ; elle conserve Games `0.1.6`, KSP `0.1.7` et les audits Rust/Clippy `0.1.8` comme scopes distincts.
|
||||||
|
|
||||||
## Entrées principales
|
## Entrées principales
|
||||||
|
|
||||||
@@ -27,6 +27,20 @@ La version courante est définie par [`VERSION`](VERSION). La release `0.0.1` é
|
|||||||
- [`docs/plans/001-V0_0_1_FOUNDATION_PLAN.md`](docs/plans/001-V0_0_1_FOUNDATION_PLAN.md) — plan historique de fondation `0.0.1` ;
|
- [`docs/plans/001-V0_0_1_FOUNDATION_PLAN.md`](docs/plans/001-V0_0_1_FOUNDATION_PLAN.md) — plan historique de fondation `0.0.1` ;
|
||||||
- [`docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md`](docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md) — plan historique des premiers profils `0.0.2` ;
|
- [`docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md`](docs/plans/002-V0_0_2_RULE_PROFILES_PLAN.md) — plan historique des premiers profils `0.0.2` ;
|
||||||
- [`docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](docs/plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — plan historique des templates et audits `0.0.3` ;
|
- [`docs/plans/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/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md`](docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md) — plan historique de la stable `0.1.5` : sémantique normative, autonomie locale, frontière PGR / Knowledge, réconciliation transversale et handoff vers l’adoption Games `0.1.6` ;
|
||||||
|
- [`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.
|
- [`docs/validation/001-VALIDATION_MATRIX.md`](docs/validation/001-VALIDATION_MATRIX.md) — matrice de validation.
|
||||||
|
|
||||||
## Langue et nomenclature
|
## Langue et nomenclature
|
||||||
|
|||||||
34
ROADMAP.md
34
ROADMAP.md
@@ -1,9 +1,9 @@
|
|||||||
<!-- file: ROADMAP.md -->
|
<!-- file: ROADMAP.md -->
|
||||||
<!-- version: 4 -->
|
<!-- version: 19 -->
|
||||||
|
|
||||||
# Roadmap Project Governance Rules
|
# Roadmap Project Governance Rules
|
||||||
|
|
||||||
Le roadmap décrit le découpage macro des releases PGR. Il ne remplace ni les objectifs globaux du projet ni les plans détaillés de version.
|
Le roadmap décrit le découpage macro engagé des releases PGR. Il ne remplace ni les objectifs globaux du projet ni les plans détaillés de version et ne sert pas à inventer des versions futures uniquement pour prolonger l'horizon.
|
||||||
|
|
||||||
Statuts : `( )` planifié, `(x)` terminé, `(d)` différé, `(c)` annulé.
|
Statuts : `( )` planifié, `(x)` terminé, `(d)` différé, `(c)` annulé.
|
||||||
|
|
||||||
@@ -12,11 +12,35 @@ Statuts : `( )` planifié, `(x)` terminé, `(d)` différé, `(c)` annulé.
|
|||||||
- `(x) 0.0.1` — fondation normative et documentaire : gouvernance, lifecycle des releases, rôles documentaires, workflow delta/history/handoff et validation proportionnée ;
|
- `(x) 0.0.1` — fondation normative et documentaire : gouvernance, lifecycle des releases, rôles documentaires, workflow delta/history/handoff et validation proportionnée ;
|
||||||
- `(x) 0.0.2` — premiers profils de règles réutilisables : Rust/Cargo, Java/Maven/Gradle et Android, avec modèle de composition et audits Markdown initiaux ;
|
- `(x) 0.0.2` — premiers profils de règles réutilisables : Rust/Cargo, Java/Maven/Gradle et Android, avec modèle de composition et audits Markdown initiaux ;
|
||||||
- `(x) 0.0.3` — templates techniques initiaux et premiers patterns d'audit réutilisables issus de besoins réels ;
|
- `(x) 0.0.3` — templates techniques initiaux et premiers patterns d'audit réutilisables issus de besoins réels ;
|
||||||
- `( ) 0.0.4` — spécifications Markdown de skeletons et règles de composition des profils/templates ;
|
- `(x) 0.0.4` — spécifications Markdown de skeletons et règles de composition des profils/templates ;
|
||||||
- `( ) 0.0.5` — réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`.
|
- `(x) 0.0.5` — réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`, incluant la consolidation du lifecycle inter-release et de la revue d'horizon.
|
||||||
|
|
||||||
## Première baseline réutilisable
|
## 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.
|
||||||
|
|
||||||
|
## Trajectoire engagée `0.1.x`
|
||||||
|
|
||||||
|
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 :
|
||||||
|
|
||||||
|
- `(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 ;
|
||||||
|
- `(x) 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`.
|
||||||
|
|
||||||
|
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).
|
||||||
|
|
||||||
|
## Trajectoires différées ou non numérotées
|
||||||
|
|
||||||
|
- `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. La revue limitée `0.1.5-rc.1` confirme que les contrats transversaux sont suffisamment stabilisés et qu’aucun nouveau prérequis ne doit précéder l’adoption Games : l’ordre `0.1.6` Games, `0.1.7` KSP, `0.1.8` audits est conservé et aucun `0.1.9` n’est réservé.
|
||||||
|
|
||||||
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`.
|
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`.
|
||||||
|
|||||||
29
RULES.md
29
RULES.md
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: RULES.md -->
|
<!-- file: RULES.md -->
|
||||||
<!-- version: 9 -->
|
<!-- version: 16 -->
|
||||||
|
|
||||||
# Index normatif Project Governance Rules
|
# Index normatif Project Governance Rules
|
||||||
|
|
||||||
@@ -19,11 +19,11 @@ La gouvernance doit rester proportionnée au risque, à la portée du changement
|
|||||||
|
|
||||||
PGR utilise les termes suivants :
|
PGR utilise les termes suivants :
|
||||||
|
|
||||||
- `MUST` / `MUST NOT` : obligation ou interdiction dans le scope de la règle, sauf override ou exception explicitement documenté ;
|
- `MUST` / `MUST NOT` : obligation ou interdiction normative dans le scope de la règle ; une contradiction applicable doit être traitée par l'exception ou l'override autorisé, sinon elle constitue une non-conformité ;
|
||||||
- `SHOULD` / `SHOULD NOT` : comportement attendu par défaut, avec dérogation possible lorsqu'une solution différente est mieux adaptée et justifiée ;
|
- `SHOULD` / `SHOULD NOT` : forte recommandation non obligatoire. Un écart ne constitue pas à lui seul une non-conformité, ne fait pas échouer à lui seul une gate et n'exige pas automatiquement un `OVERRIDE` ; la raison MAY être documentée lorsqu'elle apporte une valeur durable de maintenance, architecture ou reprise ;
|
||||||
- `MAY` : possibilité reconnue, sans obligation implicite.
|
- `MAY` : possibilité neutre reconnue, sans obligation implicite.
|
||||||
|
|
||||||
Une règle qualitative ne doit pas être artificiellement transformée en `MUST` lorsqu'elle n'est ni objectivement vérifiable ni raisonnablement révisable.
|
Une règle qualitative ne doit pas être artificiellement transformée en `MUST` lorsqu'elle n'est ni objectivement vérifiable ni raisonnablement révisable. Une gate, un skeleton, un template ou un profil plus spécifique MUST conserver cette distinction de force normative au lieu de renforcer implicitement un `SHOULD`.
|
||||||
|
|
||||||
## Hiérarchie normative
|
## Hiérarchie normative
|
||||||
|
|
||||||
@@ -45,12 +45,13 @@ project-specific
|
|||||||
explicit exception
|
explicit exception
|
||||||
```
|
```
|
||||||
|
|
||||||
Une règle plus spécifique MAY raffiner, renforcer ou remplacer localement une règle générale dans son scope. Une contradiction intentionnelle MUST être déclarée comme override ou exception, avec scope et raison. Une contrainte locale ne se propage jamais automatiquement aux autres projets ou profils.
|
Une règle plus spécifique MAY raffiner ou renforcer localement une règle générale dans son scope. Lorsqu'elle contredit intentionnellement un `MUST` / `MUST NOT` réellement applicable, cette contradiction MUST être déclarée comme override ou exception, avec scope et raison. Un choix différent d'un `SHOULD` / `SHOULD NOT` n'est pas, par lui-même, une contradiction normative exigeant un override. Une contrainte locale ne se propage jamais automatiquement aux autres projets ou profils.
|
||||||
|
|
||||||
## Principes fondamentaux
|
## Principes fondamentaux
|
||||||
|
|
||||||
- Les projets instanciés depuis PGR MUST rester autonomes et posséder leurs propres copies des règles et configurations applicables.
|
- Les projets instanciés depuis PGR MUST rester autonomes et posséder leurs propres copies des règles et configurations applicables. Après établissement de la baseline locale, cette baseline et ses owners locaux deviennent l'autorité des sessions et releases suivantes.
|
||||||
- PGR MUST NOT devenir une dépendance runtime ou build des projets qu'il aide à initialiser.
|
- PGR MUST NOT devenir une dépendance runtime, build ou documentaire implicite des projets qu'il aide à initialiser ou adopter. Un projet gouverné localement MUST NOT rechercher automatiquement « la dernière version de PGR » ni traiter PGR comme un upstream à suivre.
|
||||||
|
- Un réalignement futur avec PGR MAY être engagé comme opération explicite et bornée : le projet choisit un snapshot PGR précis, compare ce snapshot à sa baseline locale, décide les écarts applicables et conserve ses historiques. Le réalignement ne constitue jamais une mise à jour automatique de la gouvernance locale.
|
||||||
- Les skeletons PGR sont des spécifications Markdown et MUST NOT devenir un générateur qui fige l'architecture d'un projet.
|
- Les skeletons PGR sont des spécifications Markdown et MUST NOT devenir un générateur qui fige l'architecture d'un projet.
|
||||||
- Les audits `audit_*.py` MUST être read-only, déterministes autant que raisonnablement possible et sans effets de bord sur le dépôt inspecté.
|
- Les audits `audit_*.py` MUST être read-only, déterministes autant que raisonnablement possible et sans effets de bord sur le dépôt inspecté.
|
||||||
- Une propriété déjà correctement contrôlée par le compilateur, le linter ou le build system SHOULD NOT être dupliquée par un test ou audit maison sans besoin réel.
|
- Une propriété déjà correctement contrôlée par le compilateur, le linter ou le build system SHOULD NOT être dupliquée par un test ou audit maison sans besoin réel.
|
||||||
@@ -76,13 +77,23 @@ 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/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/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/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/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/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/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/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/610-ANDROID.md`](docs/rules/610-ANDROID.md) — profil Android : structure, toolchain/SDK, compatibilité, packaging, configuration locale et validation plateforme.
|
||||||
|
- [`docs/rules/700-FRAMEWORKS.md`](docs/rules/700-FRAMEWORKS.md) — contrat commun des profils framework et de leur orchestration avec langages, plateformes et outils de build.
|
||||||
|
- [`docs/rules/710-TAURI.md`](docs/rules/710-TAURI.md) — profil Tauri 2 : host Rust, configuration/capabilities, hooks frontend, version produit, artefacts générés et validation d'intégration.
|
||||||
|
|
||||||
Le modèle de composition et d'ownership des profils est défini dans [`docs/architecture/003-RULE_PROFILE_MODEL.md`](docs/architecture/003-RULE_PROFILE_MODEL.md).
|
Le modèle de composition et d'ownership des profils est défini dans [`docs/architecture/003-RULE_PROFILE_MODEL.md`](docs/architecture/003-RULE_PROFILE_MODEL.md).
|
||||||
|
|
||||||
|
|||||||
150
deltas/0.0.4/alpha.1.md
Normal file
150
deltas/0.0.4/alpha.1.md
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
<!-- file: deltas/0.0.4/alpha.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-alpha.1 — audit de baseline et cadrage des skeletons
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : archive source fournie `pgr-v0.0.3.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.3`, accompagnée du rapport externe `pgr-0.0.3-publish.001-report.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
SHA-256 vérifié de l'archive :
|
||||||
|
|
||||||
|
```text
|
||||||
|
517fb46ada098fdc221ae53a8ff4b409b81e0244ec5ce4d0e6fca0c3da61b866
|
||||||
|
```
|
||||||
|
|
||||||
|
Le rapport post-tag annonce le même hash et reste extérieur à la stable. L'archive sans `.git` est contrôlée par son contenu ; elle n'est pas utilisée comme preuve autonome du commit ou de la référence distante du tag.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.3
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Exécuter la gate de cadrage imposée par `prompts/004-V0_0_4_START_PROMPT.md` avant toute matérialisation importante : vérifier la stable, les règles `200` à `610`, la gouvernance documentaire, les templates et audits existants, la chaîne delta/history et les limites annoncées ; déterminer ensuite quels skeletons disposent déjà d'entrées suffisantes et planifier les tranches de `0.0.4`.
|
||||||
|
|
||||||
|
Le résultat détaillé de cette revue et le découpage prévisionnel sont consignés dans `docs/plans/004-V0_0_4_SKELETONS_PLAN.md`. Aucun défaut bloquant de `0.0.3` n'impose une correction rétroactive avant ce cadrage.
|
||||||
|
|
||||||
|
Le plan retient comme premières cibles la fondation composable d'un projet gouverné PGR puis un skeleton Rust/Cargo workspace. Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles sans pièces suffisantes restent différés.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
docs/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
deltas/0.0.4/alpha.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces cinq fichiers complets avec leurs chemins relatifs. Aucun history, skeleton concret, nouvelle règle, template technique, script ou manifest de suppression n'appartient à `alpha.1`.
|
||||||
|
|
||||||
|
`README.md` et `docs/000-README.md` sont des documents vivants : ils ajoutent le plan actif comme point d'entrée. `ROADMAP.md` annonce déjà `0.0.4` comme planifiée et `CHANGELOG.md` reste limité aux releases publiées ; ils n'ont pas besoin d'une modification cérémonielle dans cette tranche.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application sur le commit stable `0.0.3`, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-alpha.1'
|
||||||
|
test -f docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
test -f deltas/0.0.4/alpha.1.md
|
||||||
|
test ! -e history/0.0.4/alpha.1.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 7 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/000-README.md
|
||||||
|
grep -F '004-V0_0_4_SKELETONS_PLAN.md' README.md
|
||||||
|
grep -F '004-V0_0_4_SKELETONS_PLAN.md' docs/000-README.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10}
|
||||||
|
for release, expected in expected_counts.items():
|
||||||
|
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||||
|
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||||
|
assert len(deltas) == expected, (release, len(deltas))
|
||||||
|
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||||
|
|
||||||
|
for path in Path('history/0.0.3').glob('*.md'):
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', text), path
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('scripts/audit_rust_blank_lines.py'),
|
||||||
|
Path('scripts/audit_rust_const_blocks.py'),
|
||||||
|
Path('scripts/_rust_audit_common.py'),
|
||||||
|
):
|
||||||
|
assert path.is_file(), path
|
||||||
|
|
||||||
|
print('Baseline structural audit: clean (34 prior delta/history pairs, 10/10 histories 0.0.3 PASS, 5 TOML parsed)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md docs/000-README.md \
|
||||||
|
docs/plans/004-V0_0_4_SKELETONS_PLAN.md deltas/0.0.4/alpha.1.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/alpha.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
A docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
La vérification du ZIP et du rapport post-tag appartient à l'intake de cette tranche et a été utilisée pour préparer le plan. L'opérateur confirme également que les fichiers fournis sont bien ceux téléchargés pour la reprise, que le hash de l'archive concorde avec le rapport, que le rapport est `PASS` et qu'il n'est pas copié dans le dépôt.
|
||||||
|
|
||||||
|
La revue opérateur doit confirmer que le plan ne transforme pas une prévision en règle active, que les valeurs Rust/Cargo d'exemple restent adaptables et que les domaines différés ne sont pas matérialisés par anticipation.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Rédiger et livrer séparément `history/0.0.4/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.4-alpha.2` pour le contrat de composition des skeletons.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le résultat réel dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.4-alpha.1.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.2` ne doit être absorbé silencieusement dans un fix.
|
||||||
189
deltas/0.0.4/alpha.2.md
Normal file
189
deltas/0.0.4/alpha.2.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<!-- file: deltas/0.0.4/alpha.2.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-alpha.2 — contrat de composition des skeletons
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : commit opérateur `bf306da` (`0.0.4-alpha.1`) après application de `history/0.0.4/alpha.1.md` avec statut `PASS`, puis push sur `origin/master`.
|
||||||
|
|
||||||
|
La baseline attendue contient donc le delta, le plan et le history de `alpha.1`, sans contenu `alpha.2` préalable.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Matérialiser le contrat transversal annoncé par le plan `0.0.4` sans anticiper les skeletons concrets des tranches suivantes.
|
||||||
|
|
||||||
|
La tranche crée `docs/rules/220-SKELETONS.md` comme propriétaire normatif unique de l'applicabilité, de la sélection, de la composition, des décisions projet, des overrides et de la validation initiale des skeleton specifications. Elle active également `docs/skeletons/` avec un index réel décrivant la responsabilité de la collection.
|
||||||
|
|
||||||
|
Les index normatifs et documentaires ainsi que les deux documents d'architecture concernés sont réconciliés avec ce nouveau propriétaire. Le modèle des profils reste possédé par `docs/architecture/003-RULE_PROFILE_MODEL.md` ; le nouveau document `220` le référence au lieu de dupliquer sa hiérarchie.
|
||||||
|
|
||||||
|
Aucun skeleton de fondation, Rust/Cargo, Java/Android, Web, JNI, Tauri ou autre domaine technologique n'appartient à cette tranche.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
RULES.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
docs/rules/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/rules/220-SKELETONS.md
|
||||||
|
docs/skeletons/000-README.md
|
||||||
|
deltas/0.0.4/alpha.2.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces dix fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.4/alpha.1.md`, déjà committé dans la baseline, ni `history/0.0.4/alpha.2.md`, qui sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` n'est pas modifié : la tranche réalise son étape `alpha.2` sans replan ni changement substantiel de trajectoire.
|
||||||
|
|
||||||
|
## Décisions normatives matérialisées
|
||||||
|
|
||||||
|
Le contrat commun impose notamment qu'un skeleton :
|
||||||
|
|
||||||
|
- déclare son objectif et son applicabilité à partir de faits du projet ;
|
||||||
|
- identifie les règles, profils, templates, fichiers, décisions, options, overrides, ordre utile, validation et hors-scope nécessaires ;
|
||||||
|
- référence les owners normatifs existants au lieu de devenir propriétaire implicite de leurs règles ;
|
||||||
|
- conserve les projets instanciés autonomes et sans dépendance runtime/build vers PGR ;
|
||||||
|
- distingue les valeurs obligatoires, exemples, recommandations et choix libres lorsqu'une confusion serait possible ;
|
||||||
|
- n'applique pas tous les profils PGR par défaut ;
|
||||||
|
- n'utilise pas l'ordre de composition comme priorité normative implicite ;
|
||||||
|
- ne crée pas de skeleton composite sans interaction réelle à posséder ;
|
||||||
|
- utilise une validation proportionnée au contenu réellement matérialisé.
|
||||||
|
|
||||||
|
La collection `docs/skeletons/` reste vide de specification concrète dans `alpha.2` hormis son index. Sa création n'est pas un placeholder : l'index documente le contrat de collection réellement activé par le nouveau owner normatif.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application sur le commit `bf306da`, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-alpha.2'
|
||||||
|
test -f history/0.0.4/alpha.1.md
|
||||||
|
test -f deltas/0.0.4/alpha.2.md
|
||||||
|
test -f docs/rules/220-SKELETONS.md
|
||||||
|
test -f docs/skeletons/000-README.md
|
||||||
|
test ! -e history/0.0.4/alpha.2.md
|
||||||
|
|
||||||
|
test ! -e docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
test ! -e docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 8 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 10 -->' RULES.md
|
||||||
|
grep -Fx '<!-- version: 6 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
grep -Fx '<!-- version: 11 -->' docs/rules/000-README.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/rules/220-SKELETONS.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/skeletons/000-README.md
|
||||||
|
|
||||||
|
grep -F 'docs/rules/220-SKELETONS.md' RULES.md
|
||||||
|
grep -F '220-SKELETONS.md' docs/rules/000-README.md
|
||||||
|
grep -F 'skeletons/' docs/000-README.md
|
||||||
|
grep -F '220-SKELETONS.md' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -F '220-SKELETONS.md' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10, '0.0.4': 1}
|
||||||
|
for release, expected in expected_counts.items():
|
||||||
|
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||||
|
if release == '0.0.4':
|
||||||
|
assert histories == {'alpha.1.md'}, histories
|
||||||
|
continue
|
||||||
|
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||||
|
assert len(deltas) == expected, (release, len(deltas))
|
||||||
|
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||||
|
|
||||||
|
text = Path('history/0.0.4/alpha.1.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', text)
|
||||||
|
|
||||||
|
assert sorted(path.name for path in Path('docs/skeletons').glob('*.md')) == ['000-README.md']
|
||||||
|
|
||||||
|
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'## Applicabilité',
|
||||||
|
'## Contenu minimal d\'une specification',
|
||||||
|
'## Sélection des règles et profils',
|
||||||
|
'## Templates et artefacts techniques',
|
||||||
|
'## Décisions propres au projet',
|
||||||
|
'## Composition de plusieurs skeletons',
|
||||||
|
'## Overrides et exceptions',
|
||||||
|
'## Validation de l\'instanciation',
|
||||||
|
):
|
||||||
|
assert phrase in rule, phrase
|
||||||
|
|
||||||
|
print('Skeleton contract audit: clean (alpha.1 PASS baseline, alpha.2 contract/index only)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md RULES.md docs/000-README.md \
|
||||||
|
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
|
||||||
|
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||||
|
docs/rules/000-README.md docs/rules/220-SKELETONS.md \
|
||||||
|
docs/skeletons/000-README.md deltas/0.0.4/alpha.2.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M RULES.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/alpha.2.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
M docs/rules/000-README.md
|
||||||
|
A docs/rules/220-SKELETONS.md
|
||||||
|
A docs/skeletons/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
La revue opérateur doit également confirmer que `220-SKELETONS.md` reste transversal, ne duplique pas les règles de profils ou de validation et ne matérialise aucun choix technologique futur par anticipation.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Rédiger et livrer `history/0.0.4/alpha.2.md` avec les résultats réellement observés ; l'appliquer puis committer la tranche. La tranche suivante est `0.0.4-alpha.3`, consacrée à la première skeleton specification de fondation d'un projet gouverné.
|
||||||
|
|
||||||
|
Le history `alpha.2` et le delta `alpha.3` MAY être livrés dans la même réponse après la gate `PASS`, tout en restant deux archives séparées. Le delta `alpha.3` MUST NOT être appliqué avant le commit complet de `alpha.2`.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le résultat réel dans le history de `alpha.2`, puis corriger le contrat dans `0.0.4-alpha.2.fix.1` ou produire un REPLAN motivé. Aucun skeleton concret de `alpha.3` ne doit être absorbé silencieusement dans un fix.
|
||||||
167
deltas/0.0.4/alpha.3.md
Normal file
167
deltas/0.0.4/alpha.3.md
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<!-- file: deltas/0.0.4/alpha.3.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-alpha.3 — fondation de projet gouverné
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur de `0.0.4-alpha.2`, réalisé après application de `history/0.0.4/alpha.2.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.2` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.3` MUST NOT être appliqué avant le commit de `alpha.2`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Matérialiser la première skeleton specification concrète prévue par le plan `0.0.4` : une fondation composable de gouvernance locale pour un projet qui adopte PGR, sans sélectionner de langage, plateforme, framework ou architecture applicative.
|
||||||
|
|
||||||
|
La specification doit rendre actionnables les responsabilités générales déjà possédées par `200`, `210`, `300` et `400` : version courante, point d'entrée normatif, documentation minimale, workflow réellement retenu, décisions destinataire, overrides et validation initiale proportionnée.
|
||||||
|
|
||||||
|
Elle ne crée aucun template générique, ne copie pas la structure complète du dépôt PGR et ne précrée aucun répertoire documentaire ou workflow sans contenu réel.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/skeletons/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
deltas/0.0.4/alpha.3.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni `history/0.0.4/alpha.2.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.4/alpha.3.md`, qui sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
Le plan `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` et la règle `docs/rules/220-SKELETONS.md` ne sont pas modifiés : cette tranche exécute leur trajectoire et leur contrat sans REPLAN.
|
||||||
|
|
||||||
|
## Contenu matérialisé
|
||||||
|
|
||||||
|
`docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` :
|
||||||
|
|
||||||
|
- déclare son objectif, son applicabilité et son hors-scope ;
|
||||||
|
- sélectionne les owners généraux `200`, `210`, `300` et `400` sans sélectionner de profil technologique ;
|
||||||
|
- distingue le rôle de `220` comme contrat d'instanciation de celui des règles à reprendre localement ;
|
||||||
|
- impose de résoudre les décisions destinataire avant de présenter l'instanciation comme terminée ;
|
||||||
|
- rend le point d'entrée normatif local et la version courante explicites ;
|
||||||
|
- rend `docs/`, `ROADMAP.md`, `CHANGELOG.md` et les collections spécialisées conditionnels à un contenu réel ;
|
||||||
|
- conserve `deltas/`, `history/`, `prompts/`, `handoffs/` et `manifests/` comme répertoires créés à la demande ;
|
||||||
|
- fournit une validation initiale proportionnée sans imposer de copier les scripts PGR ;
|
||||||
|
- définit l'ordre de composition attendu pour les futures spécialisations ;
|
||||||
|
- exclut explicitement architecture applicative, toolchain, CI/CD universel, branching universel et migration rétroactive.
|
||||||
|
|
||||||
|
Aucun template générique n'est nécessaire pour rendre cette specification actionnable : elle décrit les owners, décisions, fichiers conditionnels et preuves à matérialiser sans prétendre générer leur contenu automatiquement. Le point de REPLAN du plan n'est donc pas déclenché par cette tranche.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après avoir appliqué `history/0.0.4/alpha.2.md`, committé `0.0.4-alpha.2`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-alpha.3'
|
||||||
|
test -f history/0.0.4/alpha.2.md
|
||||||
|
test -f deltas/0.0.4/alpha.3.md
|
||||||
|
test -f docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
test ! -e history/0.0.4/alpha.3.md
|
||||||
|
test ! -e docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 9 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 7 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/skeletons/000-README.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
|
||||||
|
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' README.md
|
||||||
|
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' docs/000-README.md
|
||||||
|
grep -F '001-PROJECT_GOVERNANCE_FOUNDATION.md' docs/skeletons/000-README.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert histories == {'alpha.1.md', 'alpha.2.md'}, histories
|
||||||
|
for name in sorted(histories):
|
||||||
|
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', text), name
|
||||||
|
|
||||||
|
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||||
|
assert skeletons == ['000-README.md', '001-PROJECT_GOVERNANCE_FOUNDATION.md'], skeletons
|
||||||
|
|
||||||
|
text = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'## Applicabilité',
|
||||||
|
'## Owners sélectionnés',
|
||||||
|
'## Décisions destinataire avant matérialisation',
|
||||||
|
'## Baseline locale à matérialiser',
|
||||||
|
'### Version',
|
||||||
|
'### Documentation minimale',
|
||||||
|
'### Workflow retenu',
|
||||||
|
'### Validation initiale',
|
||||||
|
'## Ordre de composition',
|
||||||
|
'## Overrides et exceptions',
|
||||||
|
'## Hors scope',
|
||||||
|
):
|
||||||
|
assert phrase in text, phrase
|
||||||
|
|
||||||
|
for owner in ('200-GOVERNANCE.md', '210-WORKFLOW.md', '300-DOCUMENTATION.md', '400-VALIDATION.md'):
|
||||||
|
assert owner in text, owner
|
||||||
|
|
||||||
|
for forbidden in (
|
||||||
|
'templates/generic',
|
||||||
|
'docs/skeletons/002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
):
|
||||||
|
assert forbidden not in text, forbidden
|
||||||
|
|
||||||
|
print('Governance foundation audit: clean (alpha.1/alpha.2 PASS baseline, one concrete non-technological skeleton)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md docs/000-README.md \
|
||||||
|
docs/skeletons/000-README.md \
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||||
|
deltas/0.0.4/alpha.3.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur
|
||||||
|
|
||||||
|
En complément des commandes, vérifier que :
|
||||||
|
|
||||||
|
- la fondation reste une procedure composable et non un template ou générateur implicite ;
|
||||||
|
- aucun document ou répertoire n'est rendu obligatoire uniquement pour reproduire le layout PGR ;
|
||||||
|
- aucune règle technologique `500+` ou `600+` n'est sélectionnée par défaut ;
|
||||||
|
- les décisions destinataire restent explicites et aucune valeur d'exemple n'est universalisée ;
|
||||||
|
- l'ordre de composition permet au futur skeleton Rust/Cargo d'ajouter ses responsabilités sans dupliquer les owners généraux.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
PASS : produire `history/0.0.4/alpha.3.md`, l'appliquer puis committer `0.0.4-alpha.3`. La tranche suivante prévue par le plan est `0.0.4-alpha.4`, consacrée au skeleton Rust/Cargo workspace et à sa validation d'instanciation.
|
||||||
|
|
||||||
|
FAIL : rester dans le scope de `alpha.3` via `alpha.3.fix.1` sauf si l'échec démontre qu'un template générique ou une nouvelle décision normative est indispensable, auquel cas déclencher le REPLAN prévu par le plan.
|
||||||
231
deltas/0.0.4/alpha.4.fix.1.md
Normal file
231
deltas/0.0.4/alpha.4.fix.1.md
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
<!-- file: deltas/0.0.4/alpha.4.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-alpha.4.fix.1 — correction du smoke Rust/Cargo
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
Version attendue avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Le history `history/0.0.4/alpha.4.md` avec statut `FAIL` MUST avoir été appliqué et committé avant ce correctif.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.4.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Corriger uniquement la procédure de smoke Rust/Cargo qui a échoué pendant la gate opérateur de `alpha.4`.
|
||||||
|
|
||||||
|
Le workspace temporaire était fonctionnel et les commandes Cargo ont réussi, mais l'adaptation de `.cargo/config.toml` remplaçait les chemins contenant `project-name` sans adapter le commentaire de guidance qui contenait encore ce placeholder. L'assertion d'absence de placeholders échouait donc avant le smoke Cargo.
|
||||||
|
|
||||||
|
Ce fix adapte explicitement ce commentaire dans la fixture temporaire avant de vérifier l'absence de placeholders.
|
||||||
|
|
||||||
|
Aucune règle, aucun skeleton, aucun template et aucun script PGR n'est ajouté ou modifié.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.4/alpha.4.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Les snapshots suivants restent inchangés :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.4/alpha.4.md
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
templates/rust-cargo/rustfmt.toml
|
||||||
|
templates/rust-cargo/clippy.toml
|
||||||
|
templates/rust-cargo/.cargo/config.toml
|
||||||
|
templates/rust-cargo/Cargo.toml
|
||||||
|
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-alpha.4.fix.1'
|
||||||
|
test -f history/0.0.4/alpha.4.md
|
||||||
|
test -f deltas/0.0.4/alpha.4.md
|
||||||
|
test -f deltas/0.0.4/alpha.4.fix.1.md
|
||||||
|
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
test ! -e history/0.0.4/alpha.4.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.4/alpha.4.md | grep -Fx 'FAIL'
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'PASS',
|
||||||
|
'alpha.4.md': 'FAIL',
|
||||||
|
}
|
||||||
|
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert histories == set(expected), histories
|
||||||
|
for name, status in expected.items():
|
||||||
|
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||||
|
assert skeletons == [
|
||||||
|
'000-README.md',
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
], skeletons
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
print('Rust/Cargo fix audit: clean (alpha.4 FAIL recorded, skeleton/templates unchanged)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
command -v cargo
|
||||||
|
command -v rustfmt
|
||||||
|
cargo --version
|
||||||
|
rustc --version
|
||||||
|
rustfmt --version
|
||||||
|
cargo clippy --version
|
||||||
|
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$tmp"' EXIT
|
||||||
|
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||||
|
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||||
|
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||||
|
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||||
|
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||||
|
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||||
|
printf '1.2.3\n' > "$tmp/VERSION"
|
||||||
|
|
||||||
|
python3 -B - "$tmp" <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
root = Path(sys.argv[1])
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
root / 'Cargo.toml': (
|
||||||
|
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||||
|
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||||
|
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||||
|
),
|
||||||
|
root / 'rustfmt.toml': (
|
||||||
|
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||||
|
),
|
||||||
|
root / 'clippy.toml': (
|
||||||
|
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||||
|
),
|
||||||
|
root / '.cargo/config.toml': (
|
||||||
|
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||||
|
(
|
||||||
|
'# Replace project-name with a unique name before using this configuration.',
|
||||||
|
'# Smoke fixture: project-specific build directory already selected.',
|
||||||
|
),
|
||||||
|
('../builds/project-name/target', 'target-smoke'),
|
||||||
|
),
|
||||||
|
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||||
|
(
|
||||||
|
'# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||||
|
'# file: crates/smoke-core-lib/Cargo.toml',
|
||||||
|
),
|
||||||
|
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
for path, pairs in replacements.items():
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
for old, new in pairs:
|
||||||
|
assert old in text, (path, old)
|
||||||
|
text = text.replace(old, new)
|
||||||
|
path.write_text(text, encoding='utf-8')
|
||||||
|
|
||||||
|
for path in root.rglob('*'):
|
||||||
|
if path.is_file() and path.name != 'Cargo.lock':
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
assert 'project-name' not in text, path
|
||||||
|
assert 'project-core-lib' not in text, path
|
||||||
|
|
||||||
|
print('Temporary Rust/Cargo template adaptation: clean')
|
||||||
|
PY
|
||||||
|
|
||||||
|
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||||
|
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||||
|
|
||||||
|
/// Returns the deterministic smoke value.
|
||||||
|
pub fn smoke_value() -> u8 {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
RS
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$tmp"
|
||||||
|
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
)
|
||||||
|
|
||||||
|
rm -rf "$tmp"
|
||||||
|
trap - EXIT
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION deltas/0.0.4/alpha.4.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/alpha.4.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer et appliquer séparément `history/0.0.4/alpha.4.fix.1.md`, committer et pousser le correctif, puis reprendre le plan `0.0.4` à la tranche suivante prévue.
|
||||||
|
|
||||||
|
Le history `alpha.4.fix.1` et le delta de la tranche suivante MAY être livrés ensemble sous forme de deux archives séparées après observation de la gate opérateur.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.4-alpha.4.fix.M`. Le scope MUST rester limité au smoke Rust/Cargo de cette tranche tant qu'aucun défaut plus large ne justifie un REPLAN.
|
||||||
277
deltas/0.0.4/alpha.4.md
Normal file
277
deltas/0.0.4/alpha.4.md
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
<!-- file: deltas/0.0.4/alpha.4.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-alpha.4 — skeleton Rust/Cargo workspace
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur de `0.0.4-alpha.3`, réalisé après application de `history/0.0.4/alpha.3.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.3` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.4` MUST NOT être appliqué avant le commit de `alpha.3`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.3
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Matérialiser la première specialization technologique prévue par le plan `0.0.4` : un skeleton Rust/Cargo workspace composable avec la fondation `001`, les profils `500 + 510`, les cinq templates Rust/Cargo existants et leurs guides d'adaptation.
|
||||||
|
|
||||||
|
La specification doit rendre explicites les décisions destinataire avant copie, la relation entre `VERSION` et la version Cargo, les membres du workspace, l'édition/toolchain, les métadonnées, les dépendances/features, `Cargo.lock`, les lints, les paramètres Rustfmt/Clippy, les artefacts Cargo et la sélection éventuelle des audits de style Rust.
|
||||||
|
|
||||||
|
Aucun template Rust/Cargo ni owner normatif n'est modifié dans cette tranche : la spécialisation doit composer les pièces déjà éprouvées sans universaliser leurs valeurs d'exemple.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/skeletons/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
deltas/0.0.4/alpha.4.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient ni `history/0.0.4/alpha.3.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.4/alpha.4.md`, qui sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
Les documents suivants restent inchangés :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/rules/220-SKELETONS.md
|
||||||
|
docs/rules/500-LANGUAGES.md
|
||||||
|
docs/rules/510-RUST_CARGO.md
|
||||||
|
docs/templates/001-RUST_CARGO_TOOLING.md
|
||||||
|
docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||||
|
templates/rust-cargo/rustfmt.toml
|
||||||
|
templates/rust-cargo/clippy.toml
|
||||||
|
templates/rust-cargo/.cargo/config.toml
|
||||||
|
templates/rust-cargo/Cargo.toml
|
||||||
|
templates/rust-cargo/crates/project-core-lib/Cargo.toml
|
||||||
|
```
|
||||||
|
|
||||||
|
La tranche exécute donc le plan sans REPLAN et sans déplacer les propriétaires existants.
|
||||||
|
|
||||||
|
## Contenu matérialisé
|
||||||
|
|
||||||
|
`docs/skeletons/002-RUST_CARGO_WORKSPACE.md` :
|
||||||
|
|
||||||
|
- se compose explicitement avec `001-PROJECT_GOVERNANCE_FOUNDATION.md` ;
|
||||||
|
- sélectionne `500-LANGUAGES.md` et `510-RUST_CARGO.md` sans absorber leurs règles ;
|
||||||
|
- référence les guides `001-RUST_CARGO_TOOLING.md` et `002-CARGO_MANIFESTS.md` ;
|
||||||
|
- identifie exactement les cinq templates Rust/Cargo copiables existants ;
|
||||||
|
- rend explicites les décisions de release unit, membres, édition/toolchain, publication, métadonnées, dépendances/features, lockfile, lints, formatage, Clippy et artefacts ;
|
||||||
|
- rappelle que `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build doivent être revus avant adoption ;
|
||||||
|
- ne fournit aucun `src/lib.rs` ou `src/main.rs` universel ;
|
||||||
|
- conserve les audits de style Rust comme option explicitement sélectionnée avec corpus ciblé ;
|
||||||
|
- définit une validation Cargo initiale fondée sur `cargo metadata`, Rustfmt, `cargo check` et Clippy ;
|
||||||
|
- permet aux futurs profils plateforme/framework de s'ajouter après le workspace sans créer un composite artificiel.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après avoir appliqué `history/0.0.4/alpha.3.md`, committé `0.0.4-alpha.3`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-alpha.4'
|
||||||
|
test -f history/0.0.4/alpha.3.md
|
||||||
|
test -f deltas/0.0.4/alpha.4.md
|
||||||
|
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
test ! -e history/0.0.4/alpha.4.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 10 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 8 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/skeletons/000-README.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
|
||||||
|
grep -F '002-RUST_CARGO_WORKSPACE.md' README.md
|
||||||
|
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/000-README.md
|
||||||
|
grep -F '002-RUST_CARGO_WORKSPACE.md' docs/skeletons/000-README.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert histories == {'alpha.1.md', 'alpha.2.md', 'alpha.3.md'}, histories
|
||||||
|
for name in sorted(histories):
|
||||||
|
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', text), name
|
||||||
|
|
||||||
|
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||||
|
assert skeletons == [
|
||||||
|
'000-README.md',
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
], skeletons
|
||||||
|
|
||||||
|
text = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'## Applicabilité et composition',
|
||||||
|
'## Owners, guides et artefacts sélectionnés',
|
||||||
|
'## Décisions destinataire avant copie',
|
||||||
|
'## Matérialisation du workspace',
|
||||||
|
'### Cargo.lock',
|
||||||
|
'### Audits de style facultatifs',
|
||||||
|
'## Validation initiale',
|
||||||
|
'## Ordre de composition et extensions',
|
||||||
|
'## Overrides et exceptions',
|
||||||
|
'## Hors scope',
|
||||||
|
):
|
||||||
|
assert phrase in text, phrase
|
||||||
|
|
||||||
|
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||||
|
assert owner in text, owner
|
||||||
|
|
||||||
|
for template in (
|
||||||
|
'templates/rust-cargo/rustfmt.toml',
|
||||||
|
'templates/rust-cargo/clippy.toml',
|
||||||
|
'templates/rust-cargo/.cargo/config.toml',
|
||||||
|
'templates/rust-cargo/Cargo.toml',
|
||||||
|
'templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||||
|
):
|
||||||
|
assert template in text, template
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
print('Rust/Cargo skeleton audit: clean (alpha.1-alpha.3 PASS baseline, five templates parsed)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
command -v cargo
|
||||||
|
command -v rustfmt
|
||||||
|
cargo --version
|
||||||
|
rustc --version
|
||||||
|
rustfmt --version
|
||||||
|
cargo clippy --version
|
||||||
|
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$tmp"' EXIT
|
||||||
|
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||||
|
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||||
|
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||||
|
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||||
|
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||||
|
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||||
|
printf '1.2.3\n' > "$tmp/VERSION"
|
||||||
|
|
||||||
|
python3 -B - "$tmp" <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
root = Path(sys.argv[1])
|
||||||
|
|
||||||
|
replacements = {
|
||||||
|
root / 'Cargo.toml': (
|
||||||
|
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||||
|
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||||
|
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||||
|
),
|
||||||
|
root / 'rustfmt.toml': (
|
||||||
|
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||||
|
),
|
||||||
|
root / 'clippy.toml': (
|
||||||
|
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||||
|
),
|
||||||
|
root / '.cargo/config.toml': (
|
||||||
|
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||||
|
('../builds/project-name/target', 'target-smoke'),
|
||||||
|
),
|
||||||
|
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||||
|
('# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml', '# file: crates/smoke-core-lib/Cargo.toml'),
|
||||||
|
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
for path, pairs in replacements.items():
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
for old, new in pairs:
|
||||||
|
assert old in text, (path, old)
|
||||||
|
text = text.replace(old, new)
|
||||||
|
path.write_text(text, encoding='utf-8')
|
||||||
|
|
||||||
|
for path in root.rglob('*'):
|
||||||
|
if path.is_file() and path.name != 'Cargo.lock':
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
assert 'project-name' not in text, path
|
||||||
|
assert 'project-core-lib' not in text, path
|
||||||
|
PY
|
||||||
|
|
||||||
|
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||||
|
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||||
|
|
||||||
|
/// Returns the deterministic smoke value.
|
||||||
|
pub fn smoke_value() -> u8 {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
RS
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$tmp"
|
||||||
|
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
)
|
||||||
|
|
||||||
|
rm -rf "$tmp"
|
||||||
|
trap - EXIT
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md docs/000-README.md \
|
||||||
|
docs/skeletons/000-README.md \
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||||
|
deltas/0.0.4/alpha.4.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur
|
||||||
|
|
||||||
|
En complément des commandes, vérifier que :
|
||||||
|
|
||||||
|
- `002` reste une specialization composable de `001` et ne redéfinit pas les owners généraux ;
|
||||||
|
- les cinq templates sont référencés comme artefacts à adapter, jamais comme valeurs universelles ;
|
||||||
|
- la politique `Cargo.lock`, les membres, dépendances/features, métadonnées et éventuelles exceptions de lints/safety restent des décisions explicites du projet ;
|
||||||
|
- les audits Rust facultatifs ne sont ni copiés ni exécutés sans sélection de leur convention et de leur corpus ;
|
||||||
|
- aucune règle Java/Android/Web/JNI/Tauri ou autre plateforme/framework n'entre dans la tranche ;
|
||||||
|
- l'instanciation temporaire prouve l'adoption minimale des templates sans ajouter de workspace Rust au dépôt PGR.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
PASS : produire `history/0.0.4/alpha.4.md`, l'appliquer puis committer `0.0.4-alpha.4`. La tranche suivante prévue par le plan est `0.0.4-beta.1`, consacrée à la réconciliation interne de la release : ownership, liens, index, duplication normative, valeurs d'exemple, limites des audits et confirmation des domaines différés.
|
||||||
|
|
||||||
|
FAIL : rester dans le scope de `alpha.4` via `alpha.4.fix.1` sauf si l'instanciation démontre qu'un template ou une décision normative existante est insuffisante, auquel cas déclencher le REPLAN prévu par le plan.
|
||||||
200
deltas/0.0.4/beta.1.fix.1.md
Normal file
200
deltas/0.0.4/beta.1.fix.1.md
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
<!-- file: deltas/0.0.4/beta.1.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-beta.1.fix.1 — correction de la gate de réconciliation
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : tranche `0.0.4-beta.1` enregistrée `FAIL`, avec `history/0.0.4/beta.1.md` appliqué, committé et poussé. Le delta et le history `beta.1` restent des snapshots historiques et MUST NOT être réécrits.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-beta.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-beta.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Motif
|
||||||
|
|
||||||
|
La gate `beta.1` a échoué avant l'exécution de son audit Python de réconciliation à cause d'une chaîne délimitée par apostrophes simples contenant l'apostrophe de `l'arborescence` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
SyntaxError: unterminated string literal
|
||||||
|
```
|
||||||
|
|
||||||
|
Les tests, audits Markdown et contrôles précédant cette commande ont réussi. Aucun défaut des règles, skeletons, templates ou documents vivants n'a été observé.
|
||||||
|
|
||||||
|
Le présent fix corrige uniquement la gate en utilisant une chaîne Python correctement délimitée, puis rejoue les preuves nécessaires de la réconciliation.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.4/beta.1.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Aucun document vivant, règle, skeleton, template, script, test ou history antérieur n'est modifié.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après commit et push de `0.0.4-beta.1` avec son history `FAIL`, appliquer ce delta puis exécuter à la racine :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-beta.1.fix.1'
|
||||||
|
git cat-file -e HEAD:history/0.0.4/beta.1.md
|
||||||
|
test -f history/0.0.4/beta.1.md
|
||||||
|
test -f deltas/0.0.4/beta.1.md
|
||||||
|
test -f deltas/0.0.4/beta.1.fix.1.md
|
||||||
|
test ! -e history/0.0.4/beta.1.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.4/beta.1.md | grep -Fx 'FAIL'
|
||||||
|
grep -A2 '^## Statut$' history/0.0.4/alpha.4.fix.1.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
expected_histories = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'PASS',
|
||||||
|
'alpha.4.md': 'FAIL',
|
||||||
|
'alpha.4.fix.1.md': 'PASS',
|
||||||
|
'beta.1.md': 'FAIL',
|
||||||
|
}
|
||||||
|
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert histories == set(expected_histories), histories
|
||||||
|
for name, status in expected_histories.items():
|
||||||
|
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||||
|
assert deltas == set(expected_histories) | {'beta.1.fix.1.md'}, deltas
|
||||||
|
|
||||||
|
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||||
|
assert skeletons == [
|
||||||
|
'000-README.md',
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
], skeletons
|
||||||
|
|
||||||
|
root_index = Path('README.md').read_text(encoding='utf-8')
|
||||||
|
docs_index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||||
|
skel_index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
|
||||||
|
for name in (
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
):
|
||||||
|
assert name in root_index, name
|
||||||
|
assert name in docs_index, name
|
||||||
|
assert name in skel_index, name
|
||||||
|
|
||||||
|
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||||
|
for owner in (
|
||||||
|
'200-GOVERNANCE.md',
|
||||||
|
'210-WORKFLOW.md',
|
||||||
|
'300-DOCUMENTATION.md',
|
||||||
|
'400-VALIDATION.md',
|
||||||
|
):
|
||||||
|
assert owner in foundation, owner
|
||||||
|
|
||||||
|
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||||
|
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||||
|
assert owner in rust, owner
|
||||||
|
for value in ('0.1.0', '2024', 'project-name', 'project-core-lib'):
|
||||||
|
assert value in rust, value
|
||||||
|
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||||
|
assert 'Cargo.lock' in rust
|
||||||
|
|
||||||
|
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||||
|
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||||
|
assert 'MUST NOT devenir une valeur universelle par simple copie' in rule
|
||||||
|
|
||||||
|
validation = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||||
|
for audit_id in ('PGR-MD-HEADER-001', 'PGR-MD-TABLE-001', 'PGR-NAV-001'):
|
||||||
|
assert audit_id in validation, audit_id
|
||||||
|
assert "vérifie uniquement l'existence des cibles de liens Markdown locaux inline" in validation
|
||||||
|
|
||||||
|
rust_audits = Path('docs/validation/002-RUST_STYLE_AUDITS.md').read_text(encoding='utf-8')
|
||||||
|
assert 'facultatif' in rust_audits.lower()
|
||||||
|
assert "Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build." in rust_audits
|
||||||
|
|
||||||
|
plan = Path('docs/plans/004-V0_0_4_SKELETONS_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
for deferred in (
|
||||||
|
'Java / Maven / Gradle — différé',
|
||||||
|
'Android — différé',
|
||||||
|
'Web, JNI, Tauri et autres familles absentes — différés',
|
||||||
|
):
|
||||||
|
assert deferred in plan, deferred
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
print('Skeleton beta reconciliation fix audit: clean (beta.1 FAIL recorded, 3 skeleton docs, 5 TOML parsed)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION deltas/0.0.4/beta.1.fix.1.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/beta.1.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que :
|
||||||
|
|
||||||
|
- le `FAIL beta.1` reste visible et n'est pas réécrit ;
|
||||||
|
- le fix ne change aucune règle, aucun skeleton, aucun template et aucun audit ;
|
||||||
|
- `220` reste le propriétaire du contrat transversal et `001`/`002` restent des orchestrateurs/compositeurs de leurs owners ;
|
||||||
|
- les valeurs de templates restent adaptables et non universelles ;
|
||||||
|
- Java/Android/Web/JNI/Tauri restent différés sans placeholder anticipé.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer et appliquer séparément `history/0.0.4/beta.1.fix.1.md`, committer et pousser le fix, puis préparer `0.0.4-rc.1`.
|
||||||
|
|
||||||
|
Le history du fix et le delta `rc.1` MAY être livrés ensemble sous forme de deux archives séparées après observation de cette gate opérateur.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Enregistrer le diagnostic réel dans `history/0.0.4/beta.1.fix.1.md`, puis poursuivre par `beta.1.fix.2` limité à la réconciliation ou faire un REPLAN explicite si un défaut de contenu est réellement découvert.
|
||||||
225
deltas/0.0.4/beta.1.md
Normal file
225
deltas/0.0.4/beta.1.md
Normal file
@@ -0,0 +1,225 @@
|
|||||||
|
<!-- file: deltas/0.0.4/beta.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-beta.1 — réconciliation interne des skeletons
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
Version attendue avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-alpha.4.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Le history `history/0.0.4/alpha.4.fix.1.md` avec statut `PASS` MUST avoir été appliqué, committé et poussé avant ce delta. Le `FAIL` de `history/0.0.4/alpha.4.md` reste un snapshot historique et MUST NOT être réécrit.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-beta.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Exécuter la réconciliation interne prévue par `docs/plans/004-V0_0_4_SKELETONS_PLAN.md` après la fondation gouvernée, le skeleton Rust/Cargo et la correction de sa gate d'instanciation.
|
||||||
|
|
||||||
|
La revue porte sur :
|
||||||
|
|
||||||
|
```text
|
||||||
|
ownership normatif
|
||||||
|
navigation et index
|
||||||
|
absence de duplication normative
|
||||||
|
composition 001 -> 002
|
||||||
|
valeurs d'exemple non universalisées
|
||||||
|
limites des audits et de la validation
|
||||||
|
spécialisations technologiques différées
|
||||||
|
continuité delta/history de 0.0.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette tranche n'ajoute aucune fonctionnalité, aucun profil, aucun skeleton, aucun template et aucun audit.
|
||||||
|
|
||||||
|
## Résultat de la réconciliation préparatoire
|
||||||
|
|
||||||
|
Aucune correction de document vivant n'est nécessaire pour entrer en beta.
|
||||||
|
|
||||||
|
Le contrat transversal reste possédé par `docs/rules/220-SKELETONS.md`. La fondation `001-PROJECT_GOVERNANCE_FOUNDATION.md` orchestre les owners généraux sans les redéfinir. La specialization `002-RUST_CARGO_WORKSPACE.md` ajoute uniquement `500 + 510`, les guides/templates Rust/Cargo et les décisions de son scope.
|
||||||
|
|
||||||
|
La navigation courante expose les deux specifications depuis `README.md`, `docs/000-README.md` et `docs/skeletons/000-README.md`. Aucun troisième skeleton ou placeholder de skeleton n'existe.
|
||||||
|
|
||||||
|
Les valeurs Rust/Cargo telles que `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build restent explicitement décrites comme exemples, baselines ou décisions destinataire à revoir. `Cargo.lock` reste une décision propre au type de produit et au besoin de reproductibilité.
|
||||||
|
|
||||||
|
Les limites des audits restent séparées : headers, tableaux et liens Markdown sont des contrôles monotâches ; les audits de style Rust sont facultatifs, read-only et ne remplacent ni Rustfmt, ni Clippy, ni la toolchain Cargo. La validation d'instanciation appartient au skeleton qui prétend matérialiser une baseline utilisable et n'est pas transformée en build global permanent de PGR.
|
||||||
|
|
||||||
|
Java/Maven/Gradle et Android possèdent des profils normatifs mais pas encore les templates/corpus nécessaires à un skeleton concret. Web, JNI, Tauri et les autres domaines insuffisamment cadrés restent également différés. Aucun fichier placeholder n'est créé pour réserver ces futurs scopes.
|
||||||
|
|
||||||
|
Le `FAIL` de `alpha.4` et le `PASS` attendu de `alpha.4.fix.1` forment une chaîne historique explicite ; le fix ne réécrit pas le delta ou le history échoué.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.4/beta.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Les documents vivants, règles, skeletons, templates, scripts, tests et histories antérieurs restent inchangés. Cette absence de modification supplémentaire est intentionnelle : la réconciliation n'a pas identifié de correction réelle qui justifierait une révision artificielle.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après commit et push de `0.0.4-alpha.4.fix.1`, appliquer ce delta puis exécuter à la racine :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-beta.1'
|
||||||
|
git cat-file -e HEAD:history/0.0.4/alpha.4.fix.1.md
|
||||||
|
test -f history/0.0.4/alpha.4.fix.1.md
|
||||||
|
test -f deltas/0.0.4/beta.1.md
|
||||||
|
test ! -e history/0.0.4/beta.1.md
|
||||||
|
|
||||||
|
test -f docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
test -f docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
test ! -e docs/skeletons/003-JAVA_MAVEN_GRADLE.md
|
||||||
|
test ! -e docs/skeletons/003-ANDROID.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.4/alpha.4.md | grep -Fx 'FAIL'
|
||||||
|
grep -A2 '^## Statut$' history/0.0.4/alpha.4.fix.1.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
expected_histories = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'PASS',
|
||||||
|
'alpha.4.md': 'FAIL',
|
||||||
|
'alpha.4.fix.1.md': 'PASS',
|
||||||
|
}
|
||||||
|
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert histories == set(expected_histories), histories
|
||||||
|
for name, status in expected_histories.items():
|
||||||
|
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||||
|
assert deltas == set(expected_histories) | {'beta.1.md'}, deltas
|
||||||
|
|
||||||
|
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||||
|
assert skeletons == [
|
||||||
|
'000-README.md',
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
], skeletons
|
||||||
|
|
||||||
|
root_index = Path('README.md').read_text(encoding='utf-8')
|
||||||
|
docs_index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||||
|
skel_index = Path('docs/skeletons/000-README.md').read_text(encoding='utf-8')
|
||||||
|
for name in (
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
):
|
||||||
|
assert name in root_index, name
|
||||||
|
assert name in docs_index, name
|
||||||
|
assert name in skel_index, name
|
||||||
|
|
||||||
|
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||||
|
for owner in (
|
||||||
|
'200-GOVERNANCE.md',
|
||||||
|
'210-WORKFLOW.md',
|
||||||
|
'300-DOCUMENTATION.md',
|
||||||
|
'400-VALIDATION.md',
|
||||||
|
):
|
||||||
|
assert owner in foundation, owner
|
||||||
|
|
||||||
|
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||||
|
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||||
|
assert owner in rust, owner
|
||||||
|
for value in ('0.1.0', '2024', 'project-name', 'project-core-lib'):
|
||||||
|
assert value in rust, value
|
||||||
|
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||||
|
assert 'Cargo.lock' in rust
|
||||||
|
|
||||||
|
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||||
|
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||||
|
assert 'MUST NOT devenir une valeur universelle par simple copie' in rule
|
||||||
|
|
||||||
|
validation = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||||
|
for audit_id in ('PGR-MD-HEADER-001', 'PGR-MD-TABLE-001', 'PGR-NAV-001'):
|
||||||
|
assert audit_id in validation, audit_id
|
||||||
|
assert 'vérifie uniquement l\'existence des cibles de liens Markdown locaux inline' in validation
|
||||||
|
|
||||||
|
rust_audits = Path('docs/validation/002-RUST_STYLE_AUDITS.md').read_text(encoding='utf-8')
|
||||||
|
assert 'facultatif' in rust_audits.lower()
|
||||||
|
assert 'Les audits ne modifient ni les fichiers inspectés ni l'arborescence de build.' in rust_audits
|
||||||
|
|
||||||
|
plan = Path('docs/plans/004-V0_0_4_SKELETONS_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
for deferred in ('Java / Maven / Gradle — différé', 'Android — différé', 'Web, JNI, Tauri et autres familles absentes — différés'):
|
||||||
|
assert deferred in plan, deferred
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
print('Skeleton beta reconciliation audit: clean (5 prior histories, 3 skeleton docs, 5 TOML parsed)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION deltas/0.0.4/beta.1.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history `beta.1` est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/beta.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que :
|
||||||
|
|
||||||
|
- `220` reste le propriétaire du contrat transversal et que `001`/`002` n'en dupliquent pas les obligations ;
|
||||||
|
- `001` reste sans spécialisation technologique et `002` n'élargit pas `510` vers Android, WASM, Tauri, FFI ou un framework ;
|
||||||
|
- les valeurs de templates restent des exemples adaptables et non des politiques globales ;
|
||||||
|
- les audits documentaires et Rust restent délimités par leur propriété réellement vérifiée ;
|
||||||
|
- Java/Android/Web/JNI/Tauri restent différés faute de pièces suffisantes, sans placeholder ni skeleton composite anticipé ;
|
||||||
|
- le `FAIL alpha.4` reste visible et la correction `alpha.4.fix.1` est enregistrée séparément.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer et appliquer séparément `history/0.0.4/beta.1.md`, committer et pousser `beta.1`, puis préparer `0.0.4-rc.1`.
|
||||||
|
|
||||||
|
La RC doit geler le scope, préparer l'entrée candidate `0.0.4` du changelog et `prompts/005-V0_0_5_START_PROMPT.md` si la trajectoire est confirmée, puis rejouer uniquement les validations réellement invalidées par la release.
|
||||||
|
|
||||||
|
Le history `beta.1` et le delta `rc.1` MAY être livrés ensemble sous forme de deux archives séparées après observation de la gate opérateur.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Enregistrer le diagnostic réel dans `history/0.0.4/beta.1.md`, puis corriger uniquement la réconciliation dans `0.0.4-beta.1.fix.N` ou faire un REPLAN explicite si un défaut révèle un changement de scope.
|
||||||
265
deltas/0.0.4/rc.1.md
Normal file
265
deltas/0.0.4/rc.1.md
Normal file
@@ -0,0 +1,265 @@
|
|||||||
|
<!-- file: deltas/0.0.4/rc.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4-rc.1 — gel du scope et préparation de release
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : `0.0.4-beta.1.fix.1`, avec `history/0.0.4/beta.1.fix.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||||
|
|
||||||
|
Le commit exact de cette baseline sera celui produit par l'opérateur après la gate `beta.1.fix.1` ; il n'est pas anticipé dans cette livraison simultanée du history et du delta suivant.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-beta.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-rc.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet et gel
|
||||||
|
|
||||||
|
La réconciliation `beta.1.fix.1` est `PASS`. La RC gèle le scope fonctionnel de `0.0.4` sur :
|
||||||
|
|
||||||
|
- le contrat transversal des skeleton specifications sous `docs/rules/220-SKELETONS.md` ;
|
||||||
|
- la collection `docs/skeletons/` et son index ;
|
||||||
|
- `001-PROJECT_GOVERNANCE_FOUNDATION.md` comme fondation composable sans spécialisation technologique ;
|
||||||
|
- `002-RUST_CARGO_WORKSPACE.md` comme première spécialisation technologique, composée avec les profils `500 + 510` ;
|
||||||
|
- les cinq templates Rust/Cargo déjà introduits avant `0.0.4`, utilisés avec des décisions destinataire explicites et une instanciation temporaire vérifiable.
|
||||||
|
|
||||||
|
Le changelog reçoit une entrée candidate `0.0.4` orientée utilisateurs. Le plan enregistre les résultats `FAIL → fix PASS` des gates `alpha.4` et `beta.1`, puis le gel RC. Le prompt `005` prépare `0.0.5`, dont la roadmap confirme la mission de réconciliation réelle avec `khadhroony-solana-project` et `sasedev-games` à partir de baselines explicitement fournies.
|
||||||
|
|
||||||
|
Aucun nouveau skeleton, profil, template, audit, générateur ou domaine technologique n'entre en RC. Java/Maven/Gradle, Android, Web, JNI, Tauri et les autres familles différées restent hors scope.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
deltas/0.0.4/rc.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive contient exactement ces fichiers complets. Le history `beta.1.fix.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
## Gate opérateur de release candidate
|
||||||
|
|
||||||
|
Après application sur le commit `beta.1.fix.1`, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4-rc.1'
|
||||||
|
git cat-file -e HEAD:history/0.0.4/beta.1.fix.1.md
|
||||||
|
test -f history/0.0.4/beta.1.fix.1.md
|
||||||
|
test -f deltas/0.0.4/rc.1.md
|
||||||
|
test -f prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
test ! -e history/0.0.4/rc.1.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 6 -->' CHANGELOG.md
|
||||||
|
grep -Fx '## 0.0.4 (candidate)' CHANGELOG.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
grep -F '`beta.1.fix.1` a rejoué la réconciliation et est `PASS`' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
grep -F 'pgr-v0.0.4.zip' prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
grep -F 'khadhroony-solana-project' prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
grep -F 'sasedev-games' prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
expected_histories = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'PASS',
|
||||||
|
'alpha.4.md': 'FAIL',
|
||||||
|
'alpha.4.fix.1.md': 'PASS',
|
||||||
|
'beta.1.md': 'FAIL',
|
||||||
|
'beta.1.fix.1.md': 'PASS',
|
||||||
|
}
|
||||||
|
histories = {path.name for path in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert histories == set(expected_histories), histories
|
||||||
|
for name, status in expected_histories.items():
|
||||||
|
text = Path('history/0.0.4', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
deltas = {path.name for path in Path('deltas/0.0.4').glob('*.md')}
|
||||||
|
assert deltas == set(expected_histories) | {'rc.1.md'}, deltas
|
||||||
|
|
||||||
|
skeletons = sorted(path.name for path in Path('docs/skeletons').glob('*.md'))
|
||||||
|
assert skeletons == [
|
||||||
|
'000-README.md',
|
||||||
|
'001-PROJECT_GOVERNANCE_FOUNDATION.md',
|
||||||
|
'002-RUST_CARGO_WORKSPACE.md',
|
||||||
|
], skeletons
|
||||||
|
|
||||||
|
rule = Path('docs/rules/220-SKELETONS.md').read_text(encoding='utf-8')
|
||||||
|
assert 'Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.' in rule
|
||||||
|
|
||||||
|
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||||
|
for owner in ('200-GOVERNANCE.md', '210-WORKFLOW.md', '300-DOCUMENTATION.md', '400-VALIDATION.md'):
|
||||||
|
assert owner in foundation, owner
|
||||||
|
|
||||||
|
rust = Path('docs/skeletons/002-RUST_CARGO_WORKSPACE.md').read_text(encoding='utf-8')
|
||||||
|
for owner in ('500-LANGUAGES.md', '510-RUST_CARGO.md'):
|
||||||
|
assert owner in rust, owner
|
||||||
|
assert 'Ils ne deviennent jamais des valeurs universelles par simple copie.' in rust
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
prompt = Path('prompts/005-V0_0_5_START_PROMPT.md').read_text(encoding='utf-8')
|
||||||
|
for value in ('pgr-v0.0.4.zip', 'pgr-0.0.4-publish.001-report.md', '0.0.5-alpha.1', 'khadhroony-solana-project', 'sasedev-games'):
|
||||||
|
assert value in prompt, value
|
||||||
|
assert 'Ne pas déduire leur version, leur commit ou leur contenu' in prompt
|
||||||
|
|
||||||
|
print('RC integration audit: clean (7 prior histories, 3 skeleton docs, 5 TOML parsed, prompt 005 ready)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
command -v cargo
|
||||||
|
command -v rustfmt
|
||||||
|
cargo --version
|
||||||
|
rustc --version
|
||||||
|
rustfmt --version
|
||||||
|
cargo clippy --version
|
||||||
|
|
||||||
|
tmp="$(mktemp -d)"
|
||||||
|
trap 'rm -rf "$tmp"' EXIT
|
||||||
|
mkdir -p "$tmp/.cargo" "$tmp/crates/smoke-core-lib/src"
|
||||||
|
cp templates/rust-cargo/Cargo.toml "$tmp/Cargo.toml"
|
||||||
|
cp templates/rust-cargo/rustfmt.toml "$tmp/rustfmt.toml"
|
||||||
|
cp templates/rust-cargo/clippy.toml "$tmp/clippy.toml"
|
||||||
|
cp templates/rust-cargo/.cargo/config.toml "$tmp/.cargo/config.toml"
|
||||||
|
cp templates/rust-cargo/crates/project-core-lib/Cargo.toml "$tmp/crates/smoke-core-lib/Cargo.toml"
|
||||||
|
printf '1.2.3\n' > "$tmp/VERSION"
|
||||||
|
|
||||||
|
python3 -B - "$tmp" <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import sys
|
||||||
|
|
||||||
|
root = Path(sys.argv[1])
|
||||||
|
replacements = {
|
||||||
|
root / 'Cargo.toml': (
|
||||||
|
('# file: templates/rust-cargo/Cargo.toml', '# file: Cargo.toml'),
|
||||||
|
('members = ["crates/project-core-lib"]', 'members = ["crates/smoke-core-lib"]'),
|
||||||
|
('version = "0.1.0"', 'version = "1.2.3"'),
|
||||||
|
),
|
||||||
|
root / 'rustfmt.toml': (
|
||||||
|
('# file: templates/rust-cargo/rustfmt.toml', '# file: rustfmt.toml'),
|
||||||
|
),
|
||||||
|
root / 'clippy.toml': (
|
||||||
|
('# file: templates/rust-cargo/clippy.toml', '# file: clippy.toml'),
|
||||||
|
),
|
||||||
|
root / '.cargo/config.toml': (
|
||||||
|
('# file: templates/rust-cargo/.cargo/config.toml', '# file: .cargo/config.toml'),
|
||||||
|
(
|
||||||
|
'# Replace project-name with a unique name before using this configuration.',
|
||||||
|
'# Smoke fixture: project-specific build directory already selected.',
|
||||||
|
),
|
||||||
|
('../builds/project-name/target', 'target-smoke'),
|
||||||
|
),
|
||||||
|
root / 'crates/smoke-core-lib/Cargo.toml': (
|
||||||
|
(
|
||||||
|
'# file: templates/rust-cargo/crates/project-core-lib/Cargo.toml',
|
||||||
|
'# file: crates/smoke-core-lib/Cargo.toml',
|
||||||
|
),
|
||||||
|
('name = "project-core-lib"', 'name = "smoke-core-lib"'),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
for path, pairs in replacements.items():
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
for old, new in pairs:
|
||||||
|
assert old in text, (path, old)
|
||||||
|
text = text.replace(old, new)
|
||||||
|
path.write_text(text, encoding='utf-8')
|
||||||
|
for path in root.rglob('*'):
|
||||||
|
if path.is_file() and path.name != 'Cargo.lock':
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
assert 'project-name' not in text, path
|
||||||
|
assert 'project-core-lib' not in text, path
|
||||||
|
print('RC temporary Rust/Cargo template adaptation: clean')
|
||||||
|
PY
|
||||||
|
|
||||||
|
cat > "$tmp/crates/smoke-core-lib/src/lib.rs" <<'RS'
|
||||||
|
//! Minimal crate used to validate the PGR Rust/Cargo templates.
|
||||||
|
|
||||||
|
/// Returns the deterministic smoke value.
|
||||||
|
pub fn smoke_value() -> u8 {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
RS
|
||||||
|
|
||||||
|
(
|
||||||
|
cd "$tmp"
|
||||||
|
cargo metadata --format-version 1 --no-deps >/dev/null
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
)
|
||||||
|
|
||||||
|
rm -rf "$tmp"
|
||||||
|
trap - EXIT
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION CHANGELOG.md docs/plans/004-V0_0_4_SKELETONS_PLAN.md \
|
||||||
|
prompts/005-V0_0_5_START_PROMPT.md deltas/0.0.4/rc.1.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope attendu avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M CHANGELOG.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/rc.1.md
|
||||||
|
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
A prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que le changelog décrit la release et non ses tranches internes, que les deux `FAIL` historiques restent visibles avec leurs fixes `PASS`, que le prompt `005` ne présume aucune version KSP/Games non fournie et que la RC n'étend pas le périmètre fonctionnel.
|
||||||
|
|
||||||
|
Une gate RC `PASS` n'est ni la promotion stable, ni le tag `v0.0.4`, ni la vérification de l'archive publiée après le tag.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire séparément `history/0.0.4/rc.1.md`, l'appliquer puis committer/pousser la RC avant le delta stable `rel.001`.
|
||||||
|
|
||||||
|
Le history RC et le delta stable MAY être livrés ensemble sous forme de deux archives séparées après observation de cette gate opérateur.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner l'échec réel dans `history/0.0.4/rc.1.md` et corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN explicite si la candidate révèle un défaut fonctionnel plus large.
|
||||||
152
deltas/0.0.4/rel.001.md
Normal file
152
deltas/0.0.4/rel.001.md
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
<!-- file: deltas/0.0.4/rel.001.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.4 rel.001 — promotion stable pré-tag
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : `0.0.4-rc.1`, avec `history/0.0.4/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||||
|
|
||||||
|
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history RC ; il n'est pas anticipé dans cette livraison simultanée du history et du delta stable.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4-rc.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4
|
||||||
|
```
|
||||||
|
|
||||||
|
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Promouvoir la RC validée vers la stable `0.0.4`. La tranche finalise uniquement la présentation de la release : version stable, roadmap terminée, changelog sans marqueur candidate, index documentaires et plan historique.
|
||||||
|
|
||||||
|
Le scope fonctionnel reste celui validé en RC : contrat transversal des skeleton specifications, fondation gouvernée `001`, spécialisation Rust/Cargo `002`, utilisation gouvernée des cinq templates Rust/Cargo existants et différé explicite des autres familles non suffisamment matérialisées.
|
||||||
|
|
||||||
|
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.4`, ni l'archive `pgr-v0.0.4.zip` téléchargée depuis Gitea, ni un rapport `pgr-0.0.4-publish.001-report.md` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication réelle du tag.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
ROADMAP.md
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.4/rel.001.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive contient uniquement ces fichiers complets. `history/0.0.4/rc.1.md` est livré séparément ; le history de `rel.001` sera produit après sa gate. Le rapport post-tag restera extérieur à l'archive source taggée.
|
||||||
|
|
||||||
|
## Validation opérateur pré-tag
|
||||||
|
|
||||||
|
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.4'
|
||||||
|
git cat-file -e HEAD:history/0.0.4/rc.1.md
|
||||||
|
test -f history/0.0.4/rc.1.md
|
||||||
|
test -f deltas/0.0.4/rel.001.md
|
||||||
|
test -f prompts/005-V0_0_5_START_PROMPT.md
|
||||||
|
test ! -e history/0.0.4/rel.001.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 11 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 7 -->' CHANGELOG.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
grep -F 'La release `0.0.4` définit le contrat transversal des skeleton specifications' README.md
|
||||||
|
grep -F 'plan historique des skeleton specifications `0.0.4`' README.md
|
||||||
|
grep -F -- '- `(x) 0.0.4`' ROADMAP.md
|
||||||
|
grep -Fx '## 0.0.4' CHANGELOG.md
|
||||||
|
grep -F 'périmètre et décisions de la release `0.0.4`' docs/000-README.md
|
||||||
|
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
grep -F 'pgr-0.0.4-publish.001-report.md' docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'PASS',
|
||||||
|
'alpha.4.md': 'FAIL',
|
||||||
|
'alpha.4.fix.1.md': 'PASS',
|
||||||
|
'beta.1.md': 'FAIL',
|
||||||
|
'beta.1.fix.1.md': 'PASS',
|
||||||
|
'rc.1.md': 'PASS',
|
||||||
|
}
|
||||||
|
for name, status in expected.items():
|
||||||
|
delta = Path('deltas/0.0.4', name)
|
||||||
|
history = Path('history/0.0.4', name)
|
||||||
|
assert delta.is_file(), name
|
||||||
|
assert history.is_file(), name
|
||||||
|
text = history.read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
pending = {p.name for p in Path('deltas/0.0.4').glob('*.md')} - \
|
||||||
|
{p.name for p in Path('history/0.0.4').glob('*.md')}
|
||||||
|
assert pending == {'rel.001.md'}, pending
|
||||||
|
print('Stable history audit: clean (8 prior histories with expected statuses, rel.001 pending)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||||
|
docs/plans/004-V0_0_4_SKELETONS_PLAN.md deltas/0.0.4/rel.001.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope attendu avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M CHANGELOG.md
|
||||||
|
M README.md
|
||||||
|
M ROADMAP.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.4/rel.001.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/004-V0_0_4_SKELETONS_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Les `15` tests, les cinq TOML et le smoke Rust/Cargo complets validés en RC restent des preuves applicables parce qu'aucun code, script, test, template ou skeleton technique n'est modifié pendant `rel.001`. La gate stable se concentre donc sur l'intégrité de la chaîne historique, la présentation stable et les audits documentaires affectés.
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que le scope fonctionnel de la RC ne change pas, que README/roadmap/changelog/index/plan décrivent la même stable, que les `FAIL` historiques restent conservés avec leurs fixes `PASS`, que le prompt `005` reste conditionnel à une vraie publication et à des baselines KSP/Games fournies, et qu'aucune preuve post-tag n'est anticipée.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire séparément `history/0.0.4/rel.001.md`, l'appliquer puis committer la stable. Ensuite seulement créer et publier le tag canonique `v0.0.4`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `pgr-0.0.4-publish.001-report.md`.
|
||||||
|
|
||||||
|
Le message manuel de reprise de `prompts/005-V0_0_5_START_PROMPT.md` n'est remis à l'opérateur qu'après vérification effective de l'archive et d'un rapport post-tag PASS réel.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le diagnostic réel dans `history/0.0.4/rel.001.md`, ne pas tagger et corriger la clôture dans une tranche explicite avant publication.
|
||||||
193
deltas/0.0.5/alpha.1.md
Normal file
193
deltas/0.0.5/alpha.1.md
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.1 — réconciliation des baselines et cadrage
|
||||||
|
|
||||||
|
## Baseline et sources
|
||||||
|
|
||||||
|
Baseline PGR : archive source fournie `pgr-v0.0.4.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.4`, accompagnée du rapport externe `pgr-0.0.4-publish.001-report.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
SHA-256 vérifié :
|
||||||
|
|
||||||
|
```text
|
||||||
|
pgr-v0.0.4.zip 7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae
|
||||||
|
khadhroony-solana-project-v0.3.16.zip db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||||
|
games-v0.3.5.zip 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||||
|
```
|
||||||
|
|
||||||
|
Les deux archives externes sont des corpus autoritaires de réconciliation pour cette session, pas des projets déjà gouvernés par PGR. Elles ne sont ni modifiées ni incorporées à l'archive delta.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Exécuter la gate de cadrage imposée par `prompts/005-V0_0_5_START_PROMPT.md` : vérifier indépendamment la stable PGR et sa preuve post-tag, contrôler les deux snapshots externes fournis, inventorier leurs responsabilités et audits, puis classer les écarts avant toute modification normative importante.
|
||||||
|
|
||||||
|
L'analyse détaillée vit dans `docs/studies/001-KSP_GAMES_RECONCILIATION.md`. Elle confirme que KSP `v0.3.16` et Games `v0.3.5` n'ont pas encore adopté PGR et ne doivent donc pas être jugés comme des projets non conformes. La plupart des mécanismes de gouvernance, documentation, validation et Rust/Cargo observés sont déjà correctement possédés par PGR.
|
||||||
|
|
||||||
|
Quatre axes communs restent suffisamment étayés pour le plan `0.0.5` : contrat générique des prompts versionnés, pattern facultatif de contrats de fichiers/familles, audit Rust de façade/export completeness, et Tauri comme premier candidat réel à la famille framework `700`.
|
||||||
|
|
||||||
|
Aucun de ces axes n'est matérialisé normativement dans `alpha.1`. Web/Vite/WASM, JNI, les audits composites et les règles métier ou de distribution spécifiques restent différés ou locaux.
|
||||||
|
|
||||||
|
## Vérifications d'intake déjà exécutées
|
||||||
|
|
||||||
|
Le ZIP PGR est lisible, possède une racine unique `pgr/`, `139` fichiers et `28` répertoires, sans doublon, collision de casse, chemin dangereux, lien symbolique ni `.git`. Son hash concorde avec le rapport post-tag.
|
||||||
|
|
||||||
|
Les deux corpus externes passent les contrôles ZIP équivalents. Leurs audits statiques fournis ont également été exécutés avec succès : audits Rust généraux/export/workspace et tableaux Markdown pour KSP ; audits Rust généraux/export/workspace, tableaux Markdown et distribution layout pour Games.
|
||||||
|
|
||||||
|
Sur la stable PGR extraite, les `15` tests Python passent, les trois audits Markdown sont propres et les cinq TOML Rust/Cargo se parsèrent. La toolchain `cargo` n'est pas disponible dans l'environnement de préparation ; aucune commande Cargo externe n'est donc présentée comme exécutée.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
docs/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/studies/000-README.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
deltas/0.0.5/alpha.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces sept fichiers complets avec leurs chemins relatifs. Aucun history, règle normative, script, template technique, profil framework, skeleton ou modification KSP/Games n'appartient à cette tranche.
|
||||||
|
|
||||||
|
`ROADMAP.md` annonce déjà `0.0.5` comme planifiée et `CHANGELOG.md` reste limité aux releases publiées ; aucun changement cérémoniel de ces deux fichiers n'est requis ici.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application sur le commit stable `0.0.4`, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.1'
|
||||||
|
test -f docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
test -f docs/studies/000-README.md
|
||||||
|
test -f docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
test -f deltas/0.0.5/alpha.1.md
|
||||||
|
test ! -e history/0.0.5/alpha.1.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 12 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 10 -->' docs/000-README.md
|
||||||
|
grep -F '005-V0_0_5_RECONCILIATION_PLAN.md' README.md docs/000-README.md
|
||||||
|
grep -F '001-KSP_GAMES_RECONCILIATION.md' README.md docs/000-README.md docs/studies/000-README.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
import tomllib
|
||||||
|
|
||||||
|
expected_hashes = {
|
||||||
|
'pgr-v0.0.4.zip': '7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae',
|
||||||
|
'khadhroony-solana-project-v0.3.16.zip': 'db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0',
|
||||||
|
'games-v0.3.5.zip': '5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105',
|
||||||
|
}
|
||||||
|
|
||||||
|
study = Path('docs/studies/001-KSP_GAMES_RECONCILIATION.md').read_text(encoding='utf-8')
|
||||||
|
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
for name, digest in expected_hashes.items():
|
||||||
|
assert name in study or name in plan, name
|
||||||
|
assert digest in study or digest in plan, digest
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
Path('templates/rust-cargo/rustfmt.toml'),
|
||||||
|
Path('templates/rust-cargo/clippy.toml'),
|
||||||
|
Path('templates/rust-cargo/.cargo/config.toml'),
|
||||||
|
Path('templates/rust-cargo/Cargo.toml'),
|
||||||
|
Path('templates/rust-cargo/crates/project-core-lib/Cargo.toml'),
|
||||||
|
):
|
||||||
|
with path.open('rb') as stream:
|
||||||
|
tomllib.load(stream)
|
||||||
|
|
||||||
|
expected_counts = {'0.0.1': 12, '0.0.2': 12, '0.0.3': 10, '0.0.4': 9}
|
||||||
|
for release, expected in expected_counts.items():
|
||||||
|
deltas = {path.name for path in Path('deltas', release).glob('*.md')}
|
||||||
|
histories = {path.name for path in Path('history', release).glob('*.md')}
|
||||||
|
assert len(deltas) == expected, (release, len(deltas))
|
||||||
|
assert deltas == histories, (release, sorted(deltas ^ histories))
|
||||||
|
|
||||||
|
statuses_004 = {}
|
||||||
|
for path in Path('history/0.0.4').glob('*.md'):
|
||||||
|
text = path.read_text(encoding='utf-8')
|
||||||
|
match = re.search(r'## Statut\s+(PASS|FAIL|PARTIAL|BLOCKED)\s', text)
|
||||||
|
assert match is not None, path
|
||||||
|
statuses_004[path.name] = match.group(1)
|
||||||
|
assert statuses_004['alpha.4.md'] == 'FAIL'
|
||||||
|
assert statuses_004['alpha.4.fix.1.md'] == 'PASS'
|
||||||
|
assert statuses_004['beta.1.md'] == 'FAIL'
|
||||||
|
assert statuses_004['beta.1.fix.1.md'] == 'PASS'
|
||||||
|
assert statuses_004['rc.1.md'] == 'PASS'
|
||||||
|
assert statuses_004['rel.001.md'] == 'PASS'
|
||||||
|
|
||||||
|
assert 'ne sont pas encore gouvernés par PGR' in plan
|
||||||
|
assert 'aucune migration de KSP ou Games' in plan
|
||||||
|
assert 'Tauri' in plan
|
||||||
|
assert 'audit_rust_export_completeness.py' in study
|
||||||
|
|
||||||
|
print('0.0.5 alpha.1 structural audit: clean (43 prior pairs, 5 TOML parsed, reconciliation sources recorded)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md docs/000-README.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/studies/000-README.md docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
deltas/0.0.5/alpha.1.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
A docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
A docs/studies/000-README.md
|
||||||
|
A docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
La revue opérateur doit en outre confirmer que :
|
||||||
|
|
||||||
|
- les trois archives/hashes consignés correspondent bien aux sources autoritaires fournies pour cette reprise ;
|
||||||
|
- l'étude traite KSP et Games comme corpus non encore migrés vers PGR ;
|
||||||
|
- le plan n'atteste aucun profil Tauri, audit de façade ou template avant sa tranche dédiée ;
|
||||||
|
- les conventions métier et plateforme locales ne sont pas promues en règles PGR par simple similarité ;
|
||||||
|
- aucune modification des deux projets externes n'est cachée dans le delta.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Rédiger et livrer séparément `history/0.0.5/alpha.1.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.5-alpha.2` pour le contrat générique des prompts versionnés.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le résultat réel dans le history de `alpha.1`, puis corriger le cadrage dans `0.0.5-alpha.1.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.2` ne doit être absorbé silencieusement dans un fix.
|
||||||
179
deltas/0.0.5/alpha.2.md
Normal file
179
deltas/0.0.5/alpha.2.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.2.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.2 — contrat générique des prompts de démarrage
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur de `0.0.5-alpha.1`, réalisé après application de `history/0.0.5/alpha.1.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Le hash de ce commit n'est volontairement pas anticipé : le history `alpha.1` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.2` MUST NOT être appliqué avant le commit de `alpha.1`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Exécuter la deuxième tranche du plan `0.0.5` en renforçant l'owner `docs/rules/210-WORKFLOW.md` pour les prompts de démarrage versionnés.
|
||||||
|
|
||||||
|
Les prompts PGR récents et les baselines KSP/Games montrent qu'un bon prompt de reprise ne se limite pas à nommer une baseline et une mission : il doit permettre de reconstruire explicitement l'état utile, les sources à lire, les décisions déjà acquises, les limites de scope, la première gate et la trajectoire de validation sans réimporter toute la documentation du projet.
|
||||||
|
|
||||||
|
La tranche généralise ce contrat sémantique sans copier la structure exhaustive des prompts KSP/Games. Elle ne crée ni nouveau template manuel ni nouveau type d'artefact.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/rules/000-README.md
|
||||||
|
docs/rules/210-WORKFLOW.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.2.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces quatre fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.5/alpha.1.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.5/alpha.2.md`, qui sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
Le plan `docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md`, l'étude `docs/studies/001-KSP_GAMES_RECONCILIATION.md` et `docs/templates/003-NEW_SESSION_PROMPT.md` restent inchangés : cette tranche exécute leur trajectoire et préserve explicitement la séparation entre prompt versionné et message manuel de nouvelle session.
|
||||||
|
|
||||||
|
## Contrat matérialisé
|
||||||
|
|
||||||
|
`docs/rules/210-WORKFLOW.md` porte désormais un contrat réutilisable des prompts de démarrage versionnés couvrant :
|
||||||
|
|
||||||
|
- baseline autoritaire, cible et première tranche ;
|
||||||
|
- ordre de lecture nécessaire à une reprise fiable ;
|
||||||
|
- état déjà acquis et traçabilité des décisions conservées ;
|
||||||
|
- mission et résultat attendu ;
|
||||||
|
- scope et hors-scope ;
|
||||||
|
- décisions gelées et questions ouvertes ;
|
||||||
|
- première gate et travaux éventuellement interdits avant sa fermeture ;
|
||||||
|
- trajectoire prévisionnelle explicitement non contraignante ;
|
||||||
|
- validation et responsabilité de la preuve ;
|
||||||
|
- comportement fail-closed lorsqu'une source externe requise manque.
|
||||||
|
|
||||||
|
Le contrat reste sémantique : il n'impose pas neuf titres littéraux ni une longueur uniforme. Les projets importants peuvent détailler leur ordre de lecture et leurs questions de cadrage ; les projets simples conservent une forme courte dès lors que les mêmes responsabilités sont couvertes.
|
||||||
|
|
||||||
|
Les règles locales de langage, plateforme, framework, architecture ou métier ne deviennent pas des règles PGR parce qu'elles apparaissent dans un prompt. Le prompt doit renvoyer vers les owners existants au lieu de les dupliquer.
|
||||||
|
|
||||||
|
`docs/templates/003-NEW_SESSION_PROMPT.md` conserve son rôle distinct : produire la courte phrase manuelle de reprise après une stable publiée. Il ne remplace pas le prompt versionné et n'est pas dupliqué par cette tranche.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après avoir appliqué `history/0.0.5/alpha.1.md`, committé `0.0.5-alpha.1`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.2'
|
||||||
|
test -f history/0.0.5/alpha.1.md
|
||||||
|
test -f deltas/0.0.5/alpha.2.md
|
||||||
|
test ! -e history/0.0.5/alpha.2.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 12 -->' docs/rules/000-README.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -F 'prompts versionnés' docs/rules/000-README.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.1.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', history)
|
||||||
|
|
||||||
|
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
|
||||||
|
required = (
|
||||||
|
'## Prompt de démarrage versionné',
|
||||||
|
'### Contrat minimal',
|
||||||
|
'baseline autoritaire et cible',
|
||||||
|
'ordre de lecture',
|
||||||
|
'état déjà acquis',
|
||||||
|
'mission et résultat attendu',
|
||||||
|
'scope et hors-scope',
|
||||||
|
'décisions gelées et questions ouvertes',
|
||||||
|
'première gate',
|
||||||
|
'trajectoire prévisionnelle',
|
||||||
|
'validation et responsabilité',
|
||||||
|
'### Sources externes et données manquantes',
|
||||||
|
'### Décisions acquises et détails locaux',
|
||||||
|
'### Création et clôture',
|
||||||
|
'003-NEW_SESSION_PROMPT.md',
|
||||||
|
)
|
||||||
|
for phrase in required:
|
||||||
|
assert phrase in workflow, phrase
|
||||||
|
|
||||||
|
for forbidden in (
|
||||||
|
'prompts/036-V0_3_17_START_PROMPT.md',
|
||||||
|
'prompts/007-V0_3_6_START_PROMPT.md',
|
||||||
|
'tokio-postgres',
|
||||||
|
'WebTransport',
|
||||||
|
'Uroburas',
|
||||||
|
):
|
||||||
|
assert forbidden not in workflow, forbidden
|
||||||
|
|
||||||
|
assert 'MUST NOT les recopier exhaustivement' in workflow
|
||||||
|
assert 'Le prompt n\'a pas à reproduire littéralement cette numérotation.' in workflow
|
||||||
|
assert 'MUST NOT autoriser à reconstituer silencieusement' in workflow
|
||||||
|
assert 'Les contraintes locales de langage, plateforme, framework, architecture ou métier restent chez leurs owners respectifs.' in workflow
|
||||||
|
|
||||||
|
manual = Path('docs/templates/003-NEW_SESSION_PROMPT.md').read_text(encoding='utf-8')
|
||||||
|
assert '<!-- version: 1 -->' in manual
|
||||||
|
assert 'une seule phrase' in manual
|
||||||
|
|
||||||
|
print('0.0.5 alpha.2 prompt contract audit: clean (versioned prompt strengthened, manual restart template unchanged)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION docs/rules/000-README.md docs/rules/210-WORKFLOW.md \
|
||||||
|
deltas/0.0.5/alpha.2.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.2.md
|
||||||
|
M docs/rules/000-README.md
|
||||||
|
M docs/rules/210-WORKFLOW.md
|
||||||
|
```
|
||||||
|
|
||||||
|
La revue opérateur doit en outre confirmer que :
|
||||||
|
|
||||||
|
- le nouveau contrat décrit des responsabilités de reprise et non une liste obligatoire de titres ;
|
||||||
|
- la baseline et les sources manquantes restent fail-closed : aucun état externe n'est reconstruit depuis un souvenir ou un workspace non fourni ;
|
||||||
|
- les décisions acquises sont résumées seulement lorsqu'elles empêchent une régression utile et restent traçables vers leur owner ;
|
||||||
|
- les contraintes KSP/Games spécifiques ne sont pas aspirées dans la règle générale ;
|
||||||
|
- le template `003-NEW_SESSION_PROMPT.md` reste la forme courte post-publication et n'est ni remplacé ni dupliqué.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Rédiger et livrer séparément `history/0.0.5/alpha.2.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.5-alpha.3` pour le pattern facultatif de contrats de fichiers/familles.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le résultat réel dans le history de `alpha.2`, puis corriger le contrat dans `0.0.5-alpha.2.fix.1` ou produire un REPLAN motivé. Aucun contenu de `alpha.3` ne doit être absorbé silencieusement dans un fix.
|
||||||
164
deltas/0.0.5/alpha.3.fix.1.md
Normal file
164
deltas/0.0.5/alpha.3.fix.1.md
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.3.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.3.fix.1 — couverture des tables dans les exemples Markdown fenced
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur de `0.0.5-alpha.3`, réalisé après application de `history/0.0.5/alpha.3.md` avec statut `FAIL`.
|
||||||
|
|
||||||
|
Le hash de ce commit n'est pas anticipé.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.3
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.3.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Corriger le faux négatif découvert pendant la gate opérateur de `alpha.3` : `audit_markdown_tables.py` ignorait toutes les tables placées dans des blocs fenced, y compris les exemples explicitement `markdown` du template `004-FILE_FAMILY_CONTRACTS.md`.
|
||||||
|
|
||||||
|
Le fix étend uniquement le contrat de l'audit de tables. Il ne transforme pas l'audit en analyseur général des blocs de code et n'introduit aucun contenu de la tranche Rust `alpha.4`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
scripts/audit_markdown_tables.py
|
||||||
|
docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
tests/test_markdown_tables.py
|
||||||
|
deltas/0.0.5/alpha.3.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Le history `history/0.0.5/alpha.3.md` appartient au commit baseline du FAIL et n'est pas inclus dans l'archive du fix.
|
||||||
|
|
||||||
|
## Correction
|
||||||
|
|
||||||
|
`scripts/audit_markdown_tables.py` passe en révision interne `2`.
|
||||||
|
|
||||||
|
L'audit continue de contrôler les tables Markdown ordinaires. Dans un bloc fenced :
|
||||||
|
|
||||||
|
- une fence explicitement `markdown` est auditée ;
|
||||||
|
- une fence explicitement `md` est auditée ;
|
||||||
|
- une fence d'un autre langage ou sans langage reste ignorée.
|
||||||
|
|
||||||
|
Cette frontière évite les faux positifs sur les sorties terminal, extraits de code ou tableaux ASCII qui utilisent éventuellement des pipes sans être du Markdown à gouverner.
|
||||||
|
|
||||||
|
`tests/test_markdown_tables.py` verrouille quatre cas :
|
||||||
|
|
||||||
|
1. table ordinaire et table fenced Markdown valides toutes deux comptées ;
|
||||||
|
2. table mal alignée dans une fence `markdown` rejetée ;
|
||||||
|
3. alias `md` audité ;
|
||||||
|
4. fence non Markdown conservée hors scope.
|
||||||
|
|
||||||
|
`docs/templates/004-FILE_FAMILY_CONTRACTS.md` passe en révision `2` et réaligne les deux tables fenced révélées par le nouvel audit.
|
||||||
|
|
||||||
|
`docs/validation/001-VALIDATION_MATRIX.md` passe en révision `10` et explicite la frontière de `PGR-MD-TABLE-001`.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `FAIL`, commit de `alpha.3`, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.3.fix.1'
|
||||||
|
test -f history/0.0.5/alpha.3.md
|
||||||
|
test -f deltas/0.0.5/alpha.3.md
|
||||||
|
test -f deltas/0.0.5/alpha.3.fix.1.md
|
||||||
|
test -f tests/test_markdown_tables.py
|
||||||
|
test ! -e history/0.0.5/alpha.3.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.3.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '# version: 2' scripts/audit_markdown_tables.py
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
grep -Fx '<!-- version: 10 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
grep -Fx '# version: 1' tests/test_markdown_tables.py
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -p 'test_markdown_tables.py' -v
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_tables.py docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.3.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+FAIL\s', history)
|
||||||
|
|
||||||
|
script = Path('scripts/audit_markdown_tables.py').read_text(encoding='utf-8')
|
||||||
|
assert '_MARKDOWN_FENCE_LANGUAGES = frozenset({"markdown", "md"})' in script
|
||||||
|
assert 'audit_fenced_markdown' in script
|
||||||
|
|
||||||
|
template = Path('docs/templates/004-FILE_FAMILY_CONTRACTS.md').read_text(encoding='utf-8')
|
||||||
|
assert template.count('```markdown') == 2
|
||||||
|
|
||||||
|
matrix = Path('docs/validation/001-VALIDATION_MATRIX.md').read_text(encoding='utf-8')
|
||||||
|
assert 'fences explicitement `markdown` ou `md`' in matrix
|
||||||
|
assert 'sorties terminal' in matrix
|
||||||
|
|
||||||
|
print('0.0.5 alpha.3.fix.1 fenced Markdown table audit: clean (regression covered, two template examples governed)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION scripts/audit_markdown_tables.py tests/test_markdown_tables.py \
|
||||||
|
docs/templates/004-FILE_FAMILY_CONTRACTS.md \
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md \
|
||||||
|
deltas/0.0.5/alpha.3.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.3.fix.1.md
|
||||||
|
M docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
M docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
M scripts/audit_markdown_tables.py
|
||||||
|
A tests/test_markdown_tables.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Le contrôle ciblé du template doit désormais compter ses deux exemples :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Markdown table audit: clean (2 table(s), 1 file(s))
|
||||||
|
```
|
||||||
|
|
||||||
|
La suite Python doit compter `19` tests si aucun autre test n'est ajouté localement avant exécution.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer et appliquer séparément `history/0.0.5/alpha.3.fix.1.md`, committer et pousser le fix, puis reprendre le plan `0.0.5` à `alpha.4`.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.3.fix.M`. Le scope MUST rester limité au contrat de `PGR-MD-TABLE-001` et aux tables révélées par ce contrôle tant qu'aucun défaut plus large ne justifie un REPLAN.
|
||||||
173
deltas/0.0.5/alpha.3.md
Normal file
173
deltas/0.0.5/alpha.3.md
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.3.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.3 — pattern facultatif de contrats de fichiers ou familles
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur de `0.0.5-alpha.2`, réalisé après application de `history/0.0.5/alpha.2.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Le hash de ce commit n'est pas anticipé. Le history `alpha.2` et le présent delta peuvent être livrés dans le même échange, mais restent deux archives séparées et le delta `alpha.3` MUST NOT être appliqué avant le commit de `alpha.2`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.2
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Exécuter la troisième tranche du plan `0.0.5` en généralisant un besoin observé indépendamment dans les deux corpus externes : expliciter, lorsque la complexité le justifie, la responsabilité et la règle de modification de certaines familles de fichiers locales.
|
||||||
|
|
||||||
|
La tranche normalise le pattern et non les catalogues KSP/Games. Elle n'impose ni le nom `FILE_CONTRACTS.md`, ni une table exhaustive, ni la reprise de leurs chemins, règles métier ou conventions de release.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/000-README.md
|
||||||
|
docs/rules/300-DOCUMENTATION.md
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
deltas/0.0.5/alpha.3.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive delta contient uniquement ces six fichiers complets avec leurs chemins relatifs. Elle ne contient pas `history/0.0.5/alpha.2.md`, livré séparément pour clôturer la tranche précédente, ni `history/0.0.5/alpha.3.md`, qui sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
## Contrat matérialisé
|
||||||
|
|
||||||
|
`docs/rules/300-DOCUMENTATION.md` possède désormais le pattern générique :
|
||||||
|
|
||||||
|
- un registre local est facultatif et ne doit exister que pour lever une ambiguïté réelle ;
|
||||||
|
- il décrit au minimum fichier/famille, responsabilité durable et règle de modification ;
|
||||||
|
- source de vérité, statut généré/versionné, owner ou validation restent des champs optionnels ;
|
||||||
|
- le registre ne doit ni recopier les owners existants ni devenir un miroir exhaustif de l'arborescence ;
|
||||||
|
- son nom, son emplacement et sa forme appartiennent au projet destinataire ;
|
||||||
|
- l'ajout d'un fichier déjà couvert par une famille ne force pas une entrée supplémentaire.
|
||||||
|
|
||||||
|
`docs/templates/004-FILE_FAMILY_CONTRACTS.md` fournit une forme d'adaptation courte avec critères d'usage, modèle minimal, règles d'instanciation et exemple abstrait.
|
||||||
|
|
||||||
|
La fondation `001-PROJECT_GOVERNANCE_FOUNDATION.md` référence ce pattern uniquement comme possibilité pour un projet dont plusieurs familles durables deviennent ambiguës. Elle confirme explicitement qu'un projet simple n'a rien à matérialiser.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après avoir appliqué `history/0.0.5/alpha.2.md`, committé `0.0.5-alpha.2`, puis appliqué le présent delta, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.3'
|
||||||
|
test -f history/0.0.5/alpha.2.md
|
||||||
|
test -f deltas/0.0.5/alpha.3.md
|
||||||
|
test -f docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
test ! -e history/0.0.5/alpha.3.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 11 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.2.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', history)
|
||||||
|
|
||||||
|
doc = Path('docs/rules/300-DOCUMENTATION.md').read_text(encoding='utf-8')
|
||||||
|
template = Path('docs/templates/004-FILE_FAMILY_CONTRACTS.md').read_text(encoding='utf-8')
|
||||||
|
foundation = Path('docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md').read_text(encoding='utf-8')
|
||||||
|
index = Path('docs/000-README.md').read_text(encoding='utf-8')
|
||||||
|
|
||||||
|
required_doc = (
|
||||||
|
'## Registre local de contrats de fichiers ou familles',
|
||||||
|
'outil de désambiguïsation, pas un inventaire exhaustif',
|
||||||
|
'le fichier, motif de chemin ou famille concernée',
|
||||||
|
'sa responsabilité durable',
|
||||||
|
'la règle ou le déclencheur pertinent de modification',
|
||||||
|
'PGR n\'impose ni `FILE_CONTRACTS.md`',
|
||||||
|
'l\'ajout d\'un fichier conforme à une famille déjà décrite ne force pas une nouvelle entrée',
|
||||||
|
)
|
||||||
|
for phrase in required_doc:
|
||||||
|
assert phrase in doc, phrase
|
||||||
|
|
||||||
|
required_template = (
|
||||||
|
'# Pattern — contrats locaux de fichiers ou familles',
|
||||||
|
'Quand l\'utiliser',
|
||||||
|
'Forme minimale',
|
||||||
|
'Règles d\'adaptation',
|
||||||
|
'Critère de sortie',
|
||||||
|
'`docs/rules/FILE_CONTRACTS.md` est un nom possible, pas une convention PGR obligatoire',
|
||||||
|
)
|
||||||
|
for phrase in required_template:
|
||||||
|
assert phrase in template, phrase
|
||||||
|
|
||||||
|
assert '004-FILE_FAMILY_CONTRACTS.md' in foundation
|
||||||
|
assert 'Ce registre reste facultatif' in foundation
|
||||||
|
assert '004-FILE_FAMILY_CONTRACTS.md' in index
|
||||||
|
|
||||||
|
for text in (doc, template, foundation):
|
||||||
|
for forbidden in ('tokio-postgres', 'WebTransport', 'Uroburas'):
|
||||||
|
assert forbidden not in text, forbidden
|
||||||
|
|
||||||
|
print('0.0.5 alpha.3 file-family contract audit: clean (optional registry, short reusable pattern, no project-specific contract imported)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION docs/000-README.md docs/rules/300-DOCUMENTATION.md \
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||||
|
docs/templates/004-FILE_FAMILY_CONTRACTS.md deltas/0.0.5/alpha.3.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.3.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/rules/300-DOCUMENTATION.md
|
||||||
|
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
A docs/templates/004-FILE_FAMILY_CONTRACTS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
La revue opérateur doit en outre confirmer que :
|
||||||
|
|
||||||
|
- le pattern réduit une ambiguïté réelle au lieu d'imposer une nouvelle cérémonie ;
|
||||||
|
- `FILE_CONTRACTS.md` reste un exemple de nom, jamais une obligation ;
|
||||||
|
- le registre ne devient pas un catalogue exhaustif de chaque fichier du dépôt ;
|
||||||
|
- une règle détaillée déjà possédée ailleurs est référencée plutôt que dupliquée ;
|
||||||
|
- la fondation n'impose aucun nouveau document aux petits projets ou aux projets dont les responsabilités sont déjà claires.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Rédiger et livrer séparément `history/0.0.5/alpha.3.md` avec les résultats réellement observés ; l'appliquer et committer la tranche. Préparer seulement ensuite `0.0.5-alpha.4` pour l'audit Rust facultatif de façade/export completeness.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le résultat réel dans le history de `alpha.3`, puis corriger le pattern dans `0.0.5-alpha.3.fix.1` ou produire un REPLAN motivé. Aucun contenu de l'audit Rust `alpha.4` ne doit être absorbé silencieusement dans un fix.
|
||||||
221
deltas/0.0.5/alpha.4.md
Normal file
221
deltas/0.0.5/alpha.4.md
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.4.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.4 — REPLAN du lifecycle inter-release et de l'horizon
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.3.fix.1`, réalisé après application de `history/0.0.5/alpha.3.fix.1.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Le hash de ce futur commit n'est pas anticipé.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.3.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.4
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rôle de la tranche
|
||||||
|
|
||||||
|
`alpha.4` est un `REPLAN` déclenché après la gate réussie du fix précédent. Il traite un besoin de gouvernance général découvert en relisant le plan `0.0.5`, `ROADMAP.md` et les historiques de conception PGR `0.0.1` à `0.0.4` : les responsabilités de fermeture sont connues séparément mais ne sont pas encore reliées par un contrat explicite de plan, et l'horizon des versions futures ne possède pas de mécanisme de revue.
|
||||||
|
|
||||||
|
La tranche ne remet pas en cause `alpha.3.fix.1`, ne commence pas le chantier Rust de façade et ne matérialise aucun profil Tauri.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
ROADMAP.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/200-GOVERNANCE.md
|
||||||
|
docs/rules/210-WORKFLOW.md
|
||||||
|
docs/rules/300-DOCUMENTATION.md
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
docs/templates/003-NEW_SESSION_PROMPT.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/templates/005-RELEASE_PLAN.md
|
||||||
|
deltas/0.0.5/alpha.4.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Le history `alpha.3.fix.1` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||||
|
|
||||||
|
## Décisions matérialisées
|
||||||
|
|
||||||
|
### Plan de release
|
||||||
|
|
||||||
|
Un plan complexe doit désormais expliciter sa **clôture et transition** : réconciliation documentaire, `CHANGELOG`, `ROADMAP`, prompt/handoff suivant, fermeture du plan, stable et publication.
|
||||||
|
|
||||||
|
Il doit aussi indiquer si une **revue d'horizon** est nécessaire. Une cible future inconnue reste inconnue : PGR interdit d'inventer une version ou une mission uniquement pour remplir le plan.
|
||||||
|
|
||||||
|
### Revue d'horizon
|
||||||
|
|
||||||
|
`ROADMAP.md` devient explicitement une trajectoire macro engagée à horizon fini. Une revue d'horizon est déclenchée lorsque la dernière release connue approche, qu'un jalon change la trajectoire ou que les ideas/studies/décisions accumulées justifient de rediscuter la suite.
|
||||||
|
|
||||||
|
La revue peut vivre dans une session stratégique séparée sans changement de `VERSION`.
|
||||||
|
|
||||||
|
Pour PGR, l'après-`0.1.0` reste volontairement ouvert. Le plan `0.1.0` devra programmer sa propre revue avant fermeture au lieu de spéculer dès `0.0.5`.
|
||||||
|
|
||||||
|
### Continuité et productivité
|
||||||
|
|
||||||
|
Lorsque la gate courante est `PASS` et que la suite est déjà déterminée, le générateur peut remettre `history` courant et `delta` suivant dans la même réponse. Les archives restent séparées et le delta suivant reste interdit d'application avant le commit de la tranche courante.
|
||||||
|
|
||||||
|
Le message manuel après publication devient spontané lorsque la prochaine cible est connue. S'il existe une preuve post-tag externe requise, la consigne finale indique explicitement qu'elle doit être fournie avec l'archive taggée.
|
||||||
|
|
||||||
|
### Pattern de plan
|
||||||
|
|
||||||
|
`docs/templates/005-RELEASE_PLAN.md` fournit une forme courte réutilisable pour KSP, Games et les futurs projets : mission, état acquis/ouvert, scope, validation, forecast, déclencheurs de REPLAN, clôture/transition et revue d'horizon.
|
||||||
|
|
||||||
|
Le pattern ne crée pas un journal de revisions obligatoire ; les deltas/histories restent la trace détaillée.
|
||||||
|
|
||||||
|
## Replan de 0.0.5
|
||||||
|
|
||||||
|
L'ancien forecast est décalé :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.4 REPLAN lifecycle inter-release / horizon
|
||||||
|
alpha.5 audit Rust façade/export completeness
|
||||||
|
alpha.6 profil Tauri
|
||||||
|
alpha.7 décision skeleton Tauri
|
||||||
|
beta.1 réconciliation intégrée
|
||||||
|
rc.1 candidate gelée / CHANGELOG / ROADMAP / prompt 006
|
||||||
|
stable 0.0.5 + publish.001 séparé
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun ancien objectif n'est abandonné par ce décalage.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.3.fix.1`, commit/push de ce fix, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.4'
|
||||||
|
test -f history/0.0.5/alpha.3.fix.1.md
|
||||||
|
test -f deltas/0.0.5/alpha.4.md
|
||||||
|
test -f docs/templates/005-RELEASE_PLAN.md
|
||||||
|
test ! -e history/0.0.5/alpha.4.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.3.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/200-GOVERNANCE.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -Fx '<!-- version: 6 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/templates/003-NEW_SESSION_PROMPT.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/templates/005-RELEASE_PLAN.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.3.fix.1.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', history)
|
||||||
|
|
||||||
|
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'## REPLAN alpha.4 — lifecycle inter-release et horizon',
|
||||||
|
'## Clôture et transition',
|
||||||
|
'## Revue d\'horizon',
|
||||||
|
'### alpha.5 — audit Rust de façade/export completeness',
|
||||||
|
'### alpha.6 — premier profil framework : Tauri',
|
||||||
|
'### alpha.7 — décision de skeleton Tauri',
|
||||||
|
):
|
||||||
|
assert phrase in plan, phrase
|
||||||
|
|
||||||
|
workflow = Path('docs/rules/210-WORKFLOW.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'clôture et transition',
|
||||||
|
'revue d\'horizon',
|
||||||
|
'archive history de la tranche courante',
|
||||||
|
'archive delta de la tranche suivante',
|
||||||
|
'MUST remettre spontanément',
|
||||||
|
'preuve future extérieure au tag',
|
||||||
|
):
|
||||||
|
assert phrase in workflow, phrase
|
||||||
|
|
||||||
|
doc = Path('docs/rules/300-DOCUMENTATION.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'### Revue d\'horizon',
|
||||||
|
'Une roadmap à horizon fini est valide.',
|
||||||
|
'roadmap ou plan lorsqu\'un engagement de réalisation existe',
|
||||||
|
):
|
||||||
|
assert phrase in doc, phrase
|
||||||
|
|
||||||
|
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||||
|
assert '## Horizon après `0.1.0`' in roadmap
|
||||||
|
assert 'L\'horizon est volontairement ouvert.' in roadmap
|
||||||
|
assert '0.2.0' in roadmap # cité uniquement comme version à ne pas réserver arbitrairement
|
||||||
|
|
||||||
|
template = Path('docs/templates/005-RELEASE_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in ('## Contrat minimal', '## Clôture et transition', '## Revue d\'horizon', '## Critère de sortie'):
|
||||||
|
assert phrase in template, phrase
|
||||||
|
|
||||||
|
manual = Path('docs/templates/003-NEW_SESSION_PROMPT.md').read_text(encoding='utf-8')
|
||||||
|
assert 'doit être remis spontanément' in manual
|
||||||
|
assert 'horizon reste ouvert' in manual
|
||||||
|
|
||||||
|
print('0.0.5 alpha.4 lifecycle audit: clean (closure assigned, horizon review explicit, deterministic handoff optimized)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION ROADMAP.md docs/000-README.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/200-GOVERNANCE.md docs/rules/210-WORKFLOW.md \
|
||||||
|
docs/rules/300-DOCUMENTATION.md \
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||||
|
docs/templates/003-NEW_SESSION_PROMPT.md docs/templates/005-RELEASE_PLAN.md \
|
||||||
|
deltas/0.0.5/alpha.4.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history `alpha.4` est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M ROADMAP.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.4.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/200-GOVERNANCE.md
|
||||||
|
M docs/rules/210-WORKFLOW.md
|
||||||
|
M docs/rules/300-DOCUMENTATION.md
|
||||||
|
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
M docs/templates/003-NEW_SESSION_PROMPT.md
|
||||||
|
A docs/templates/005-RELEASE_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer/appliquer `history/0.0.5/alpha.4.md`, committer/pousser `0.0.5-alpha.4`, puis poursuivre le forecast révisé à `0.0.5-alpha.5` pour l'audit Rust de façade/export completeness.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.4.fix.M` tant que le défaut concerne le lifecycle inter-release ou la documentation livrée par cette tranche. Si la revue révèle qu'un autre chantier substantiel doit être absorbé avant l'audit Rust, refaire explicitement le REPLAN plutôt que l'introduire dans un fix.
|
||||||
217
deltas/0.0.5/alpha.5.fix.1.md
Normal file
217
deltas/0.0.5/alpha.5.fix.1.md
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.5.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.5.fix.1 — canonicalisation réelle des références crate-root
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.5`, réalisé après application de `history/0.0.5/alpha.5.md` avec statut `FAIL`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.5
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.5.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cause du fix
|
||||||
|
|
||||||
|
La gate mécanique de `alpha.5` est passée, mais la revue fonctionnelle opérateur a identifié un blind spot dans `RUST-IMPORT-201` : la `version: 1` détecte `crate::module::Item` lorsque `crate::Item` existe, mais ne détecte pas un usage nu ou autrement non canonique de ce même item dans son module propriétaire ou un autre module.
|
||||||
|
|
||||||
|
Or le contrat recherché est bien :
|
||||||
|
|
||||||
|
```text
|
||||||
|
item partagé pub/pub(crate)
|
||||||
|
↓
|
||||||
|
façade crate-root
|
||||||
|
↓
|
||||||
|
toutes les références intra-crate détectées utilisent crate::Item
|
||||||
|
```
|
||||||
|
|
||||||
|
Le compilateur et Clippy ne possèdent pas cette convention. Une seule référence correcte à `crate::Item` peut rendre le réexport utilisé tout en laissant subsister d'autres `Item`, `self::Item`, `super::Item` ou chemins internes.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/510-RUST_CARGO.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
scripts/audit_rust_export_completeness.py
|
||||||
|
tests/test_rust_export_completeness.py
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.5.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Le history `alpha.5` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||||
|
|
||||||
|
## Décisions matérialisées
|
||||||
|
|
||||||
|
### RUST-IMPORT-201 couvre toute référence non canonique détectable
|
||||||
|
|
||||||
|
Pour un item possédant une identité crate-root, la seule forme intra-crate canonique est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
crate::Item
|
||||||
|
```
|
||||||
|
|
||||||
|
Le diagnostic couvre désormais les formes suivantes lorsqu'elles désignent cet item partagé :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Item
|
||||||
|
self::Item
|
||||||
|
super::Item
|
||||||
|
module::Item
|
||||||
|
crate::module::Item
|
||||||
|
```
|
||||||
|
|
||||||
|
La règle s'applique au module propriétaire lui-même : signatures, `impl`, constructeurs, appels et références de types doivent employer la façade crate-root lorsqu'ils portent l'item partagé.
|
||||||
|
|
||||||
|
Les déclarations qui créent l'item et les lignes de réexport qui construisent la façade sont exemptées. Les éléments strictement privés restent hors de cette règle ; leurs tests attachés peuvent utiliser `super::PrivateItem`.
|
||||||
|
|
||||||
|
### Targets Cargo distinctes
|
||||||
|
|
||||||
|
Le fix évite également de confondre bibliothèque et binaire d'un même package. `src/lib.rs`, `src/main.rs`, les bins standard et les targets explicites sont traités comme des crates compilées distinctes. Le graphe de modules de chaque target est suivi via `mod name;` et `#[path = "..."]`.
|
||||||
|
|
||||||
|
Cette correction est nécessaire pour ne pas qualifier à tort `owner_crate::Item` dans un binaire comme référence intra-crate de la bibliothèque du même package.
|
||||||
|
|
||||||
|
### Analyse lexicale bornée
|
||||||
|
|
||||||
|
L'audit reste read-only et standard library. Il ne prétend pas remplacer un parseur Rust :
|
||||||
|
|
||||||
|
- les commentaires et littéraux sont masqués ;
|
||||||
|
- les chemins qualifiés par une crate externe ne sont pas assimilés à l'item local homonyme ;
|
||||||
|
- un appel de méthode `.name()` n'est pas assimilé à une fonction libre locale de même nom ;
|
||||||
|
- les fonctions libres sont contrôlées dans les contextes d'appel directs ; leur usage comme valeur de premier ordre peut nécessiter une revue humaine.
|
||||||
|
|
||||||
|
### Réconciliation corrigée
|
||||||
|
|
||||||
|
En `--report-only --summary-only`, la `version: 2` observe sur les baselines de `alpha.1` :
|
||||||
|
|
||||||
|
```text
|
||||||
|
KSP 0.3.16
|
||||||
|
22 package(s)
|
||||||
|
1525 candidate(s)
|
||||||
|
RUST-IMPORT-201: 1525
|
||||||
|
|
||||||
|
Games 0.3.5
|
||||||
|
23 package(s)
|
||||||
|
181 candidate(s)
|
||||||
|
RUST-API-201: 2
|
||||||
|
RUST-IMPORT-201: 179
|
||||||
|
```
|
||||||
|
|
||||||
|
Ces nombres sont des lignes candidates à revoir, pas des déclarations distinctes. Ils ne constituent pas une non-conformité rétroactive : KSP et Games ne sont pas encore gouvernés par ce PGR. Ils montrent pourquoi une future adoption doit commencer par un inventaire `--report-only` et une migration proportionnée.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `FAIL` de `alpha.5`, commit/push de cette tranche, puis application du présent fix :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.5.fix.1'
|
||||||
|
test -f history/0.0.5/alpha.5.md
|
||||||
|
test -f deltas/0.0.5/alpha.5.fix.1.md
|
||||||
|
test ! -e history/0.0.5/alpha.5.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.5.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '# version: 2' scripts/audit_rust_export_completeness.py
|
||||||
|
grep -Fx '# version: 2' tests/test_rust_export_completeness.py
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/510-RUST_CARGO.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -p 'test_rust_export_completeness.py' -v
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.5.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+FAIL\s', history)
|
||||||
|
|
||||||
|
script = Path('scripts/audit_rust_export_completeness.py').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'def target_roots(',
|
||||||
|
'def target_modules(',
|
||||||
|
'def _canonical_reference_candidates(',
|
||||||
|
'RUST-API-201',
|
||||||
|
'RUST-IMPORT-201',
|
||||||
|
'non-canonical same-crate reference',
|
||||||
|
):
|
||||||
|
assert phrase in script, phrase
|
||||||
|
|
||||||
|
validation = Path('docs/validation/003-RUST_EXPORT_COMPLETENESS.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'Item\nself::Item\nsuper::Item\nmodule::Item\ncrate::module::Item',
|
||||||
|
'dans le module qui déclare l\'item',
|
||||||
|
'1525 candidate(s)',
|
||||||
|
'181 candidate(s)',
|
||||||
|
'pas des déclarations distinctes',
|
||||||
|
):
|
||||||
|
assert phrase in validation, phrase
|
||||||
|
|
||||||
|
rules = Path('docs/rules/510-RUST_CARGO.md').read_text(encoding='utf-8')
|
||||||
|
assert 'toute référence dans la même crate MUST utiliser `crate::Item`' in rules
|
||||||
|
assert 'y compris depuis son module de déclaration' in rules
|
||||||
|
|
||||||
|
print('0.0.5 alpha.5.fix.1 canonical Rust path audit: clean (owner module, cross-module, attached tests, distinct Cargo targets)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/510-RUST_CARGO.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
docs/validation/003-RUST_EXPORT_COMPLETENESS.md \
|
||||||
|
scripts/audit_rust_export_completeness.py \
|
||||||
|
tests/test_rust_export_completeness.py \
|
||||||
|
deltas/0.0.5/alpha.5.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history du fix est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.5.fix.1.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/510-RUST_CARGO.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
M docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
M scripts/audit_rust_export_completeness.py
|
||||||
|
M tests/test_rust_export_completeness.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer/appliquer `history/0.0.5/alpha.5.fix.1.md`, committer/pousser `0.0.5-alpha.5.fix.1`, puis poursuivre à `0.0.5-alpha.6` pour le profil Tauri prévu par le plan.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.5.fix.M`. Aucun travail Tauri ne doit être absorbé tant que le contrat de façade Rust n'est pas correctement fermé.
|
||||||
205
deltas/0.0.5/alpha.5.md
Normal file
205
deltas/0.0.5/alpha.5.md
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.5.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.5 — audit Rust de façade/export completeness
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.4`, réalisé après application de `history/0.0.5/alpha.4.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Le hash de ce futur commit n'est pas anticipé.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.5
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rôle de la tranche
|
||||||
|
|
||||||
|
`alpha.5` extrait un audit Rust facultatif réellement réutilisable à partir du corpus KSP/Games, mais corrige avant généralisation une limite découverte dans le script historique : Games organise ses crates sous plusieurs niveaux et n'était pas réellement couvert par le glob `crates/*/Cargo.toml`.
|
||||||
|
|
||||||
|
La tranche reste limitée à la façade crate-root et aux chemins same-crate canoniques. Elle ne copie pas `audit_rust_general_rules.py`, ne commence pas Tauri et ne transforme pas PGR en workspace Rust.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/510-RUST_CARGO.md
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
scripts/audit_rust_export_completeness.py
|
||||||
|
tests/test_rust_export_completeness.py
|
||||||
|
deltas/0.0.5/alpha.5.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Le history `alpha.4` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||||
|
|
||||||
|
## Décisions matérialisées
|
||||||
|
|
||||||
|
### Audit monotâche
|
||||||
|
|
||||||
|
Le nouveau script possède exactement deux responsabilités :
|
||||||
|
|
||||||
|
```text
|
||||||
|
RUST-API-201
|
||||||
|
façade crate-root absente pour un élément public, ou crate-public clairement partagé
|
||||||
|
|
||||||
|
RUST-IMPORT-201
|
||||||
|
chemin `crate::module::Item` alors qu'un réexport explicite fournit déjà `crate::Item`
|
||||||
|
```
|
||||||
|
|
||||||
|
Les conventions des tests unitaires séparés du script historique ne sont pas reprises. Le contrôle d'un symbole `crate::X` inexistant n'est pas repris non plus, car le compilateur Rust possède déjà la résolution de noms.
|
||||||
|
|
||||||
|
### Découverte des crates
|
||||||
|
|
||||||
|
La découverte des `Cargo.toml` devient récursive et accepte les crates imbriquées. Les arbres générés usuels (`target`, `build`, `builds`, `dist`, `node_modules`, etc.) restent ignorés.
|
||||||
|
|
||||||
|
Le module fichier `foo/mod.rs` est interprété comme `foo`, et les réexports crate-root simples, groupés ou aliasés couverts par les tests sont reconnus.
|
||||||
|
|
||||||
|
### Adoption facultative
|
||||||
|
|
||||||
|
Le contrat général Rust reste un `SHOULD`. Un projet existant peut commencer avec `--report-only`, traiter les écarts ou exceptions locales, puis rendre l'audit bloquant seulement après décision explicite.
|
||||||
|
|
||||||
|
L'audit est documenté dans `docs/validation/003-RUST_EXPORT_COMPLETENESS.md` et référencé par le skeleton Rust/Cargo sans devenir obligatoire.
|
||||||
|
|
||||||
|
### Mesure de réconciliation
|
||||||
|
|
||||||
|
La prévalidation générateur sur les baselines autoritaires de `alpha.1` observe :
|
||||||
|
|
||||||
|
```text
|
||||||
|
KSP 0.3.16 22 crate(s) 0 candidate(s)
|
||||||
|
Games 0.3.5 23 crate(s) 2 candidate(s)
|
||||||
|
```
|
||||||
|
|
||||||
|
Le résultat Games antérieur `0 candidate(s)` provenait d'une découverte de crates incomplète. Les deux candidats actuels ne sont pas traités comme des défauts historiques, car Games n'est pas encore gouverné par PGR.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.4`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.5'
|
||||||
|
test -f history/0.0.5/alpha.4.md
|
||||||
|
test -f deltas/0.0.5/alpha.5.md
|
||||||
|
test -f scripts/audit_rust_export_completeness.py
|
||||||
|
test -f tests/test_rust_export_completeness.py
|
||||||
|
test -f docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
test ! -e history/0.0.5/alpha.5.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.4.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '# version: 1' scripts/audit_rust_export_completeness.py
|
||||||
|
grep -Fx '# version: 1' tests/test_rust_export_completeness.py
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/510-RUST_CARGO.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
grep -Fx '<!-- version: 11 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -p 'test_rust_export_completeness.py' -v
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.4.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', history)
|
||||||
|
|
||||||
|
script = Path('scripts/audit_rust_export_completeness.py').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'def crate_roots(',
|
||||||
|
'root.rglob("Cargo.toml")',
|
||||||
|
'RUST-API-201',
|
||||||
|
'RUST-IMPORT-201',
|
||||||
|
'--report-only',
|
||||||
|
'--summary-only',
|
||||||
|
):
|
||||||
|
assert phrase in script, phrase
|
||||||
|
for forbidden in ('RUST-IMPORT-202', 'RUST-IMPORT-203', 'RUST-IMPORT-204', 'RUST-IMPORT-205'):
|
||||||
|
assert forbidden not in script, forbidden
|
||||||
|
|
||||||
|
validation = Path('docs/validation/003-RUST_EXPORT_COMPLETENESS.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'22` crates KSP',
|
||||||
|
'23` crates Games',
|
||||||
|
'0 candidate(s)',
|
||||||
|
'2 candidate(s)',
|
||||||
|
'ne sont pas qualifiés de défauts rétroactifs',
|
||||||
|
):
|
||||||
|
assert phrase in validation, phrase
|
||||||
|
|
||||||
|
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
assert 'KSP = 0 candidate(s) / 22 crates' in plan
|
||||||
|
assert 'Games = 2 candidate(s) / 23 crates' in plan
|
||||||
|
|
||||||
|
print('0.0.5 alpha.5 Rust façade audit: clean (recursive crate discovery, narrow ownership, regression coverage)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION docs/000-README.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/510-RUST_CARGO.md \
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md \
|
||||||
|
docs/validation/003-RUST_EXPORT_COMPLETENESS.md \
|
||||||
|
scripts/audit_rust_export_completeness.py \
|
||||||
|
tests/test_rust_export_completeness.py \
|
||||||
|
deltas/0.0.5/alpha.5.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history `alpha.5` est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.5.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/510-RUST_CARGO.md
|
||||||
|
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
M docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
A docs/validation/003-RUST_EXPORT_COMPLETENESS.md
|
||||||
|
A scripts/audit_rust_export_completeness.py
|
||||||
|
A tests/test_rust_export_completeness.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer/appliquer `history/0.0.5/alpha.5.md`, committer/pousser `0.0.5-alpha.5`, puis poursuivre à `0.0.5-alpha.6` pour le premier profil framework Tauri.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.5.fix.M` si le défaut concerne l'audit, ses tests, sa documentation ou l'intégration Rust/Cargo. Ne pas absorber le profil Tauri dans un fix.
|
||||||
178
deltas/0.0.5/alpha.6.fix.1.md
Normal file
178
deltas/0.0.5/alpha.6.fix.1.md
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.6.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.6.fix.1 — composition Tauri/Rust/frontend et gate corrigé
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6`, réalisé après application de `history/0.0.5/alpha.6.md` avec statut `FAIL`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.6
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.6.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cause du fix
|
||||||
|
|
||||||
|
Deux défauts appartiennent au scope exact de `alpha.6` :
|
||||||
|
|
||||||
|
1. le heredoc Python de la gate `alpha.6` contient une chaîne multilignes entre quotes simples et échoue avec `SyntaxError: unterminated string literal` ;
|
||||||
|
2. le profil livré ne distingue pas encore assez explicitement le contrat Tauri universel des conventions de structure/stack retenues pour les projets Tauri que l'organisation contrôle.
|
||||||
|
|
||||||
|
La clarification opérateur confirme aussi un écart plus large dans le profil Rust strict PGR. Ce troisième sujet ne doit pas être absorbé par le présent fix : il est replanifié en `alpha.7`, puis la décision de skeleton Tauri passe à `alpha.8`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/700-FRAMEWORKS.md
|
||||||
|
docs/rules/710-TAURI.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.6.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Décisions corrigées
|
||||||
|
|
||||||
|
Le fix précise que :
|
||||||
|
|
||||||
|
- un host Tauri est un projet Rust/Cargo et n'obtient aucune exception implicite aux règles Rust sélectionnées ;
|
||||||
|
- un projet externe/imposé peut conserver des règles différentes via le niveau project-specific ou des overrides explicites ;
|
||||||
|
- le profil Tauri universel ne possède pas le choix `frontend/`, Vite, TypeScript, Sass, Bootstrap ou du package manager ;
|
||||||
|
- ces choix forment un candidat de skeleton pour les futurs projets contrôlés ;
|
||||||
|
- WASM n'est pas une composante implicite de Tauri et reste normalement une unité séparée avec ses propres owners ;
|
||||||
|
- `cargo tauri add` est une commodité, pas une obligation : l'ajout explicite des dépendances et de l'initialisation à partir de la documentation officielle des plugins est valide et peut être préféré pour garder le contrôle des manifests ;
|
||||||
|
- un POC mobile non concluant pour Games ne permet pas de rejeter Tauri Android/iOS pour d'autres produits.
|
||||||
|
|
||||||
|
## REPLAN borné
|
||||||
|
|
||||||
|
La clarification révèle qu'une décision Rust déjà retenue historiquement n'est pas complètement matérialisée dans `510-RUST_CARGO.md`. `alpha.7` devient donc une tranche normale de complétude du profil Rust strict, puis l'ancienne décision de skeleton Tauri devient `alpha.8`.
|
||||||
|
|
||||||
|
Le présent fix ne modifie pas `510-RUST_CARGO.md` et n'ajoute aucun nouvel audit Rust : cela constituerait un nouveau scope fonctionnel.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `FAIL` de `alpha.6`, commit/push de cette tranche, puis application du présent fix :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.6.fix.1'
|
||||||
|
test -f history/0.0.5/alpha.6.md
|
||||||
|
test -f deltas/0.0.5/alpha.6.fix.1.md
|
||||||
|
test ! -e history/0.0.5/alpha.6.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.6.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/700-FRAMEWORKS.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/710-TAURI.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 6 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.6.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+FAIL\s', history)
|
||||||
|
|
||||||
|
frameworks = Path('docs/rules/700-FRAMEWORKS.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
"Il n'annule pas silencieusement les conventions des owners qu'il compose.",
|
||||||
|
'Un projet existant ou imposé de l'extérieur MAY conserver des contraintes différentes.',
|
||||||
|
'## Profil framework et convention d'instanciation',
|
||||||
|
):
|
||||||
|
assert phrase in frameworks, phrase
|
||||||
|
|
||||||
|
tauri = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'## Héritage Rust du host Tauri',
|
||||||
|
'Tauri ne crée aucune exception implicite aux règles Rust sélectionnées par le projet.',
|
||||||
|
'PGR MUST NOT imposer universellement Vite, TypeScript, Sass, Bootstrap, Tailwind CSS',
|
||||||
|
'WASM n'est pas une composante implicite d'un projet Tauri.',
|
||||||
|
'PGR ne définit aucun catalogue de plugins Tauri obligatoires et ne rend pas `cargo tauri add` obligatoire.',
|
||||||
|
'Un POC Tauri mobile non concluant pour un produit particulier ne constitue pas une preuve',
|
||||||
|
):
|
||||||
|
assert phrase in tauri, phrase
|
||||||
|
|
||||||
|
version_chain = '\n'.join((
|
||||||
|
'VERSION',
|
||||||
|
'↓',
|
||||||
|
'workspace.package.version',
|
||||||
|
'↓',
|
||||||
|
'package Cargo du host',
|
||||||
|
'↓',
|
||||||
|
'version applicative Tauri',
|
||||||
|
))
|
||||||
|
assert version_chain in tauri
|
||||||
|
|
||||||
|
study = Path('docs/studies/001-KSP_GAMES_RECONCILIATION.md').read_text(encoding='utf-8')
|
||||||
|
assert 'candidat de skeleton pour projets contrôlés' in study
|
||||||
|
assert 'WASM n'est pas une dépendance implicite de Tauri' in study
|
||||||
|
assert 'écart antérieur dans le profil Rust PGR' in study
|
||||||
|
|
||||||
|
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
assert '### alpha.7 — complétude du profil Rust strict' in plan
|
||||||
|
assert '### alpha.8 — décision de skeleton Tauri pour projets contrôlés' in plan
|
||||||
|
|
||||||
|
print('0.0.5 alpha.6.fix.1 Tauri composition audit: clean (Rust inherited, frontend/skeleton separated, WASM independent, gate valid)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/architecture/003-RULE_PROFILE_MODEL.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/700-FRAMEWORKS.md docs/rules/710-TAURI.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
deltas/0.0.5/alpha.6.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.6.fix.1.md
|
||||||
|
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/700-FRAMEWORKS.md
|
||||||
|
M docs/rules/710-TAURI.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer/appliquer `history/0.0.5/alpha.6.fix.1.md`, committer/pousser le fix, puis poursuivre à `0.0.5-alpha.7` pour réconcilier les conventions Rust strictes déjà décidées avant toute matérialisation d'un skeleton Tauri.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.6.fix.M`. Aucun changement du profil Rust ni skeleton Tauri ne doit être absorbé tant que la frontière Tauri/Rust/frontend n'est pas correctement fermée.
|
||||||
167
deltas/0.0.5/alpha.6.fix.2.md
Normal file
167
deltas/0.0.5/alpha.6.fix.2.md
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.6.fix.2.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.6.fix.2 — convention Tauri contrôlée et gate robuste
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6.fix.1`, réalisé après application de `history/0.0.5/alpha.6.fix.1.md` avec statut `FAIL`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.6.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.6.fix.2
|
||||||
|
```
|
||||||
|
|
||||||
|
## Cause du fix
|
||||||
|
|
||||||
|
`alpha.6.fix.1` conserve une gate Python invalide : une phrase contenant `l'extérieur` est placée dans une chaîne simple et son apostrophe provoque encore `SyntaxError: unterminated string literal`.
|
||||||
|
|
||||||
|
La revue opérateur demande en parallèle de confronter le profil non seulement aux configurations Tauri mais aux règles complètes KSP/Games. Cette seconde passe montre qu'une convention de projet contrôlé plus riche est déjà éprouvée et doit être distinguée du contrat Tauri universel.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/710-TAURI.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.6.fix.2.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Décisions
|
||||||
|
|
||||||
|
Le fix établit pour les nouveaux projets Tauri contrôlés une convention forte mais adaptable :
|
||||||
|
|
||||||
|
- host Cargo direct, sans `src-tauri/` ajouté par réflexe ;
|
||||||
|
- fichiers Tauri/frontend principaux à la racine de la crate et sources Rust sous `src/` ;
|
||||||
|
- frontend versionné sous `frontend/` ;
|
||||||
|
- `lib.rs` comme façade, `main.rs` comme launcher mince et `tauri.rs` comme owner de l'assemblage et des wrappers `#[tauri::command]` ;
|
||||||
|
- modules cohérents par fenêtre/responsabilité et modules communs pour les helpers réellement partagés ;
|
||||||
|
- TS-RS obligatoire dans le profil strict lorsque des DTO/enum/struct Rust possédés par le host sont partagés avec un frontend TypeScript, sauf incompatibilité documentée ;
|
||||||
|
- bindings générés reconstruisibles et non modifiés manuellement ;
|
||||||
|
- intégration explicite des plugins préférée à une commande de commodité opaque ;
|
||||||
|
- WASM séparé du host Tauri par défaut.
|
||||||
|
|
||||||
|
Vite, TypeScript, Sass et Bootstrap restent le candidat de stack/skeleton pour les projets contrôlés ; ils ne deviennent pas des invariants universels du framework Tauri tant que leurs owners Web ne sont pas matérialisés.
|
||||||
|
|
||||||
|
## Replanification
|
||||||
|
|
||||||
|
La seconde lecture des règles KSP/Games montre que `alpha.7` serait trop large si elle mélangeait conventions sémantiques, nomenclature et tous les audits de formatage. Le forecast devient :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.7 profil Rust strict + chemins + nomenclature des crates
|
||||||
|
alpha.8 formatage Rust structurel + audits monotâches
|
||||||
|
alpha.9 décision de skeleton Tauri pour projets contrôlés
|
||||||
|
beta.1 réconciliation intégrée
|
||||||
|
```
|
||||||
|
|
||||||
|
KSP est utilisé comme référence stricte ; Games sert à identifier ce qui doit rester `SHOULD`, sélectionnable ou project-specific.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `FAIL` de `alpha.6.fix.1`, commit/push de cette tranche, puis application du présent fix :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.6.fix.2'
|
||||||
|
test -f history/0.0.5/alpha.6.fix.1.md
|
||||||
|
test -f deltas/0.0.5/alpha.6.fix.2.md
|
||||||
|
test ! -e history/0.0.5/alpha.6.fix.2.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.6.fix.1.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/710-TAURI.md
|
||||||
|
grep -Fx '<!-- version: 6 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 7 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.6.fix.1.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+FAIL\s", history)
|
||||||
|
|
||||||
|
tauri = Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"## Convention renforcée pour les projets contrôlés",
|
||||||
|
"sans couche `src-tauri/` ajoutée uniquement pour reproduire `create-tauri-app`",
|
||||||
|
"`src/tauri.rs` SHOULD posséder l'assemblage Tauri et les wrappers `#[tauri::command]`",
|
||||||
|
"partagés avec le frontend MUST utiliser TS-RS comme source de génération",
|
||||||
|
"WASM reste normalement une unité séparée de la crate Tauri",
|
||||||
|
):
|
||||||
|
assert phrase in tauri, phrase
|
||||||
|
|
||||||
|
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"Commun aux `8` hosts Tauri observés",
|
||||||
|
"aucun ne possède `src-tauri/`",
|
||||||
|
"KSP plus strict mais réutilisable",
|
||||||
|
"Nomenclature des crates",
|
||||||
|
):
|
||||||
|
assert phrase in study, phrase
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"### alpha.7 — profil Rust strict, chemins et nomenclature explicite",
|
||||||
|
"### alpha.8 — formatage Rust structurel et audits monotâches",
|
||||||
|
"### alpha.9 — décision de skeleton Tauri pour projets contrôlés",
|
||||||
|
):
|
||||||
|
assert phrase in plan, phrase
|
||||||
|
|
||||||
|
print("0.0.5 alpha.6.fix.2 Tauri convention audit: clean (8 hosts reconciled, strict controlled layout separated from universal framework)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/710-TAURI.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
deltas/0.0.5/alpha.6.fix.2.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.6.fix.2.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/710-TAURI.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer/appliquer `history/0.0.5/alpha.6.fix.2.md`, committer/pousser le fix, puis poursuivre avec `alpha.7`.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.6.fix.M`. Ne pas commencer la réconciliation Rust tant que la convention Tauri et sa gate ne sont pas fermées proprement.
|
||||||
140
deltas/0.0.5/alpha.6.fix.3.md
Normal file
140
deltas/0.0.5/alpha.6.fix.3.md
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.6.fix.3.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.6.fix.3 — politique de versions Tauri/frontend
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6.fix.2`, réalisé après application de `history/0.0.5/alpha.6.fix.2.md` avec statut `FAIL`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.6.fix.3
|
||||||
|
```
|
||||||
|
|
||||||
|
## Motif
|
||||||
|
|
||||||
|
La gate mécanique de `alpha.6.fix.2` est propre, mais la revue fonctionnelle identifie une convention mal généralisée : KSP et Games ont tous deux utilisé l'omission de `tauri.conf.json > version` et une `package.json > version` rarement synchronisée comme moyen de réduire le churn des prereleases. PGR ne doit pas transformer cette solution historique en obligation.
|
||||||
|
|
||||||
|
L'objectif réel est de conserver `VERSION` comme identité exacte de travail tout en évitant de modifier les miroirs produit qui n'ont pas besoin de suivre chaque `alpha`, `.fix`, beta ou RC.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/200-GOVERNANCE.md
|
||||||
|
docs/rules/710-TAURI.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.6.fix.3.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Décisions
|
||||||
|
|
||||||
|
Le fix rétablit une classification explicite des valeurs de version :
|
||||||
|
|
||||||
|
- `CANONICAL` pour `VERSION` ;
|
||||||
|
- `MIRROR-EXACT` pour les miroirs techniques qui doivent suivre chaque prerelease ;
|
||||||
|
- `MIRROR-STABLE` pour les champs qui portent seulement la cible `X.Y.Z` ;
|
||||||
|
- catégories indépendantes pour compteurs, schémas et révisions documentaires.
|
||||||
|
|
||||||
|
Pour une application Tauri contrôlée appartenant au même produit, `tauri.conf.json > version` et `package.json > version`, lorsqu'ils sont conservés, SHOULD être `MIRROR-STABLE` par défaut et porter `X.Y.Z` pendant tout le développement de cette cible. Ils ne sont pas modifiés uniquement pour passer de `alpha.N` à un autre alpha/fix/beta/RC.
|
||||||
|
|
||||||
|
Si des bundles prerelease sont réellement distribués et doivent être identifiables séparément, le projet MAY sélectionner `MIRROR-EXACT` ou une politique de jalons de packaging documentée. L'omission d'un champ reste possible lorsqu'il est réellement inutile, mais elle n'est plus la stratégie PGR recommandée uniquement pour éviter le churn.
|
||||||
|
|
||||||
|
La revue obligatoire déclenchée par `.fix.3` conclut `CONTINUE` : `alpha.6` reste bornée au profil Tauri ; `alpha.7`, `alpha.8` et `alpha.9` conservent leurs scopes distincts.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
Ce fix ne modifie ni les règles Rust strictes prévues en `alpha.7`, ni les audits de formatage de `alpha.8`, ni le skeleton Tauri de `alpha.9`. Il ne modifie pas non plus la politique Cargo existante de `510-RUST_CARGO.md`.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `FAIL` de `alpha.6.fix.2`, commit/push de cette tranche, puis application du présent fix :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.6.fix.3'
|
||||||
|
test -f history/0.0.5/alpha.6.fix.2.md
|
||||||
|
test -f deltas/0.0.5/alpha.6.fix.3.md
|
||||||
|
test ! -e history/0.0.5/alpha.6.fix.3.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.6.fix.2.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/200-GOVERNANCE.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/710-TAURI.md
|
||||||
|
grep -Fx '<!-- version: 7 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 8 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.6.fix.2.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+FAIL\s", history)
|
||||||
|
|
||||||
|
governance = Path("docs/rules/200-GOVERNANCE.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"MIRROR-EXACT",
|
||||||
|
"MIRROR-STABLE",
|
||||||
|
"Seul un `MIRROR-EXACT` est normalement modifié à chaque changement de `VERSION`.",
|
||||||
|
"PGR MUST NOT imposer la suppression d'un champ utile uniquement pour éviter de le modifier à chaque prerelease",
|
||||||
|
):
|
||||||
|
assert phrase in governance, phrase
|
||||||
|
|
||||||
|
tauri = Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"PGR MUST NOT imposer l'une de ces deux formes uniquement pour réduire le nombre de fichiers modifiés.",
|
||||||
|
"la politique recommandée lorsque les prereleases ne sont pas distribuées comme produits installables distincts est `MIRROR-STABLE`",
|
||||||
|
"tauri.conf.json version = X.Y.Z",
|
||||||
|
"package.json version = X.Y.Z",
|
||||||
|
"remplace explicitement les conventions historiques KSP/Games",
|
||||||
|
):
|
||||||
|
assert phrase in tauri, phrase
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
assert "`alpha.6.fix.3` restaure la classification générale" in plan
|
||||||
|
assert "résultat `CONTINUE`" in plan
|
||||||
|
|
||||||
|
print("0.0.5 alpha.6.fix.3 version policy audit: clean (canonical/exact/stable mirrors classified, Tauri/frontend churn bounded)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/200-GOVERNANCE.md docs/rules/710-TAURI.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
deltas/0.0.5/alpha.6.fix.3.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.6.fix.3.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/200-GOVERNANCE.md
|
||||||
|
M docs/rules/710-TAURI.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
189
deltas/0.0.5/alpha.6.md
Normal file
189
deltas/0.0.5/alpha.6.md
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.6.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.6 — premier profil framework : Tauri 2
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.5.fix.1`, réalisé après application de `history/0.0.5/alpha.5.fix.1.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.5.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.6
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
RULES.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/000-README.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/rules/700-FRAMEWORKS.md
|
||||||
|
docs/rules/710-TAURI.md
|
||||||
|
deltas/0.0.5/alpha.6.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Le history `alpha.5.fix.1` appartient au commit baseline et n'est pas inclus dans l'archive du présent delta.
|
||||||
|
|
||||||
|
## Preuve de généralisation
|
||||||
|
|
||||||
|
Les baselines autoritaires étudiées en `alpha.1` contiennent :
|
||||||
|
|
||||||
|
```text
|
||||||
|
KSP 0.3.16 6 applications Tauri
|
||||||
|
Games 0.3.5 2 applications Tauri
|
||||||
|
```
|
||||||
|
|
||||||
|
Les huit applications utilisent Tauri 2 avec un host Rust/Cargo, `tauri-build`, `tauri.conf.json`, des capability files, des hooks frontend et un `frontendDist`. Elles divergent en revanche sur fenêtres, ports, CSP, bundling, plugins, ressources et contenu réel des hooks.
|
||||||
|
|
||||||
|
Le profil normalise donc les responsabilités et l'orchestration communes, pas ces valeurs locales.
|
||||||
|
|
||||||
|
## Décisions matérialisées
|
||||||
|
|
||||||
|
### Famille `700 — frameworks`
|
||||||
|
|
||||||
|
`700-FRAMEWORKS.md` devient l'owner des règles communes aux frameworks : composition avec les owners langage/plateforme, ownership des commandes d'intégration, classification des artefacts générés, cohérence de version produit et validation proportionnée.
|
||||||
|
|
||||||
|
La famille interdit notamment de supposer qu'un framework absorbe automatiquement son frontend, sa plateforme ou son package manager.
|
||||||
|
|
||||||
|
### Profil `710 — Tauri 2`
|
||||||
|
|
||||||
|
Le profil Tauri :
|
||||||
|
|
||||||
|
- se compose au-dessus de Rust/Cargo et des plateformes réellement ciblées ;
|
||||||
|
- ne rend pas Vite, WASM, TypeScript ou npm obligatoires ;
|
||||||
|
- ne rend pas `src-tauri/` obligatoire lorsque la toolchain supporte clairement un autre layout ;
|
||||||
|
- possède l'orchestration via le CLI Tauri lorsque les hooks/config/capabilities/bundles sont concernés ;
|
||||||
|
- distingue un check Rust, un build frontend et une preuve d'intégration Tauri ;
|
||||||
|
- préfère une chaîne de version unique `VERSION → workspace Cargo → package host → Tauri` lorsque l'application partage le release train et que la configuration Tauri peut omettre sa propre version ;
|
||||||
|
- traite les capability files comme source de sécurité intentionnelle ;
|
||||||
|
- ne généralise ni plugins, CSP, fenêtres, bundles, ports ni ressources des corpus ;
|
||||||
|
- ne généralise pas l'ignorance de tout `gen/`, car un projet mobile généré peut recevoir des personnalisations intentionnelles ;
|
||||||
|
- sélectionne `tauri dev/build` ou leur équivalent seulement lorsque la propriété à prouver le justifie.
|
||||||
|
|
||||||
|
### Pas de skeleton dans cette tranche
|
||||||
|
|
||||||
|
`alpha.6` ne crée aucun `tauri.conf.json`, package frontend, template Tauri ou skeleton. La décision de matérialiser une specialization Tauri appartient explicitement à `alpha.7`.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.5.fix.1`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.6'
|
||||||
|
test -f history/0.0.5/alpha.5.fix.1.md
|
||||||
|
test -f deltas/0.0.5/alpha.6.md
|
||||||
|
test -f docs/rules/700-FRAMEWORKS.md
|
||||||
|
test -f docs/rules/710-TAURI.md
|
||||||
|
test ! -e history/0.0.5/alpha.6.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.5.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 11 -->' RULES.md
|
||||||
|
grep -Fx '<!-- version: 13 -->' docs/rules/000-README.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/rules/700-FRAMEWORKS.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/rules/710-TAURI.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path('history/0.0.5/alpha.5.fix.1.md').read_text(encoding='utf-8')
|
||||||
|
assert re.search(r'## Statut\s+PASS\s', history)
|
||||||
|
|
||||||
|
frameworks = Path('docs/rules/700-FRAMEWORKS.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'# Règles de profils framework',
|
||||||
|
"Ownership des commandes d'intégration",
|
||||||
|
'PGR MUST NOT appliquer une règle globale « tout `gen/` est ignoré »',
|
||||||
|
'Les profils spécifiques utilisent la plage `710` à `799`.',
|
||||||
|
):
|
||||||
|
assert phrase in frameworks, phrase
|
||||||
|
|
||||||
|
tauri = Path('docs/rules/710-TAURI.md').read_text(encoding='utf-8')
|
||||||
|
for phrase in (
|
||||||
|
'# Profil Tauri 2',
|
||||||
|
'PGR MUST NOT imposer Vite, TypeScript, npm, pnpm, yarn, Bun, WASM',
|
||||||
|
"le CLI Tauri est l'owner de l'orchestration",
|
||||||
|
'VERSION
|
||||||
|
↓
|
||||||
|
workspace.package.version
|
||||||
|
↓
|
||||||
|
package Cargo du host
|
||||||
|
↓
|
||||||
|
version applicative Tauri',
|
||||||
|
'PGR MUST NOT appliquer en revanche une exclusion universelle de tout répertoire `gen/`',
|
||||||
|
'## Validation proportionnée',
|
||||||
|
'de `tauri.conf.json` universel',
|
||||||
|
):
|
||||||
|
assert phrase in tauri, phrase
|
||||||
|
|
||||||
|
study = Path('docs/studies/001-KSP_GAMES_RECONCILIATION.md').read_text(encoding='utf-8')
|
||||||
|
assert 'KSP contient `6` applications Desk Tauri et Games `2` hôtes Tauri' in study
|
||||||
|
assert 'Décision `alpha.6` : classer Tauri `COMMON`' in study
|
||||||
|
|
||||||
|
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
assert '`6` applications Tauri KSP et `2` applications Tauri Games' in plan
|
||||||
|
assert 'La tranche active `700-FRAMEWORKS.md` et `710-TAURI.md`.' in plan
|
||||||
|
|
||||||
|
print('0.0.5 alpha.6 Tauri profile audit: clean (700 activated, Tauri 2 responsibilities bounded, no frontend/layout overreach)')
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION RULES.md docs/000-README.md docs/architecture/003-RULE_PROFILE_MODEL.md docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md docs/rules/000-README.md docs/rules/700-FRAMEWORKS.md docs/rules/710-TAURI.md docs/studies/001-KSP_GAMES_RECONCILIATION.md deltas/0.0.5/alpha.6.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history `alpha.6` est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M RULES.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.6.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/architecture/003-RULE_PROFILE_MODEL.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/000-README.md
|
||||||
|
A docs/rules/700-FRAMEWORKS.md
|
||||||
|
A docs/rules/710-TAURI.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Créer/appliquer `history/0.0.5/alpha.6.md`, committer/pousser `0.0.5-alpha.6`, puis poursuivre à `0.0.5-alpha.7` pour décider si une skeleton specification Tauri apporte réellement une valeur de composition au-dessus des profils existants.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Rester dans `0.0.5-alpha.6.fix.M` ou REPLAN si le profil exige encore une valeur applicative arbitraire. Aucun skeleton Tauri ne doit être créé tant que le profil framework n'est pas correctement fermé.
|
||||||
186
deltas/0.0.5/alpha.7.fix.1.md
Normal file
186
deltas/0.0.5/alpha.7.fix.1.md
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.7.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.7.fix.1 — contrats de suffixes, packaging Rust et tracing
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.7`, réalisé après application de `history/0.0.5/alpha.7.md` avec statut `FAIL`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.7.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Motif
|
||||||
|
|
||||||
|
La gate mécanique de `alpha.7` est propre, mais la revue fonctionnelle opérateur révèle que la nomenclature livrée reste trop descriptive. Dans les projets contrôlés, les suffixes doivent également porter un contrat architectural : `-api` désigne une frontière de contrats réellement justifiée, `-lib` une implémentation/fonctionnalité réutilisable, tandis que les exécutables restent normalement des packages distincts et minces.
|
||||||
|
|
||||||
|
La relecture ciblée des corpus confirme plusieurs éléments réutilisables :
|
||||||
|
|
||||||
|
- KSP distingue explicitement `ksp-<domain>-api` et `ksp-<role>-lib`, interdit une crate `*-api` créée uniquement par symétrie et garde les APIs purement déclaratives sans logging runtime ;
|
||||||
|
- Games sépare explicitement la crate lib de jeu et ses launchers ;
|
||||||
|
- KSP et Games convergent sur `tracing`, la composition du subscriber et une crate transverse de logging ;
|
||||||
|
- les six hosts Tauri KSP et les deux hosts Tauri Games observés utilisent tous un package mixte lib/bin avec des noms de targets distincts.
|
||||||
|
|
||||||
|
Une ancienne règle KSP préférait un package worker mixte lib/bin. Cette préférence n'est pas généralisée : la décision PGR actuelle est la séparation par défaut, Tauri restant l'exception framework explicitement reconnue.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/510-RUST_CARGO.md
|
||||||
|
docs/rules/710-TAURI.md
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.7.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Décisions
|
||||||
|
|
||||||
|
Pour une nouvelle baseline Rust contrôlée :
|
||||||
|
|
||||||
|
- `-api` signifie contrat extensible/passif ; une crate `-api` n'est créée que si une séparation réelle est justifiée par extension, backend, lifecycle, implémentations multiples ou implémentation externe ;
|
||||||
|
- une crate `-api` purement déclarative reste normalement sans logging/tracing runtime ;
|
||||||
|
- lorsqu'une seule implémentation est utile et qu'aucune frontière séparée n'apporte de valeur, une seule crate `-lib` est préférée ;
|
||||||
|
- `-lib` signifie implémentation ou fonctionnalité réutilisable et ne contient normalement pas de cible binaire ;
|
||||||
|
- hors exception explicite de framework/plateforme, une bibliothèque réutilisable et son exécutable sont des packages Cargo distincts ;
|
||||||
|
- l'exécutable porte un rôle lisible lorsqu'il existe (`cli`, `desk`, `worker`, `job`, `server`, etc.), dépend des libs nécessaires et conserve `main.rs` comme couche de bootstrap/composition mince ;
|
||||||
|
- Tauri reste l'exception framework actuelle au package séparé lib/bin ; son profil impose alors des noms de targets réellement distincts, y compris après normalisation Cargo `-` -> `_`.
|
||||||
|
|
||||||
|
Pour les diagnostics :
|
||||||
|
|
||||||
|
- `tracing` est le mécanisme recommandé pour les nouveaux projets Rust contrôlés ;
|
||||||
|
- `log` reste acceptable comme bridge de compatibilité mais n'est pas la façade par défaut sans contrainte externe ;
|
||||||
|
- lorsqu'un workspace possède plusieurs runtimes partageant subscriber, filtres, sinks ou lifecycle, une crate transverse de logging/tracing SHOULD centraliser cette responsabilité ;
|
||||||
|
- `tracing-subscriber` et `tracing-appender` appartiennent normalement à cet owner de composition ;
|
||||||
|
- une bibliothèque métier/technique peut émettre des événements mais ne configure pas silencieusement le subscriber global.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
Ce correctif ne traite toujours pas l'ordre des blocs, le regroupement par visibilité, l'espacement interne, l'ordre alphabétique des items ou les audits de forme : ces sujets restent réservés à `alpha.8`.
|
||||||
|
|
||||||
|
Il ne crée aucun nouvel audit Python et ne transforme pas le profil Rust en catalogue exhaustif de suffixes. Les vocabulaires métier exacts restent locaux.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `FAIL` de `alpha.7`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.7.fix.1'
|
||||||
|
test -f history/0.0.5/alpha.7.md
|
||||||
|
test -f deltas/0.0.5/alpha.7.fix.1.md
|
||||||
|
test ! -e history/0.0.5/alpha.7.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.7.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '<!-- version: 6 -->' docs/rules/510-RUST_CARGO.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/710-TAURI.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 10 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.7.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+FAIL\s", history)
|
||||||
|
|
||||||
|
rules = Path("docs/rules/510-RUST_CARGO.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"### Les suffixes portent un contrat architectural",
|
||||||
|
"Une crate `-api` MUST NOT être créée uniquement pour obtenir une paire de noms symétrique.",
|
||||||
|
"Lorsqu'une seule implémentation est réellement prévue",
|
||||||
|
"### Séparation bibliothèques / exécutables",
|
||||||
|
"Tauri constitue l'exception framework actuellement reconnue par PGR",
|
||||||
|
"## Diagnostics structurés et ownership du logging",
|
||||||
|
"`tracing` est le mécanisme recommandé",
|
||||||
|
"SHOULD NOT installer silencieusement un subscriber global",
|
||||||
|
):
|
||||||
|
assert phrase in rules, phrase
|
||||||
|
|
||||||
|
tauri = Path("docs/rules/710-TAURI.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"le package mixte `lib + bin` constitue l'exception framework explicite",
|
||||||
|
"leurs noms MUST être distincts même après la normalisation Cargo usuelle des tirets en underscores",
|
||||||
|
"project_feature_desk_lib",
|
||||||
|
"Un plugin Tauri de tracing sert alors d'adapter",
|
||||||
|
):
|
||||||
|
assert phrase in tauri, phrase
|
||||||
|
|
||||||
|
skeleton = Path("docs/skeletons/002-RUST_CARGO_WORKSPACE.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"les frontières `-api` / `-lib` réellement justifiées",
|
||||||
|
"Les exécutables sont des packages distincts des bibliothèques",
|
||||||
|
"crate transverse de logging/tracing",
|
||||||
|
):
|
||||||
|
assert phrase in skeleton, phrase
|
||||||
|
|
||||||
|
template = Path("docs/templates/002-CARGO_MANIFESTS.md").read_text(encoding="utf-8")
|
||||||
|
assert "une bibliothèque réutilisable et son exécutable sont normalement deux packages Cargo distincts" in template
|
||||||
|
assert "Tauri est une exception framework" in template
|
||||||
|
|
||||||
|
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"#### Correction `alpha.7.fix.1` — suffixes, packaging et tracing",
|
||||||
|
"KSP-WORKER-014",
|
||||||
|
"les `6` hosts Tauri KSP `0.3.16` et les `2` hosts Tauri Games `0.3.5`",
|
||||||
|
"PGR retient donc `tracing` par défaut",
|
||||||
|
):
|
||||||
|
assert phrase in study, phrase
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
assert "`alpha.7.fix.1` complète donc la tranche" in plan
|
||||||
|
assert "### alpha.8 — formatage Rust structurel et audits monotâches" in plan
|
||||||
|
|
||||||
|
print("0.0.5 alpha.7.fix.1 crate contract audit: clean (api/lib semantics, binary split, tracing owner, Tauri exception)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/510-RUST_CARGO.md docs/rules/710-TAURI.md \
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
docs/templates/002-CARGO_MANIFESTS.md \
|
||||||
|
deltas/0.0.5/alpha.7.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.7.fix.1.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/510-RUST_CARGO.md
|
||||||
|
M docs/rules/710-TAURI.md
|
||||||
|
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
M docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
```
|
||||||
175
deltas/0.0.5/alpha.7.md
Normal file
175
deltas/0.0.5/alpha.7.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.7.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.7 — profil Rust strict, chemins et nomenclature explicite
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.6.fix.3`, réalisé après application de `history/0.0.5/alpha.6.fix.3.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.7
|
||||||
|
```
|
||||||
|
|
||||||
|
## Motif
|
||||||
|
|
||||||
|
La réconciliation Tauri a confirmé qu'un host contrôlé hérite du profil Rust au lieu de redéfinir ses conventions. La relecture des règles autoritaires KSP/Games révèle alors un écart PGR plus ancien : la conception initiale avait retenu un profil de forte explicité, mais `510-RUST_CARGO.md` matérialisé conservait encore une politique permissive sur les `use` non-traits et ne formalisait pas la nomenclature des crates.
|
||||||
|
|
||||||
|
KSP `RULES_RUST.md` version `10` fournit la référence stricte : Rust 2024, `use` réservé aux traits, chemins externes publics explicites et courts, réexports internes `self::`, façade crate-root, `crate::Item`, absence d'alias/globs et contrôle de flux explicite. Games `RULES_RUST.md` version `7` confirme le noyau Rust 2024/façade/erreurs mais reste plus léger sur certains imports et règles de forme. `alpha.7` retient donc le profil strict comme défaut des **nouvelles baselines contrôlées** tout en conservant des overrides explicites pour les projets externes ou historiques.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/510-RUST_CARGO.md
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.7.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Décisions
|
||||||
|
|
||||||
|
Pour une nouvelle baseline Rust contrôlée :
|
||||||
|
|
||||||
|
- Rust 2024 devient la baseline normative actuelle ; une contrainte externe doit être documentée explicitement ;
|
||||||
|
- `use` est réservé aux traits qui doivent réellement être mis en scope ; les autres symboles sont appelés par chemins explicites ;
|
||||||
|
- un symbole externe utilise le chemin public le plus court exposé par sa crate ;
|
||||||
|
- les réexports internes utilisent `self::`, restent explicites ligne par ligne et ne masquent pas les collisions par alias ;
|
||||||
|
- les glob imports, regroupements par accolades de façade et imports non-traits de commodité sont interdits ;
|
||||||
|
- les modules d'implémentation restent privés ; les items partagés passent par la façade crate-root et `crate::Item`, y compris dans leur module propriétaire ;
|
||||||
|
- `pub(super)`/`pub(in ...)` ne remplacent pas cette façade dans une baseline contrôlée ;
|
||||||
|
- tout `pub`/`pub(crate)` et tout réexport crate-root porte une rustdoc utile ;
|
||||||
|
- `unwrap`, `expect` et `?` sont interdits en production dans le profil strict ; la propagation d'erreur et les retours restent explicites.
|
||||||
|
|
||||||
|
Le marqueur historique KSP `rust-rules: trait-import` n'est pas généralisé : il appartient à l'enforcement local, pas à la règle sémantique.
|
||||||
|
|
||||||
|
Pour la nomenclature des crates d'un nouveau projet contrôlé :
|
||||||
|
|
||||||
|
```text
|
||||||
|
<project>-<responsibility>-<role-or-target>
|
||||||
|
```
|
||||||
|
|
||||||
|
est la forme recommandée. Le préfixe projet/abréviation est obligatoire ; le classificateur (`lib`, `api`, `worker`, `job`, `cli`, `desk`, `desktop`, `tauri`, `wasm`, `server`, etc.) est utilisé lorsqu'il apporte une information réelle. Le vocabulaire exact reste local, aucun suffixe n'est ajouté par symétrie et aucun projet historique n'est renommé rétroactivement uniquement pour adopter cette grammaire.
|
||||||
|
|
||||||
|
Le skeleton Rust/Cargo et le guide des manifests adoptent ces choix pour les futures baselines contrôlées. L'audit de façade déjà livré devient une sélection recommandée du skeleton strict ; l'adoption d'un projet existant commence toujours en `--report-only`.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
Cette tranche ne modifie pas les règles de blocs homogènes, ordre alphabétique, espacement, regroupement par visibilité ou organisation structurelle des items : elles restent réservées à `alpha.8` avec leurs audits monotâches.
|
||||||
|
|
||||||
|
Elle n'importe pas `audit_rust_general_rules.py` depuis KSP/Games, ne crée aucun parser Rust général et ne modifie pas le skeleton Tauri prévu en `alpha.9`.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.6.fix.3`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.7'
|
||||||
|
test -f history/0.0.5/alpha.6.fix.3.md
|
||||||
|
test -f deltas/0.0.5/alpha.7.md
|
||||||
|
test ! -e history/0.0.5/alpha.7.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.6.fix.3.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/510-RUST_CARGO.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
grep -Fx '<!-- version: 8 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.6.fix.3.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+PASS\s", history)
|
||||||
|
|
||||||
|
rules = Path("docs/rules/510-RUST_CARGO.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"nouveau projet Rust contrôlé MUST utiliser l'édition Rust 2024",
|
||||||
|
"### Nomenclature des crates dans un projet contrôlé",
|
||||||
|
"<project>-<responsibility>-<role-or-target>",
|
||||||
|
"### `use` réservé aux traits",
|
||||||
|
"le code utilise directement le **chemin public le plus court**",
|
||||||
|
"Les réexports d'éléments internes commencent par `self::`",
|
||||||
|
"toute référence dans la même crate MUST utiliser `crate::Item`",
|
||||||
|
"`unwrap()` et `expect()` MUST NOT être utilisés",
|
||||||
|
"l'opérateur `?` MUST NOT être utilisé",
|
||||||
|
):
|
||||||
|
assert phrase in rules, phrase
|
||||||
|
|
||||||
|
for forbidden in (
|
||||||
|
"PGR ne généralise pas l'interdiction KSP plus stricte de tous les `use` non-traits",
|
||||||
|
"le profil de façade crate-root est seulement facultatif pour une nouvelle baseline contrôlée",
|
||||||
|
):
|
||||||
|
assert forbidden not in rules, forbidden
|
||||||
|
|
||||||
|
skeleton = Path("docs/skeletons/002-RUST_CARGO_WORKSPACE.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"nom court/abréviation canonique du projet",
|
||||||
|
"édition Rust 2024",
|
||||||
|
"façade crate-root et les chemins explicites sont sélectionnés par défaut",
|
||||||
|
"audit_rust_export_completeness.py",
|
||||||
|
):
|
||||||
|
assert phrase in skeleton, phrase
|
||||||
|
|
||||||
|
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||||
|
assert "#### Décision `alpha.7` — profil Rust strict et nomenclature" in study
|
||||||
|
assert "KSP `RULES_RUST.md` version `10`" in study
|
||||||
|
assert "Games `RULES_RUST.md` version `7`" in study
|
||||||
|
assert "Les règles de blocs homogènes" in study
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
assert "La réconciliation des règles versionnées KSP/Games retient KSP comme référence stricte" in plan
|
||||||
|
assert "### alpha.8 — formatage Rust structurel et audits monotâches" in plan
|
||||||
|
assert "### alpha.9 — décision de skeleton Tauri pour projets contrôlés" in plan
|
||||||
|
|
||||||
|
print("0.0.5 alpha.7 strict Rust profile audit: clean (explicit paths, crate-root facade, controlled naming, alpha.8 formatting deferred)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/510-RUST_CARGO.md \
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
docs/templates/002-CARGO_MANIFESTS.md \
|
||||||
|
deltas/0.0.5/alpha.7.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.7.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/510-RUST_CARGO.md
|
||||||
|
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
M docs/templates/002-CARGO_MANIFESTS.md
|
||||||
|
```
|
||||||
248
deltas/0.0.5/alpha.8.md
Normal file
248
deltas/0.0.5/alpha.8.md
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.8.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.8 — formatage Rust structurel et audits monotâches
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.7.fix.1`, réalisé après application de `history/0.0.5/alpha.7.fix.1.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.8
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mission
|
||||||
|
|
||||||
|
Fermer le chantier de réconciliation du formatage Rust structurel sans importer les anciens `audit_rust_general_rules.py` composites de KSP/Games.
|
||||||
|
|
||||||
|
La tranche attribue chaque propriété à un owner identifiable : Rustfmt lorsqu'il sait réellement réécrire la forme, audits PGR monotâches lorsqu'une structure stable n'est pas possédée par l'outil officiel, et revue humaine lorsque l'ordre peut être métier/protocolaire.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/rules/510-RUST_CARGO.md
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
docs/validation/002-RUST_STYLE_AUDITS.md
|
||||||
|
tests/test_rust_audits.py
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.8.md
|
||||||
|
scripts/audit_rust_item_spacing.py
|
||||||
|
scripts/audit_rust_module_order.py
|
||||||
|
scripts/audit_rust_reexport_blocks.py
|
||||||
|
scripts/audit_rust_trait_import_blocks.py
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Décisions de formatage
|
||||||
|
|
||||||
|
Pour une nouvelle baseline Rust contrôlée sélectionnant le profil strict :
|
||||||
|
|
||||||
|
- les lignes vides consécutives et les lignes vides dans fonctions/méthodes/`struct`/`enum` sont interdites ;
|
||||||
|
- deux items Rust distincts voisins d'un même scope sont séparés par exactement une ligne vide lorsque rien d'intermédiaire ne possède lui-même l'espacement ;
|
||||||
|
- les blocs compacts `const` restent sous un owner séparé et ne sont pas interprétés par l'audit d'espacement général ;
|
||||||
|
- les modules de production précèdent les modules de tests et chaque groupe est alphabétique lorsque cet ordre est sans sémantique ;
|
||||||
|
- les `use` non exportés autorisés par le profil strict restent dans un bloc module-level compact avant les déclarations métier ;
|
||||||
|
- les `pub use` précèdent les `pub(crate) use`, sans ligne vide interne et avec exactement une ligne vide entre les deux visibilités lorsqu'elles coexistent ;
|
||||||
|
- Rustfmt reste l'owner du tri intra-bloc des `use`, réexports et modules qu'il sait réécrire ; les audits PGR ne créent pas un tri concurrent.
|
||||||
|
|
||||||
|
PGR conserve comme fortes conventions de lisibilité le rapprochement d'un `struct` et de ses `impl`, ainsi que la préférence des éléments visibles avant les helpers privés lorsque cela clarifie le fichier. Aucun audit lexical n'impose cependant un ordre global `enum → struct → impl → fn` ou un tri visible/privé susceptible d'écraser une organisation métier.
|
||||||
|
|
||||||
|
## Audits ajoutés
|
||||||
|
|
||||||
|
Quatre contrôles read-only monotâches sont extraits :
|
||||||
|
|
||||||
|
```text
|
||||||
|
audit_rust_item_spacing.py
|
||||||
|
séparation exacte des items distincts voisins
|
||||||
|
|
||||||
|
audit_rust_module_order.py
|
||||||
|
ordre production/tests et ordre alphabétique des modules
|
||||||
|
|
||||||
|
audit_rust_trait_import_blocks.py
|
||||||
|
placement/contiguïté des use non exportés
|
||||||
|
|
||||||
|
audit_rust_reexport_blocks.py
|
||||||
|
ordre de visibilité et espacement des blocs de réexports
|
||||||
|
```
|
||||||
|
|
||||||
|
Ils utilisent `_rust_audit_common.py` pour la sélection et le masquage lexical. Ils ne tentent pas de remplacer un parser Rust ni de déterminer la nature sémantique d'un import.
|
||||||
|
|
||||||
|
Les audits déjà existants gardent leurs responsabilités :
|
||||||
|
|
||||||
|
```text
|
||||||
|
audit_rust_blank_lines.py
|
||||||
|
blancs consécutifs / blancs dans certains corps
|
||||||
|
|
||||||
|
audit_rust_const_blocks.py
|
||||||
|
consts sélectionnées : visibilité, ordre, espacement
|
||||||
|
|
||||||
|
audit_rust_export_completeness.py
|
||||||
|
façade crate-root et chemins canoniques
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mesure croisée
|
||||||
|
|
||||||
|
Les quatre nouveaux audits ont été exécutés pendant la préparation sur tous les fichiers Rust sous `crates/` des baselines autoritaires :
|
||||||
|
|
||||||
|
```text
|
||||||
|
KSP 0.3.16 603 file(s) item/module/trait-import/reexport: clean
|
||||||
|
Games 0.3.5 87 file(s) item/module/trait-import/reexport: clean
|
||||||
|
```
|
||||||
|
|
||||||
|
`audit_rust_blank_lines.py` est également propre sur ces `603` et `87` fichiers.
|
||||||
|
|
||||||
|
En revanche, `audit_rust_const_blocks.py` exécuté aveuglément sur l'ensemble produit `18` signaux KSP et `0` Games. Certains signaux correspondent à des tables/schémas à ordre intentionnel. Il reste donc un audit à sélection explicite par fichier et ne devient pas une gate globale.
|
||||||
|
|
||||||
|
Ces mesures servent à qualifier la réutilisabilité des règles PGR ; elles ne constituent pas une validation opérateur de KSP/Games.
|
||||||
|
|
||||||
|
## Horizon documenté sans engagement
|
||||||
|
|
||||||
|
La revue d'horizon du plan conserve `0.1.0` comme seule prochaine release engagée, mais mémorise trois candidats sans numéro ni engagement :
|
||||||
|
|
||||||
|
1. profils techniques composables par langage/framework/target/plateforme et préoccupation transverse, notamment observability/logging ;
|
||||||
|
2. profil documentaire/spécification, avec `saselang-bible` comme corpus pilote possible ;
|
||||||
|
3. audit de généricité de PGR pour des projets hors développement logiciel.
|
||||||
|
|
||||||
|
Ces candidats ne deviennent ni `Study`, ni `ROADMAP`, ni release plan tant qu'une décision explicite ne les promeut pas.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
Cette tranche ne :
|
||||||
|
|
||||||
|
- crée pas de parser Rust général ;
|
||||||
|
- réimporte pas `audit_rust_general_rules.py` ;
|
||||||
|
- impose pas un ordre alphabétique à une séquence sémantique ;
|
||||||
|
- crée pas d'audit dédié `static/type` uniquement pour la symétrie ;
|
||||||
|
- modifie pas les contrats de suffixes/packaging/tracing fermés par `alpha.7.fix.1` ;
|
||||||
|
- commence pas le skeleton Tauri réservé à `alpha.9` ;
|
||||||
|
- transforme pas les candidats d'horizon en versions promises.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.7.fix.1`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.8'
|
||||||
|
test -f history/0.0.5/alpha.7.fix.1.md
|
||||||
|
test -f deltas/0.0.5/alpha.8.md
|
||||||
|
test -f scripts/audit_rust_item_spacing.py
|
||||||
|
test -f scripts/audit_rust_module_order.py
|
||||||
|
test -f scripts/audit_rust_reexport_blocks.py
|
||||||
|
test -f scripts/audit_rust_trait_import_blocks.py
|
||||||
|
test ! -e scripts/audit_rust_general_rules.py
|
||||||
|
test ! -e history/0.0.5/alpha.8.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.7.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 7 -->' docs/rules/510-RUST_CARGO.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
grep -Fx '<!-- version: 10 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 12 -->' docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/validation/002-RUST_STYLE_AUDITS.md
|
||||||
|
grep -Fx '<!-- version: 11 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -Fx '# version: 2' tests/test_rust_audits.py
|
||||||
|
grep -Fx '# version: 1' scripts/audit_rust_item_spacing.py
|
||||||
|
grep -Fx '# version: 1' scripts/audit_rust_module_order.py
|
||||||
|
grep -Fx '# version: 1' scripts/audit_rust_reexport_blocks.py
|
||||||
|
grep -Fx '# version: 1' scripts/audit_rust_trait_import_blocks.py
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -p 'test_rust_audits.py' -v
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.7.fix.1.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+PASS\s", history)
|
||||||
|
|
||||||
|
rules = Path("docs/rules/510-RUST_CARGO.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"Le profil structurel strict fait partie du défaut des nouvelles baselines Rust contrôlées.",
|
||||||
|
"audit_rust_item_spacing.py",
|
||||||
|
"audit_rust_module_order.py",
|
||||||
|
"audit_rust_trait_import_blocks.py",
|
||||||
|
"audit_rust_reexport_blocks.py",
|
||||||
|
"PGR n'impose toutefois pas un ordre global automatique `enum → struct → impl → fn`",
|
||||||
|
):
|
||||||
|
assert phrase in rules, phrase
|
||||||
|
|
||||||
|
validation = Path("docs/validation/002-RUST_STYLE_AUDITS.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"603` fichiers KSP `0.3.16`",
|
||||||
|
"87` fichiers Games `0.3.5`",
|
||||||
|
"18` signaux KSP",
|
||||||
|
"0` Games",
|
||||||
|
"Rustfmt reste l'owner de l'ordre intra-bloc",
|
||||||
|
):
|
||||||
|
assert phrase in validation, phrase
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"quatre extractions monotâches complètent le profil",
|
||||||
|
"maturation de profils techniques composables",
|
||||||
|
"`saselang-bible` comme corpus pilote possible",
|
||||||
|
"audit du noyau PGR hors développement logiciel",
|
||||||
|
"### alpha.9 — décision de skeleton Tauri pour projets contrôlés",
|
||||||
|
):
|
||||||
|
assert phrase in plan, phrase
|
||||||
|
|
||||||
|
print("0.0.5 alpha.8 Rust structure audit: clean (owners split, four monotask audits, semantic order protected, horizon candidates recorded)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/rules/510-RUST_CARGO.md \
|
||||||
|
docs/skeletons/002-RUST_CARGO_WORKSPACE.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
docs/validation/001-VALIDATION_MATRIX.md \
|
||||||
|
docs/validation/002-RUST_STYLE_AUDITS.md \
|
||||||
|
scripts/audit_rust_item_spacing.py \
|
||||||
|
scripts/audit_rust_module_order.py \
|
||||||
|
scripts/audit_rust_reexport_blocks.py \
|
||||||
|
scripts/audit_rust_trait_import_blocks.py \
|
||||||
|
tests/test_rust_audits.py \
|
||||||
|
deltas/0.0.5/alpha.8.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.8.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/rules/510-RUST_CARGO.md
|
||||||
|
M docs/skeletons/002-RUST_CARGO_WORKSPACE.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
M docs/validation/001-VALIDATION_MATRIX.md
|
||||||
|
M docs/validation/002-RUST_STYLE_AUDITS.md
|
||||||
|
A scripts/audit_rust_item_spacing.py
|
||||||
|
A scripts/audit_rust_module_order.py
|
||||||
|
A scripts/audit_rust_reexport_blocks.py
|
||||||
|
A scripts/audit_rust_trait_import_blocks.py
|
||||||
|
M tests/test_rust_audits.py
|
||||||
|
```
|
||||||
178
deltas/0.0.5/alpha.9.md
Normal file
178
deltas/0.0.5/alpha.9.md
Normal file
@@ -0,0 +1,178 @@
|
|||||||
|
<!-- file: deltas/0.0.5/alpha.9.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-alpha.9 — décision de skeleton Tauri contrôlé
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline attendue : commit opérateur complet de `0.0.5-alpha.8`, réalisé après application de `history/0.0.5/alpha.8.md` avec statut `PASS`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.9
|
||||||
|
```
|
||||||
|
|
||||||
|
## Mission
|
||||||
|
|
||||||
|
Décider si les owners PGR réellement matérialisés permettent de créer un skeleton Tauri actionnable pour les projets contrôlés sans transformer ce skeleton en propriétaire implicite de règles Web encore absentes.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
docs/skeletons/000-README.md
|
||||||
|
docs/studies/000-README.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/alpha.9.md
|
||||||
|
docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Aucun fichier `docs/skeletons/003-TAURI*.md` n'est créé.
|
||||||
|
|
||||||
|
## Décision
|
||||||
|
|
||||||
|
Résultat :
|
||||||
|
|
||||||
|
```text
|
||||||
|
DEFER
|
||||||
|
```
|
||||||
|
|
||||||
|
Le host Tauri est suffisamment cadré par les owners existants : Rust/Cargo, Tauri, plateformes applicables et règles générales de skeleton. La partie frontend candidate ne l'est pas encore : PGR ne possède aucun profil Web/Vite/TypeScript/Sass.
|
||||||
|
|
||||||
|
Créer maintenant le skeleton obligerait donc sa specification à posséder de fait la structure et la validation Web, alors qu'un skeleton doit composer des owners et non compenser leur absence.
|
||||||
|
|
||||||
|
## Candidat conservé
|
||||||
|
|
||||||
|
La décision ne rejette pas le skeleton organisationnel. Elle conserve comme hypothèse à réévaluer lorsque les owners Web existeront :
|
||||||
|
|
||||||
|
```text
|
||||||
|
host Cargo direct
|
||||||
|
+ frontend/
|
||||||
|
+ Vite
|
||||||
|
+ TypeScript
|
||||||
|
+ Sass
|
||||||
|
+ Bootstrap lorsque pertinent
|
||||||
|
+ TS-RS pour les DTO Rust partagés
|
||||||
|
+ tauri.rs comme owner Tauri
|
||||||
|
+ plugins/capabilities explicitement intégrés
|
||||||
|
+ WASM séparé par défaut
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucune de ces lignes ne crée dans `0.0.5` un owner Web qui n'existe pas encore.
|
||||||
|
|
||||||
|
## Sources et vérification
|
||||||
|
|
||||||
|
La décision repose d'abord sur les baselines KSP `0.3.16` et Games `0.3.5` déjà autoritaires pour la réconciliation. La préparation a également vérifié la documentation Tauri 2 courante concernant la flexibilité du frontend, le scaffold `src-tauri/`, l'initialisation manuelle et l'installation explicite des plugins/capabilities.
|
||||||
|
|
||||||
|
L'étude détaillée est `docs/studies/002-TAURI_SKELETON_DECISION.md`.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
Cette tranche ne :
|
||||||
|
|
||||||
|
- crée pas un skeleton décoratif ;
|
||||||
|
- matérialise pas les futurs profils Web ;
|
||||||
|
- modifie pas `710-TAURI.md` ;
|
||||||
|
- choisit pas un package manager universel ;
|
||||||
|
- modifie pas les règles Rust fermées par `alpha.7/alpha.8` ;
|
||||||
|
- réserve pas une release pour le futur skeleton.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.8`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-alpha.9'
|
||||||
|
test -f history/0.0.5/alpha.8.md
|
||||||
|
test -f deltas/0.0.5/alpha.9.md
|
||||||
|
test -f docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||||
|
test ! -e docs/skeletons/003-TAURI.md
|
||||||
|
test ! -e docs/skeletons/003-TAURI_CONTROLLED_PROJECT.md
|
||||||
|
test ! -e history/0.0.5/alpha.9.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.8.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 15 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 12 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/skeletons/000-README.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/studies/000-README.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.8.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+PASS\s", history)
|
||||||
|
|
||||||
|
study = Path("docs/studies/002-TAURI_SKELETON_DECISION.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"Décision `alpha.9` :",
|
||||||
|
"DEFER",
|
||||||
|
"Aucun des `8` hosts n'utilise `src-tauri/`.",
|
||||||
|
"PGR `0.0.5` **ne crée pas** de skeleton Tauri `003`.",
|
||||||
|
"PGR `0.0.5` ne possède aucun profil Web dédié",
|
||||||
|
"001-PROJECT_GOVERNANCE_FOUNDATION",
|
||||||
|
"002-RUST_CARGO_WORKSPACE",
|
||||||
|
"Bootstrap comme baseline de présentation lorsqu'un framework CSS généraliste est utile",
|
||||||
|
):
|
||||||
|
assert phrase in study, phrase
|
||||||
|
|
||||||
|
index = Path("docs/skeletons/000-README.md").read_text(encoding="utf-8")
|
||||||
|
assert "Aucun `003-TAURI...` n'est donc créé dans `0.0.5`." in index
|
||||||
|
assert "profils Web réellement matérialisés" in index
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
assert "### alpha.9 — décision de skeleton Tauri pour projets contrôlés — DEFER" in plan
|
||||||
|
assert "aucun skeleton Tauri `003` n'est créé dans `0.0.5`" in plan
|
||||||
|
assert "### beta.1 — réconciliation intégrée" in plan
|
||||||
|
|
||||||
|
assert not any(Path("docs/skeletons").glob("003-TAURI*.md"))
|
||||||
|
|
||||||
|
print("0.0.5 alpha.9 Tauri skeleton decision: clean (host ready, Web owners missing, decorative skeleton rejected, exit conditions recorded)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION \
|
||||||
|
docs/000-README.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/skeletons/000-README.md \
|
||||||
|
docs/studies/000-README.md \
|
||||||
|
docs/studies/002-TAURI_SKELETON_DECISION.md \
|
||||||
|
deltas/0.0.5/alpha.9.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/alpha.9.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/skeletons/000-README.md
|
||||||
|
M docs/studies/000-README.md
|
||||||
|
A docs/studies/002-TAURI_SKELETON_DECISION.md
|
||||||
|
```
|
||||||
208
deltas/0.0.5/beta.1.md
Normal file
208
deltas/0.0.5/beta.1.md
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
<!-- file: deltas/0.0.5/beta.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-beta.1 — réconciliation intégrée et transition vers 0.1.0
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
Version attendue avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-alpha.9
|
||||||
|
```
|
||||||
|
|
||||||
|
Le history `history/0.0.5/alpha.9.md` avec statut `PASS` MUST avoir été appliqué, committé et poussé avant ce delta.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-beta.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Fermer la phase alpha de `0.0.5` par une réconciliation intégrée des décisions réellement matérialisées, puis préparer la transition vers la première baseline réutilisable `0.1.0` sans inventer d'owners, de skeletons ou de releases futures.
|
||||||
|
|
||||||
|
Cette tranche :
|
||||||
|
|
||||||
|
- rejoue la classification KSP/Games sur l'état PGR obtenu ;
|
||||||
|
- vérifie que chaque responsabilité nouvelle possède un owner identifiable et que les conventions locales non généralisées restent hors du noyau ;
|
||||||
|
- inscrit durablement le skeleton Tauri contrôlé comme trajectoire `DEFER` dans `ROADMAP.md`, sans numéro de release réservé ;
|
||||||
|
- maintient les trois autres axes discutés pendant `alpha.8` au stade de candidats d'horizon, hors roadmap engagée ;
|
||||||
|
- réconcilie les points d'entrée durables ;
|
||||||
|
- prépare `prompts/006-V0_1_0_START_PROMPT.md` puisque la mission `0.1.0` est suffisamment connue.
|
||||||
|
|
||||||
|
## Décision de roadmap
|
||||||
|
|
||||||
|
La décision `alpha.9` a déjà établi qu'un skeleton Tauri complet ne peut pas être matérialisé proprement avant l'existence d'owners Web suffisants. Ce report est plus qu'une idée : il résulte d'une étude et possède des conditions de sortie explicites.
|
||||||
|
|
||||||
|
`ROADMAP.md` enregistre donc :
|
||||||
|
|
||||||
|
```text
|
||||||
|
(d) skeleton Tauri pour projets contrôlés
|
||||||
|
```
|
||||||
|
|
||||||
|
sans associer cette trajectoire à `0.1.1`, `0.2.0` ou une autre release hypothétique.
|
||||||
|
|
||||||
|
Les axes suivants restent en revanche hors roadmap tant qu'une revue d'horizon ne les engage pas :
|
||||||
|
|
||||||
|
- maturation plus large des profils techniques composables ;
|
||||||
|
- projet documentaire/spécification avec `saselang-bible` comme corpus pilote possible ;
|
||||||
|
- audit de généricité de PGR hors développement logiciel.
|
||||||
|
|
||||||
|
Cette distinction applique directement `300-DOCUMENTATION.md` : une décision de report réelle peut être conservée comme trajectoire différée, tandis qu'un candidat d'horizon ne devient pas automatiquement un engagement macro.
|
||||||
|
|
||||||
|
## Réconciliation intégrée
|
||||||
|
|
||||||
|
L'étude `001-KSP_GAMES_RECONCILIATION.md` reçoit une matrice de sortie `beta.1` qui confirme notamment :
|
||||||
|
|
||||||
|
```text
|
||||||
|
prompt versionné OWNED
|
||||||
|
contrats de fichiers/familles OWNED
|
||||||
|
lifecycle inter-release / horizon OWNED
|
||||||
|
profil Rust contrôlé OWNED
|
||||||
|
audits Rust monotâches OWNED
|
||||||
|
profil Tauri 2 OWNED
|
||||||
|
skeleton Tauri complet DEFER
|
||||||
|
Web/Vite/TypeScript/Sass DEFER
|
||||||
|
Android/JNI spécifique LOCAL/DEFER
|
||||||
|
architectures métier KSP/Games LOCAL
|
||||||
|
```
|
||||||
|
|
||||||
|
La présence d'un owner PGR n'impose pas sa sélection à tous les projets. Applicabilité, composition et overrides restent gouvernés par le modèle de profils.
|
||||||
|
|
||||||
|
## Prompt 006
|
||||||
|
|
||||||
|
`prompts/006-V0_1_0_START_PROMPT.md` prépare la reprise après publication réelle de `v0.0.5`.
|
||||||
|
|
||||||
|
Il fixe uniquement ce qui est déjà décidé :
|
||||||
|
|
||||||
|
- baseline autoritaire `pgr-v0.0.5.zip` et rapport post-tag séparé lorsqu'il existe et est `PASS` ;
|
||||||
|
- cible `0.1.0`, première tranche `0.1.0-alpha.1` ;
|
||||||
|
- audit complet de la stable avant extension ;
|
||||||
|
- mission de première baseline réellement réutilisable ;
|
||||||
|
- nécessité de produire/consolider le plan `0.1.0` pendant `alpha.1` ;
|
||||||
|
- revue d'horizon obligatoire avant fermeture ;
|
||||||
|
- skeleton Tauri conservé `DEFER` tant que ses préconditions ne sont pas réellement satisfaites.
|
||||||
|
|
||||||
|
Le prompt MUST NOT être interprété comme un plan détaillé de `0.1.0` ni comme une promesse de matérialiser tous les candidats d'horizon.
|
||||||
|
|
||||||
|
## Documentation durable
|
||||||
|
|
||||||
|
`README.md` résume désormais les capacités réellement apportées par `0.0.5` sans recopier le plan de release.
|
||||||
|
|
||||||
|
`docs/000-README.md` expose les deux contrats de validation Rust et le prompt de reprise candidat `006`.
|
||||||
|
|
||||||
|
Le plan `005` enregistre le résultat de la réconciliation intégrée et conserve les responsabilités `rc.1`, stable et `publish.001` déjà attribuées.
|
||||||
|
|
||||||
|
## Hors scope
|
||||||
|
|
||||||
|
Cette tranche ne :
|
||||||
|
|
||||||
|
- crée pas de skeleton Tauri `003` ;
|
||||||
|
- crée pas de profil Web placeholder ;
|
||||||
|
- attribue pas de release au travail Tauri différé ;
|
||||||
|
- ajoute pas les trois candidats d'horizon à la roadmap engagée ;
|
||||||
|
- modifie pas `CHANGELOG.md`, réservé à la préparation RC puis à la stable ;
|
||||||
|
- migre pas KSP ou Games ;
|
||||||
|
- change pas les règles Rust/Tauri fermées pendant les alphas.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Après application du history `PASS` de `alpha.9`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-beta.1'
|
||||||
|
test -f history/0.0.5/alpha.9.md
|
||||||
|
test -f deltas/0.0.5/beta.1.md
|
||||||
|
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
test ! -e history/0.0.5/beta.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/alpha.9.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 13 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 7 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 16 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 13 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -Fx '<!-- version: 11 -->' docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PY'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
history = Path("history/0.0.5/alpha.9.md").read_text(encoding="utf-8")
|
||||||
|
assert re.search(r"## Statut\s+PASS\s", history)
|
||||||
|
|
||||||
|
roadmap = Path("ROADMAP.md").read_text(encoding="utf-8")
|
||||||
|
assert "(d) skeleton Tauri pour projets contrôlés" in roadmap
|
||||||
|
assert "Aucun numéro de release n'est réservé pour ce travail" in roadmap
|
||||||
|
assert "saselang-bible" not in roadmap
|
||||||
|
|
||||||
|
study = Path("docs/studies/001-KSP_GAMES_RECONCILIATION.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"## Réconciliation intégrée `beta.1`",
|
||||||
|
"skeleton Tauri contrôlé complet",
|
||||||
|
"`DEFER`",
|
||||||
|
"repris dans `ROADMAP.md` sans numéro de release",
|
||||||
|
"Les trois axes plus larges identifiés pendant `alpha.8` restent des **candidats d'horizon**",
|
||||||
|
):
|
||||||
|
assert phrase in study, phrase
|
||||||
|
|
||||||
|
plan = Path("docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"Le `DEFER` du skeleton Tauri contrôlé est suffisamment décidé",
|
||||||
|
"`prompts/006-V0_1_0_START_PROMPT.md` est préparé",
|
||||||
|
"il ne transforme pas le skeleton Tauri différé en obligation de `0.1.0`",
|
||||||
|
):
|
||||||
|
assert phrase in plan, phrase
|
||||||
|
|
||||||
|
prompt = Path("prompts/006-V0_1_0_START_PROMPT.md").read_text(encoding="utf-8")
|
||||||
|
for phrase in (
|
||||||
|
"# Prompt de démarrage 0.1.0 — première baseline réutilisable",
|
||||||
|
"pgr-v0.0.5.zip",
|
||||||
|
"pgr-0.0.5-publish.001-report.md",
|
||||||
|
"Version cible : `0.1.0`. Première tranche attendue : `0.1.0-alpha.1`.",
|
||||||
|
"Le skeleton Tauri contrôlé reste `DEFER`",
|
||||||
|
"Le plan `0.1.0` MUST programmer une revue d'horizon avant la clôture stable.",
|
||||||
|
):
|
||||||
|
assert phrase in prompt, phrase
|
||||||
|
|
||||||
|
assert not any(Path("docs/skeletons").glob("003-TAURI*.md"))
|
||||||
|
|
||||||
|
print("0.0.5 beta.1 integrated reconciliation: clean (owners reconciled, Tauri defer roadmapped, horizon candidates remain uncommitted, prompt 006 prepared)")
|
||||||
|
PY
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION README.md ROADMAP.md \
|
||||||
|
docs/000-README.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
docs/studies/001-KSP_GAMES_RECONCILIATION.md \
|
||||||
|
prompts/006-V0_1_0_START_PROMPT.md \
|
||||||
|
deltas/0.0.5/beta.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
La sortie Git attendue avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M ROADMAP.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/beta.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
M docs/studies/001-KSP_GAMES_RECONCILIATION.md
|
||||||
|
A prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
```
|
||||||
190
deltas/0.0.5/rc.1.md
Normal file
190
deltas/0.0.5/rc.1.md
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
<!-- file: deltas/0.0.5/rc.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5-rc.1 — gel du scope et préparation de release
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : `0.0.5-beta.1`, avec `history/0.0.5/beta.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||||
|
|
||||||
|
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history beta ; il n'est pas anticipé dans cette livraison simultanée du history et du delta suivant.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-beta.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-rc.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet et gel
|
||||||
|
|
||||||
|
La réconciliation `beta.1` est `PASS`. La RC gèle le scope fonctionnel de `0.0.5` sur :
|
||||||
|
|
||||||
|
- les prompts versionnés, contrats documentaires facultatifs et responsabilités de lifecycle/revue d'horizon ;
|
||||||
|
- le profil Rust strict des projets contrôlés, ses contrats de nomenclature/packaging/tracing et ses audits monotâches ;
|
||||||
|
- l'audit de complétude de façade et l'usage canonique `crate::Item` ;
|
||||||
|
- les profils framework et Tauri 2, leurs frontières Rust/frontend, TS-RS, plugins/capabilities, politique de versions produit et exception encadrée `lib + bin` ;
|
||||||
|
- la décision explicite `DEFER` du skeleton Tauri contrôlé jusqu'à matérialisation d'owners Web suffisants ;
|
||||||
|
- la réconciliation KSP/Games et le prompt candidat `006` vers `0.1.0`.
|
||||||
|
|
||||||
|
Le changelog reçoit une entrée candidate `0.0.5` orientée utilisateurs. `ROADMAP.md` est vérifié mais reste inchangé : `0.0.5` n'est marqué terminé qu'à la promotion stable ; `0.1.0` reste la prochaine release engagée ; le skeleton Tauri reste différé sans numéro réservé. Le prompt `006` est vérifié sans être réécrit si son contrat est déjà correct.
|
||||||
|
|
||||||
|
Aucun nouvel owner, profil Web, skeleton, template, audit, règle fonctionnelle ou version postérieure à `0.1.0` n'entre en RC.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/rc.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive contient exactement ces fichiers complets. Le history `beta.1` est livré séparément ; le history `rc.1` sera produit après la gate opérateur.
|
||||||
|
|
||||||
|
## Gate opérateur de release candidate
|
||||||
|
|
||||||
|
Après application du history `PASS` de `beta.1`, commit/push de cette tranche, puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5-rc.1'
|
||||||
|
git cat-file -e HEAD:history/0.0.5/beta.1.md
|
||||||
|
test -f history/0.0.5/beta.1.md
|
||||||
|
test -f deltas/0.0.5/rc.1.md
|
||||||
|
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
test ! -e history/0.0.5/rc.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/beta.1.md | grep -Fx 'PASS'
|
||||||
|
grep -Fx '<!-- version: 8 -->' CHANGELOG.md
|
||||||
|
grep -Fx '## 0.0.5 (candidate)' CHANGELOG.md
|
||||||
|
grep -Fx '<!-- version: 14 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -Fx '<!-- version: 7 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
grep -F 'La gate opérateur de `beta.1` est `PASS`' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -F '(d) skeleton Tauri pour projets contrôlés' ROADMAP.md
|
||||||
|
grep -F 'Le skeleton Tauri contrôlé reste `DEFER`' prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
python3 -B - <<'PYGATE'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'FAIL',
|
||||||
|
'alpha.3.fix.1.md': 'PASS',
|
||||||
|
'alpha.4.md': 'PASS',
|
||||||
|
'alpha.5.md': 'FAIL',
|
||||||
|
'alpha.5.fix.1.md': 'PASS',
|
||||||
|
'alpha.6.md': 'FAIL',
|
||||||
|
'alpha.6.fix.1.md': 'FAIL',
|
||||||
|
'alpha.6.fix.2.md': 'FAIL',
|
||||||
|
'alpha.6.fix.3.md': 'PASS',
|
||||||
|
'alpha.7.md': 'FAIL',
|
||||||
|
'alpha.7.fix.1.md': 'PASS',
|
||||||
|
'alpha.8.md': 'PASS',
|
||||||
|
'alpha.9.md': 'PASS',
|
||||||
|
'beta.1.md': 'PASS',
|
||||||
|
}
|
||||||
|
histories = {path.name for path in Path('history/0.0.5').glob('*.md')}
|
||||||
|
assert histories == set(expected), histories
|
||||||
|
for name, status in expected.items():
|
||||||
|
text = Path('history/0.0.5', name).read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
deltas = {path.name for path in Path('deltas/0.0.5').glob('*.md')}
|
||||||
|
assert deltas == set(expected) | {'rc.1.md'}, deltas
|
||||||
|
|
||||||
|
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
|
||||||
|
assert '## 0.0.5 (candidate)' in changelog
|
||||||
|
for forbidden in ('alpha.6.fix.3', 'alpha.7.fix.1', 'beta.1'):
|
||||||
|
assert forbidden not in changelog, forbidden
|
||||||
|
|
||||||
|
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||||
|
assert '- `( ) 0.0.5`' in roadmap
|
||||||
|
assert '- `( ) 0.1.0`' in roadmap
|
||||||
|
assert '(d) skeleton Tauri pour projets contrôlés' in roadmap
|
||||||
|
assert 'saselang-bible' not in roadmap
|
||||||
|
|
||||||
|
prompt = Path('prompts/006-V0_1_0_START_PROMPT.md').read_text(encoding='utf-8')
|
||||||
|
for value in (
|
||||||
|
'pgr-v0.0.5.zip',
|
||||||
|
'pgr-0.0.5-publish.001-report.md',
|
||||||
|
'0.1.0-alpha.1',
|
||||||
|
'Le skeleton Tauri contrôlé reste `DEFER`',
|
||||||
|
"revue d'horizon avant la clôture stable",
|
||||||
|
):
|
||||||
|
assert value in prompt, value
|
||||||
|
|
||||||
|
for path in (
|
||||||
|
'scripts/audit_rust_item_spacing.py',
|
||||||
|
'scripts/audit_rust_module_order.py',
|
||||||
|
'scripts/audit_rust_reexport_blocks.py',
|
||||||
|
'scripts/audit_rust_trait_import_blocks.py',
|
||||||
|
'scripts/audit_rust_export_completeness.py',
|
||||||
|
):
|
||||||
|
assert Path(path).is_file(), path
|
||||||
|
|
||||||
|
assert Path('docs/rules/710-TAURI.md').is_file()
|
||||||
|
assert not any(Path('docs/skeletons').glob('003-TAURI*.md'))
|
||||||
|
|
||||||
|
print('0.0.5 rc.1 integration audit: clean (16 prior histories, frozen scope, candidate changelog, roadmap/prompt 006 verified)')
|
||||||
|
PYGATE
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add VERSION CHANGELOG.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
deltas/0.0.5/rc.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope attendu avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M CHANGELOG.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/rc.1.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que le changelog décrit les capacités de la release plutôt que ses tranches internes, que le `DEFER` Tauri reste visible sans numéro de release, que les trois autres candidats d'horizon ne sont pas promus en roadmap, que le prompt `006` ne présume aucune publication post-tag et que la RC n'étend pas le périmètre fonctionnel.
|
||||||
|
|
||||||
|
Une gate RC `PASS` n'est ni la promotion stable, ni le tag `v0.0.5`, ni la vérification de l'archive publiée après le tag.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire séparément `history/0.0.5/rc.1.md`, l'appliquer puis committer/pousser la RC avant le delta stable `rel.001`.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner l'échec réel dans `history/0.0.5/rc.1.md` et corriger uniquement le scope gelé dans `rc.1.fix.1`, sauf REPLAN explicite si la candidate révèle un défaut fonctionnel plus large.
|
||||||
170
deltas/0.0.5/rel.001.fix.1.md
Normal file
170
deltas/0.0.5/rel.001.fix.1.md
Normal file
@@ -0,0 +1,170 @@
|
|||||||
|
<!-- file: deltas/0.0.5/rel.001.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5 rel.001.fix.1 — correction de la gate stable pré-tag
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : état stable `0.0.5` issu de `rel.001`, avec `history/0.0.5/rel.001.md` appliqué et committé en `FAIL`.
|
||||||
|
|
||||||
|
`VERSION` reste :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5
|
||||||
|
```
|
||||||
|
|
||||||
|
Ce correctif est strictement documentaire et opérationnel. Il ne change ni la version produit, ni le scope fonctionnel validé par `rc.1`, ni les fichiers de présentation stable déjà promus par `rel.001`.
|
||||||
|
|
||||||
|
## Diagnostic corrigé
|
||||||
|
|
||||||
|
La gate `rel.001` devait confirmer la présence exacte du heading stable `## 0.0.5` dans `CHANGELOG.md`. Le delta livré a généré une chaîne Python simple contenant un retour à la ligne physique :
|
||||||
|
|
||||||
|
```python
|
||||||
|
assert '## 0.0.5
|
||||||
|
' in changelog
|
||||||
|
```
|
||||||
|
|
||||||
|
Le heredoc est donc invalide et produit `SyntaxError: unterminated string literal` avant la preuve attendue.
|
||||||
|
|
||||||
|
`rel.001.fix.1` remplace cette forme fragile par une vérification ligne par ligne :
|
||||||
|
|
||||||
|
```python
|
||||||
|
assert '## 0.0.5' in changelog.splitlines()
|
||||||
|
```
|
||||||
|
|
||||||
|
Le delta historique `rel.001.md` reste immuable.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/rel.001.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Aucun fichier `VERSION`, `README`, `ROADMAP`, `CHANGELOG`, règle, script, test, template ou skeleton n'est modifié par ce correctif.
|
||||||
|
|
||||||
|
## Validation opérateur pré-tag
|
||||||
|
|
||||||
|
Après application sur le commit qui contient le history `FAIL` de `rel.001` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5'
|
||||||
|
git cat-file -e HEAD:history/0.0.5/rel.001.md
|
||||||
|
test -f history/0.0.5/rel.001.md
|
||||||
|
test -f deltas/0.0.5/rel.001.fix.1.md
|
||||||
|
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
test ! -e history/0.0.5/rel.001.fix.1.md
|
||||||
|
|
||||||
|
grep -A2 '^## Statut$' history/0.0.5/rel.001.md | grep -Fx 'FAIL'
|
||||||
|
grep -Fx '<!-- version: 16 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -Fx '<!-- version: 14 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 8 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' CHANGELOG.md
|
||||||
|
grep -Fx '## 0.0.5' CHANGELOG.md
|
||||||
|
grep -F -- '- `(x) 0.0.5`' ROADMAP.md
|
||||||
|
grep -F 'Le skeleton Tauri contrôlé reste `DEFER`' prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
|
||||||
|
python3 -B - <<'PYGATE'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'FAIL',
|
||||||
|
'alpha.3.fix.1.md': 'PASS',
|
||||||
|
'alpha.4.md': 'PASS',
|
||||||
|
'alpha.5.md': 'FAIL',
|
||||||
|
'alpha.5.fix.1.md': 'PASS',
|
||||||
|
'alpha.6.md': 'FAIL',
|
||||||
|
'alpha.6.fix.1.md': 'FAIL',
|
||||||
|
'alpha.6.fix.2.md': 'FAIL',
|
||||||
|
'alpha.6.fix.3.md': 'PASS',
|
||||||
|
'alpha.7.md': 'FAIL',
|
||||||
|
'alpha.7.fix.1.md': 'PASS',
|
||||||
|
'alpha.8.md': 'PASS',
|
||||||
|
'alpha.9.md': 'PASS',
|
||||||
|
'beta.1.md': 'PASS',
|
||||||
|
'rc.1.md': 'PASS',
|
||||||
|
'rel.001.md': 'FAIL',
|
||||||
|
}
|
||||||
|
for name, status in expected.items():
|
||||||
|
delta = Path('deltas/0.0.5', name)
|
||||||
|
history = Path('history/0.0.5', name)
|
||||||
|
assert delta.is_file(), name
|
||||||
|
assert history.is_file(), name
|
||||||
|
text = history.read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
pending = {p.name for p in Path('deltas/0.0.5').glob('*.md')} - \
|
||||||
|
{p.name for p in Path('history/0.0.5').glob('*.md')}
|
||||||
|
assert pending == {'rel.001.fix.1.md'}, pending
|
||||||
|
|
||||||
|
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||||
|
assert '- `(x) 0.0.5`' in roadmap
|
||||||
|
assert '- `( ) 0.1.0`' in roadmap
|
||||||
|
assert '(d) skeleton Tauri pour projets contrôlés' in roadmap
|
||||||
|
assert 'saselang-bible' not in roadmap
|
||||||
|
|
||||||
|
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
|
||||||
|
assert '## 0.0.5' in changelog.splitlines()
|
||||||
|
assert '## 0.0.5 (candidate)' not in changelog
|
||||||
|
|
||||||
|
prompt = Path('prompts/006-V0_1_0_START_PROMPT.md').read_text(encoding='utf-8')
|
||||||
|
assert 'pgr-v0.0.5.zip' in prompt
|
||||||
|
assert 'pgr-0.0.5-publish.001-report.md' in prompt
|
||||||
|
assert '0.1.0-alpha.1' in prompt
|
||||||
|
assert 'Le skeleton Tauri contrôlé reste `DEFER`' in prompt
|
||||||
|
|
||||||
|
plan = Path('docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md').read_text(encoding='utf-8')
|
||||||
|
assert "La gate opérateur de `rel.001` est toutefois `FAIL`" in plan
|
||||||
|
assert '`rel.001.fix.1` corrige uniquement cette preuve de clôture' in plan
|
||||||
|
|
||||||
|
print('0.0.5 rel.001.fix.1 stable history audit: clean (18 prior histories, failed rel preserved, corrected pre-tag proof)')
|
||||||
|
PYGATE
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
|
||||||
|
git add docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md \
|
||||||
|
deltas/0.0.5/rel.001.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope attendu avant ajout du history du fix est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
A deltas/0.0.5/rel.001.fix.1.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que `VERSION` reste `0.0.5`, que la présentation stable de `rel.001` reste inchangée, que le `FAIL` de `rel.001` est conservé historiquement, que le fix ne modifie aucun owner fonctionnel et qu'aucun tag n'est créé avant le history PASS de ce correctif.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire séparément `history/0.0.5/rel.001.fix.1.md`, l'appliquer puis committer/pousser la clôture stable corrigée. Ensuite seulement créer et publier le tag canonique `v0.0.5`, télécharger son archive source depuis Gitea et exécuter la vérification externe `publish.001`.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le diagnostic réel dans `history/0.0.5/rel.001.fix.1.md`, ne pas tagger et poursuivre avec un nouveau `.fix.N` ou un REPLAN si le problème dépasse la gate de clôture.
|
||||||
179
deltas/0.0.5/rel.001.md
Normal file
179
deltas/0.0.5/rel.001.md
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
<!-- file: deltas/0.0.5/rel.001.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.0.5 rel.001 — promotion stable pré-tag
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : `0.0.5-rc.1`, avec `history/0.0.5/rc.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||||
|
|
||||||
|
Le commit exact de cette baseline sera celui produit par l'opérateur après application du history RC ; il n'est pas anticipé dans cette livraison simultanée du history et du delta stable.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5-rc.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.5
|
||||||
|
```
|
||||||
|
|
||||||
|
`rel.001` identifie la clôture opérationnelle ; il ne fait pas partie de la version SemVer du produit.
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Promouvoir la RC validée vers la stable `0.0.5`. La tranche finalise uniquement la présentation de la release : version stable, roadmap terminée, changelog sans marqueur candidate, index documentaires et plan historique.
|
||||||
|
|
||||||
|
Le scope fonctionnel reste celui validé en RC : lifecycle inter-release, prompts versionnés, contrats documentaires locaux, profil Rust strict et audits monotâches, contrats architecturaux des suffixes de crates, ownership du tracing, profil Tauri 2, classification des versions produit, réconciliation KSP/Games et décision `DEFER` du skeleton Tauri contrôlé jusqu'à matérialisation d'owners Web suffisants.
|
||||||
|
|
||||||
|
La validation de cette tranche est **pré-tag**. Ni le tag `v0.0.5`, ni l'archive `pgr-v0.0.5.zip` téléchargée depuis Gitea, ni un rapport `pgr-0.0.5-publish.001-report.md` ne sont déclarés existants par ce delta. Ils suivent le history PASS, le commit stable et la publication réelle du tag.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
ROADMAP.md
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.0.5/rel.001.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
L'archive contient uniquement ces fichiers complets. `history/0.0.5/rc.1.md` est livré séparément ; le history de `rel.001` sera produit après sa gate. Le rapport post-tag restera extérieur à l'archive source taggée.
|
||||||
|
|
||||||
|
## Validation opérateur pré-tag
|
||||||
|
|
||||||
|
Après application sur le commit `rc.1`, depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test "$(cat VERSION)" = '0.0.5'
|
||||||
|
git cat-file -e HEAD:history/0.0.5/rc.1.md
|
||||||
|
test -f history/0.0.5/rc.1.md
|
||||||
|
test -f deltas/0.0.5/rel.001.md
|
||||||
|
test -f prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
test ! -e history/0.0.5/rel.001.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 14 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 8 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' CHANGELOG.md
|
||||||
|
grep -Fx '<!-- version: 17 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 15 -->' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -F 'plan historique de réconciliation `0.0.5`' README.md
|
||||||
|
grep -F -- '- `(x) 0.0.5`' ROADMAP.md
|
||||||
|
grep -Fx '## 0.0.5' CHANGELOG.md
|
||||||
|
grep -F 'périmètre et décisions de la release `0.0.5`' docs/000-README.md
|
||||||
|
grep -F 'La gate opérateur de `rc.1` est `PASS`' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -F 'pgr-0.0.5-publish.001-report.md' docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
grep -F 'Le skeleton Tauri contrôlé reste `DEFER`' prompts/006-V0_1_0_START_PROMPT.md
|
||||||
|
|
||||||
|
python3 -B - <<'PYGATE'
|
||||||
|
from pathlib import Path
|
||||||
|
import re
|
||||||
|
|
||||||
|
expected = {
|
||||||
|
'alpha.1.md': 'PASS',
|
||||||
|
'alpha.2.md': 'PASS',
|
||||||
|
'alpha.3.md': 'FAIL',
|
||||||
|
'alpha.3.fix.1.md': 'PASS',
|
||||||
|
'alpha.4.md': 'PASS',
|
||||||
|
'alpha.5.md': 'FAIL',
|
||||||
|
'alpha.5.fix.1.md': 'PASS',
|
||||||
|
'alpha.6.md': 'FAIL',
|
||||||
|
'alpha.6.fix.1.md': 'FAIL',
|
||||||
|
'alpha.6.fix.2.md': 'FAIL',
|
||||||
|
'alpha.6.fix.3.md': 'PASS',
|
||||||
|
'alpha.7.md': 'FAIL',
|
||||||
|
'alpha.7.fix.1.md': 'PASS',
|
||||||
|
'alpha.8.md': 'PASS',
|
||||||
|
'alpha.9.md': 'PASS',
|
||||||
|
'beta.1.md': 'PASS',
|
||||||
|
'rc.1.md': 'PASS',
|
||||||
|
}
|
||||||
|
for name, status in expected.items():
|
||||||
|
delta = Path('deltas/0.0.5', name)
|
||||||
|
history = Path('history/0.0.5', name)
|
||||||
|
assert delta.is_file(), name
|
||||||
|
assert history.is_file(), name
|
||||||
|
text = history.read_text(encoding='utf-8')
|
||||||
|
assert re.search(rf'## Statut\s+{status}\s', text), (name, status)
|
||||||
|
|
||||||
|
pending = {p.name for p in Path('deltas/0.0.5').glob('*.md')} - \
|
||||||
|
{p.name for p in Path('history/0.0.5').glob('*.md')}
|
||||||
|
assert pending == {'rel.001.md'}, pending
|
||||||
|
|
||||||
|
roadmap = Path('ROADMAP.md').read_text(encoding='utf-8')
|
||||||
|
assert '- `(x) 0.0.5`' in roadmap
|
||||||
|
assert '- `( ) 0.1.0`' in roadmap
|
||||||
|
assert '(d) skeleton Tauri pour projets contrôlés' in roadmap
|
||||||
|
assert 'saselang-bible' not in roadmap
|
||||||
|
|
||||||
|
changelog = Path('CHANGELOG.md').read_text(encoding='utf-8')
|
||||||
|
assert '## 0.0.5
|
||||||
|
' in changelog
|
||||||
|
assert '## 0.0.5 (candidate)' not in changelog
|
||||||
|
|
||||||
|
prompt = Path('prompts/006-V0_1_0_START_PROMPT.md').read_text(encoding='utf-8')
|
||||||
|
assert 'pgr-v0.0.5.zip' in prompt
|
||||||
|
assert 'pgr-0.0.5-publish.001-report.md' in prompt
|
||||||
|
assert '0.1.0-alpha.1' in prompt
|
||||||
|
assert 'Le skeleton Tauri contrôlé reste `DEFER`' in prompt
|
||||||
|
|
||||||
|
print('0.0.5 stable history audit: clean (17 prior histories with expected statuses, rel.001 pending)')
|
||||||
|
PYGATE
|
||||||
|
|
||||||
|
python3 -B scripts/audit_markdown_headers.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_tables.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
python3 -B scripts/audit_markdown_links.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md docs deltas history prompts
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git add VERSION README.md ROADMAP.md CHANGELOG.md docs/000-README.md \
|
||||||
|
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md deltas/0.0.5/rel.001.md
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope attendu avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M CHANGELOG.md
|
||||||
|
M README.md
|
||||||
|
M ROADMAP.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.0.5/rel.001.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Les `48` tests Python et les validations structurelles validés en RC restent des preuves applicables parce qu'aucun code, script, test, règle, template ou skeleton technique n'est modifié pendant `rel.001`. La gate stable se concentre donc sur l'intégrité de la chaîne historique, la présentation stable et les audits documentaires affectés.
|
||||||
|
|
||||||
|
## Revue opérateur complémentaire
|
||||||
|
|
||||||
|
Confirmer que le scope fonctionnel de la RC ne change pas, que README/roadmap/changelog/index/plan décrivent la même stable, que les `FAIL` historiques restent conservés avec leurs fixes `PASS`, que le skeleton Tauri reste différé sans release réservée, que le prompt `006` reste conditionnel à une vraie publication et qu'aucune preuve post-tag n'est anticipée.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire séparément `history/0.0.5/rel.001.md`, l'appliquer puis committer la stable. Ensuite seulement créer et publier le tag canonique `v0.0.5`, télécharger son archive source depuis Gitea, vérifier cette archive et conserver séparément la preuve post-tag `pgr-0.0.5-publish.001-report.md`.
|
||||||
|
|
||||||
|
Le message manuel de reprise de `prompts/006-V0_1_0_START_PROMPT.md` n'est remis à l'opérateur qu'après vérification effective de l'archive et d'un rapport post-tag PASS réel.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Consigner le diagnostic réel dans `history/0.0.5/rel.001.md`, ne pas tagger et corriger la clôture dans une tranche explicite avant publication.
|
||||||
202
deltas/0.1.0/alpha.1.md
Normal file
202
deltas/0.1.0/alpha.1.md
Normal 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.
|
||||||
178
deltas/0.1.0/alpha.2.fix.1.md
Normal file
178
deltas/0.1.0/alpha.2.fix.1.md
Normal 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
201
deltas/0.1.0/alpha.2.md
Normal 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.
|
||||||
167
deltas/0.1.0/alpha.3.fix.1.md
Normal file
167
deltas/0.1.0/alpha.3.fix.1.md
Normal 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
185
deltas/0.1.0/alpha.3.md
Normal 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
232
deltas/0.1.0/alpha.4.md
Normal 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
371
deltas/0.1.0/alpha.5.md
Normal 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
237
deltas/0.1.0/beta.1.md
Normal 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
333
deltas/0.1.0/rc.1.md
Normal 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
202
deltas/0.1.0/rel.1.md
Normal 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
219
deltas/0.1.1/alpha.1.md
Normal 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`.
|
||||||
204
deltas/0.1.1/alpha.2.fix.1.md
Normal file
204
deltas/0.1.1/alpha.2.fix.1.md
Normal 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
269
deltas/0.1.1/alpha.2.md
Normal 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é.
|
||||||
242
deltas/0.1.1/alpha.3.fix.1.md
Normal file
242
deltas/0.1.1/alpha.3.fix.1.md
Normal 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.
|
||||||
199
deltas/0.1.1/alpha.3.fix.2.md
Normal file
199
deltas/0.1.1/alpha.3.fix.2.md
Normal 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
310
deltas/0.1.1/alpha.3.md
Normal 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
226
deltas/0.1.1/alpha.4.md
Normal 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
325
deltas/0.1.1/alpha.5.md
Normal 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
264
deltas/0.1.1/beta.1.md
Normal 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
331
deltas/0.1.1/rc.1.md
Normal 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
252
deltas/0.1.1/rel.1.md
Normal 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
235
deltas/0.1.2/alpha.1.md
Normal 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`.
|
||||||
213
deltas/0.1.2/alpha.2.fix.1.md
Normal file
213
deltas/0.1.2/alpha.2.fix.1.md
Normal 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
259
deltas/0.1.2/alpha.2.md
Normal 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
365
deltas/0.1.2/alpha.3.md
Normal 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
275
deltas/0.1.2/beta.1.md
Normal 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
359
deltas/0.1.2/rc.1.md
Normal 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
288
deltas/0.1.2/rel.1.md
Normal 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
247
deltas/0.1.3/alpha.1.md
Normal 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
198
deltas/0.1.3/alpha.2.md
Normal 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
211
deltas/0.1.3/alpha.3.md
Normal 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
266
deltas/0.1.3/beta.1.md
Normal 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
312
deltas/0.1.3/rc.1.md
Normal 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
288
deltas/0.1.3/rel.1.md
Normal 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
207
deltas/0.1.4/alpha.1.md
Normal 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.
|
||||||
209
deltas/0.1.4/alpha.2.fix.1.md
Normal file
209
deltas/0.1.4/alpha.2.fix.1.md
Normal 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
214
deltas/0.1.4/alpha.2.md
Normal 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
202
deltas/0.1.4/alpha.3.md
Normal 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
189
deltas/0.1.4/beta.1.md
Normal 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
203
deltas/0.1.4/rc.1.md
Normal 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
233
deltas/0.1.4/rel.1.md
Normal 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`.
|
||||||
125
deltas/0.1.5/alpha.1.fix.1.md
Normal file
125
deltas/0.1.5/alpha.1.fix.1.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<!-- file: deltas/0.1.5/alpha.1.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-alpha.1.fix.1 — acquisition des preuves manquantes de la gate d'ouverture
|
||||||
|
|
||||||
|
## Baseline
|
||||||
|
|
||||||
|
Version attendue avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.5-alpha.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Le history `history/0.1.5/alpha.1.md` avec statut `PARTIAL` MUST avoir été appliqué, committé et poussé avant ce delta.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.5-alpha.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Résoudre uniquement le résultat `PARTIAL` de `alpha.1` en exécutant les preuves exigées par sa gate mais absentes du transcript opérateur.
|
||||||
|
|
||||||
|
Aucun défaut normatif, documentaire ou structurel n'est établi par `alpha.1`. Le présent fix ne réécrit donc pas son contenu, ne modifie aucun owner et ne commence pas `alpha.2`.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.1.5/alpha.1.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
## Preuves à acquérir
|
||||||
|
|
||||||
|
Le fix doit confirmer dans l'environnement opérateur :
|
||||||
|
|
||||||
|
- la trajectoire vivante `0.1.4` terminé puis `0.1.5` à `0.1.8`, sans réservation `0.1.9` ;
|
||||||
|
- les `103` couples delta/history historiques de `0.0.1` à `0.1.4`, plus le couple `0.1.5-alpha.1` désormais clôturé et le delta courant encore sans history ;
|
||||||
|
- les contrats du prompt `011` sur `SHOULD`, l'autonomie post-adoption et les scopes réservés ;
|
||||||
|
- les constats structurants du plan `011` et la séparation des tranches `alpha.2`, `alpha.3` et `alpha.4` ;
|
||||||
|
- l'hygiène du nouveau delta et le scope Git strictement limité au fix.
|
||||||
|
|
||||||
|
Les `55/55` tests Python, l'hygiène texte et les audits Markdown complets de `alpha.1` sont déjà des preuves opérateur acquises. Le fix ne modifie aucun code ni script ; il ne rejoue donc pas la suite Python par simple répétition. Les audits texte/Markdown sont toutefois rejoués pour valider le nouvel artefact documentaire.
|
||||||
|
|
||||||
|
## Validation opérateur
|
||||||
|
|
||||||
|
Exécuter depuis la racine du dépôt après commit/push de `alpha.1` puis application du présent delta :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/alpha.1.md
|
||||||
|
test -f deltas/0.1.5/alpha.1.fix.1.md
|
||||||
|
test ! -e history/0.1.5/alpha.1.fix.1.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-alpha.1.fix.1' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.md | grep -Fx 'PARTIAL'
|
||||||
|
|
||||||
|
grep -F -- '- `(x) 0.1.4`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.5`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md'}; print('0.1.5 alpha.1.fix.1 history boundary: clean (104 closed prior pairs, current fix pending)')"
|
||||||
|
|
||||||
|
grep -F 'forte recommandation non obligatoire' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'ne doivent ni rechercher automatiquement « la dernière version de PGR »' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'réservée à `0.1.6`' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'réservée à `0.1.7`' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'réservés à `0.1.8`' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
|
||||||
|
grep -F '29` fichiers' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '242` occurrences' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '### `alpha.2` — sémantique normative et conséquences de gate/adoption' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '### `alpha.3` — autonomie locale et réalignement volontaire' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '### `alpha.4` — frontière PGR / SaseDev Knowledge' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 status --short
|
||||||
|
|
||||||
|
git add VERSION deltas/0.1.5/alpha.1.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history du fix est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.1.5/alpha.1.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire `history/0.1.5/alpha.1.fix.1.md`, appliquer ce history puis committer/pusher `0.1.5-alpha.1.fix.1`. Préparer ensuite `0.1.5-alpha.2` conformément au plan, sans réouvrir les scopes autonomie `alpha.3` ou Knowledge `alpha.4`.
|
||||||
|
|
||||||
|
### FAIL / PARTIAL / BLOCKED
|
||||||
|
|
||||||
|
Consigner le résultat réellement observé dans `history/0.1.5/alpha.1.fix.1.md` et rester dans `alpha.1.fix.M` tant que les preuves d'ouverture ne sont pas complètement acquises, sauf REPLAN si un défaut plus large est démontré.
|
||||||
222
deltas/0.1.5/alpha.1.md
Normal file
222
deltas/0.1.5/alpha.1.md
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<!-- file: deltas/0.1.5/alpha.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-alpha.1 — intake, audit transversal et plan d’autonomie
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Ouvrir `0.1.5` conformément à `prompts/011-V0_1_5_START_PROMPT.md`, rejouer la stable `0.1.4`, conserver son histoire réelle et matérialiser l’inventaire des ambiguïtés avant toute modification normative.
|
||||||
|
|
||||||
|
La tranche ne modifie aucune règle, aucun skeleton ni template normatif. Elle ne commence ni l’adoption Games `0.1.6`, ni l’adoption KSP `0.1.7`, ni les audits Rust/Clippy `0.1.8`.
|
||||||
|
|
||||||
|
## Sources vérifiées avant préparation
|
||||||
|
|
||||||
|
```text
|
||||||
|
pgr-v0.1.4(1).zip
|
||||||
|
SHA-256 9f85ac16a5ad9fd788df51883b6ebf592602c5189d94e338a86edab2288b8f77
|
||||||
|
CRC PASS
|
||||||
|
contenu 310 fichiers + 44 répertoires sous pgr/
|
||||||
|
|
||||||
|
pgr-0.1.4-publish.001-report.md
|
||||||
|
SHA-256 bb0c27a69e78037328d13c7be8df255d17f55e1392f1bc1b6121dd32b6fb07da
|
||||||
|
status PASS
|
||||||
|
stable c41b69badfd10ef9500d4cc4061fc6f66644352c
|
||||||
|
```
|
||||||
|
|
||||||
|
Le SHA de l’archive reçue correspond au SHA canonique vérifié lors de la publication post-tag. L’absence de `.git` dans l’archive est normale pour l’export du tag et n’est pas interprétée comme un défaut.
|
||||||
|
|
||||||
|
## Replay de la stable
|
||||||
|
|
||||||
|
La baseline extraite a été vérifiée avant toute préparation de delta :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION 0.1.4
|
||||||
|
tests Python 55/55 PASS
|
||||||
|
hygiène texte 309 fichiers PASS
|
||||||
|
headers Markdown 282 fichiers PASS
|
||||||
|
tables Markdown 11 tables / 282 fichiers PASS
|
||||||
|
liens Markdown 357 liens locaux / 282 fichiers PASS
|
||||||
|
JSON 2 fichiers parsés
|
||||||
|
TOML 5 fichiers parsés
|
||||||
|
deltas 103
|
||||||
|
histories 103
|
||||||
|
appariement historique exact
|
||||||
|
```
|
||||||
|
|
||||||
|
La séquence `0.1.4` publiée est explicitement conservée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PASS
|
||||||
|
alpha.2 FAIL
|
||||||
|
alpha.2.fix.1 PASS
|
||||||
|
alpha.3 PASS
|
||||||
|
beta.1 PASS
|
||||||
|
rc.1 PASS
|
||||||
|
rel.1 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun history n’est réécrit pour rendre la chronologie artificiellement linéaire.
|
||||||
|
|
||||||
|
## Résultats de l’audit transversal
|
||||||
|
|
||||||
|
Le corpus courant contient `29` fichiers avec au moins un `SHOULD` ou `SHOULD NOT`, pour `242` occurrences brutes. Cette volumétrie confirme qu’une conversion mécanique serait incorrecte : la majorité des recommandations restent valides et doivent hériter d’un contrat global clarifié.
|
||||||
|
|
||||||
|
Les ambiguïtés confirmées sont consignées dans `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md`.
|
||||||
|
|
||||||
|
### Force normative
|
||||||
|
|
||||||
|
- `RULES.md` peut faire comprendre qu’un écart à `SHOULD` doit être systématiquement justifié ;
|
||||||
|
- `230-ADOPTION.md` peut faire comprendre qu’un choix différent d’un `SHOULD` nécessite automatiquement `OVERRIDE` ;
|
||||||
|
- `400-VALIDATION.md` ne protège pas encore explicitement une gate contre l’échec fondé sur le seul écart à une recommandation ;
|
||||||
|
- plusieurs owners Web matérialisent cette ambiguïté par une justification ou un `OVERRIDE` rendu obligatoire autour d’une recommandation.
|
||||||
|
|
||||||
|
### Autonomie
|
||||||
|
|
||||||
|
Les objectifs, l’architecture, les skeletons et les patterns d’adoption contiennent déjà le principe d’autonomie, mais le contrat « baseline locale = autorité des sessions/releases suivantes » n’est pas encore propagé explicitement partout. PGR doit aussi cesser d’être interprétable comme upstream documentaire vivant après l’adoption.
|
||||||
|
|
||||||
|
`210-WORKFLOW.md` et `003-NEW_SESSION_PROMPT.md` sont classés `KEEP / REVIEW` à ce stade : ils utilisent déjà la baseline autoritaire du projet courant plutôt qu’une version PGR externe.
|
||||||
|
|
||||||
|
### Frontière PGR / Knowledge
|
||||||
|
|
||||||
|
`001-PROJECT_OBJECTIVES.md` et `002-GOVERNANCE_ARCHITECTURE.md` parlent encore de skeletons comme de « recettes Markdown ». Cette terminologie brouille la frontière décidée en `0.1.4`, où les recettes pratiques deviennent des candidats à Knowledge tandis qu’un skeleton PGR reste une spécification de composition.
|
||||||
|
|
||||||
|
`300-DOCUMENTATION.md` est proposé comme owner de la taxonomie ; aucun nouvel owner Knowledge n’est créé pendant `alpha.1`.
|
||||||
|
|
||||||
|
### Cohérence d’horizon
|
||||||
|
|
||||||
|
`docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` contient encore une référence vivante à l’adoption Games `0.1.5`. La trajectoire autoritaire issue de la revue `0.1.4` réserve maintenant Games à `0.1.6`, KSP à `0.1.7` et les audits Rust/Clippy à `0.1.8`.
|
||||||
|
|
||||||
|
La correction appartient à la réconciliation normative suivante. Les références historiques qui décrivent correctement un horizon antérieur ne doivent pas être réécrites.
|
||||||
|
|
||||||
|
## Modifications de la tranche
|
||||||
|
|
||||||
|
- `VERSION` passe à `0.1.5-alpha.1` ;
|
||||||
|
- `README.md` annonce l’ouverture de l’audit transversal et référence le plan actif ;
|
||||||
|
- `docs/000-README.md` ajoute les points d’entrée actifs de `0.1.5` ;
|
||||||
|
- `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` consigne preuves, ambiguïtés, owners et trajectoire ;
|
||||||
|
- le présent delta décrit la gate opérateur.
|
||||||
|
|
||||||
|
`ROADMAP.md`, `CHANGELOG.md`, `RULES.md`, `docs/rules/`, `docs/skeletons/` et `docs/templates/` restent normativement inchangés pendant cette tranche d’ouverture.
|
||||||
|
|
||||||
|
## Décision de tranche
|
||||||
|
|
||||||
|
```text
|
||||||
|
baseline 0.1.4 VERIFIED
|
||||||
|
history 0.1.4 alpha.2 FAIL PRESERVED
|
||||||
|
inventaire transversal COMPLETE
|
||||||
|
conversion mécanique des SHOULD REJECTED
|
||||||
|
owners ciblés IDENTIFIED
|
||||||
|
règles modifiées en alpha.1 NO
|
||||||
|
Games / KSP / audits Rust commencés NO
|
||||||
|
prochaine tranche alpha.2 — sémantique normative et gates/adoption
|
||||||
|
```
|
||||||
|
|
||||||
|
## Trajectoire retenue
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 intake + audit transversal + plan
|
||||||
|
alpha.2 sémantique MUST/SHOULD/MAY + gates/adoption + cas concrets
|
||||||
|
alpha.3 autonomie locale + réalignement PGR volontaire
|
||||||
|
alpha.4 frontière PGR / SaseDev Knowledge
|
||||||
|
beta.1 réconciliation transversale
|
||||||
|
rc.1 freeze + handoff
|
||||||
|
rel.1 promotion stable
|
||||||
|
```
|
||||||
|
|
||||||
|
Le découpage peut être ajusté uniquement si une gate révèle un défaut réel ou si deux owners ne peuvent pas être corrigés proprement dans la même tranche.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Appliquer le delta puis exécuter depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
test -f deltas/0.1.5/alpha.1.md
|
||||||
|
test ! -e history/0.1.5/alpha.1.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-alpha.1' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.4/alpha.2.md | grep -Fx 'FAIL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.4/alpha.2.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.4/rel.1.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -F -- '- `(x) 0.1.4`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.5`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert Path('deltas/0.1.5/alpha.1.md').is_file(); assert not Path('history/0.1.5/alpha.1.md').exists(); print('0.1.5 alpha.1 history boundary: clean (103 prior pairs, current delta pending)')"
|
||||||
|
|
||||||
|
grep -F 'forte recommandation non obligatoire' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'ne doivent ni rechercher automatiquement « la dernière version de PGR »' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'réservée à `0.1.6`' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'réservée à `0.1.7`' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
grep -F 'réservés à `0.1.8`' prompts/011-V0_1_5_START_PROMPT.md
|
||||||
|
|
||||||
|
grep -F '29` fichiers' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '242` occurrences' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'alpha.2` — sémantique normative' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'alpha.3` — autonomie locale' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'alpha.4` — frontière PGR / SaseDev Knowledge' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
git add VERSION README.md docs/000-README.md \
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md \
|
||||||
|
deltas/0.1.5/alpha.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.1.5/alpha.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
A docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun fichier sous `docs/rules/`, `docs/skeletons/` ou `docs/templates/` ne doit être indexé pour `alpha.1`.
|
||||||
|
|
||||||
|
## Revue opérateur attendue
|
||||||
|
|
||||||
|
La revue doit confirmer que l’inventaire distingue bien :
|
||||||
|
|
||||||
|
- un `SHOULD` réellement recommandatoire d’une obligation `MUST` ;
|
||||||
|
- un choix local face à une recommandation d’un véritable `OVERRIDE` ;
|
||||||
|
- l’autonomie documentaire du projet d’une simple absence de dépendance runtime/build ;
|
||||||
|
- une skeleton specification normative d’une recette pratique candidate à Knowledge ;
|
||||||
|
- les références vivantes à corriger des références historiques à préserver.
|
||||||
|
|
||||||
|
Elle doit également confirmer qu’aucune adoption Games/KSP, aucun audit Rust futur et aucune réouverture Tauri ne sont introduits par la tranche.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire `history/0.1.5/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.5-alpha.2` consacré à la sémantique normative, aux conséquences de gate/adoption et aux cas concrets déjà identifiés, sans absorber l’autonomie `alpha.3` ni la frontière Knowledge `alpha.4`.
|
||||||
|
|
||||||
|
Après remise du history, fournir automatiquement le bloc opérateur exact pour appliquer le history, committer/pusher `0.1.5-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.5-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.
|
||||||
196
deltas/0.1.5/alpha.2.md
Normal file
196
deltas/0.1.5/alpha.2.md
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
<!-- file: deltas/0.1.5/alpha.2.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-alpha.2 — sémantique normative et conséquences de gate/adoption
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Stabiliser la force normative de `MUST / SHOULD / MAY` après le cadrage `alpha.1` et la récupération de preuve `alpha.1.fix.1`, puis corriger uniquement les renforcements accidentels démontrés par l'inventaire.
|
||||||
|
|
||||||
|
La tranche ne convertit pas mécaniquement les `242` occurrences de `SHOULD / SHOULD NOT`. Elle fixe le contrat transversal, aligne adoption et validation, puis corrige les quelques owners/skeletons/templates où une recommandation était implicitement transformée en obligation de justification ou en `OVERRIDE`.
|
||||||
|
|
||||||
|
## Précondition
|
||||||
|
|
||||||
|
Le history `history/0.1.5/alpha.1.fix.1.md` doit être présent avec statut `PASS` avant application de ce delta.
|
||||||
|
|
||||||
|
La séquence d'ouverture reste conservée telle qu'observée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PARTIAL
|
||||||
|
alpha.1.fix.1 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Le `PARTIAL` n'est pas réécrit : le fix a seulement acquis les preuves manquantes et autorise maintenant la progression vers la sémantique normative.
|
||||||
|
|
||||||
|
## Contrat normatif stabilisé
|
||||||
|
|
||||||
|
`RULES.md` devient l'owner primaire de la distinction :
|
||||||
|
|
||||||
|
```text
|
||||||
|
MUST / MUST NOT obligation ou interdiction normative
|
||||||
|
SHOULD / SHOULD NOT forte recommandation non obligatoire
|
||||||
|
MAY possibilité neutre
|
||||||
|
```
|
||||||
|
|
||||||
|
Un écart à un `SHOULD / SHOULD NOT` PGR :
|
||||||
|
|
||||||
|
- ne constitue pas à lui seul une non-conformité ;
|
||||||
|
- ne fait pas échouer à lui seul une gate ;
|
||||||
|
- n'exige pas automatiquement un `OVERRIDE` ;
|
||||||
|
- MAY être documenté lorsque la raison apporte une valeur durable de maintenance, architecture ou reprise.
|
||||||
|
|
||||||
|
Une contradiction avec un `MUST / MUST NOT` réellement applicable reste distincte et continue d'utiliser l'exception ou l'override autorisé par le scope concerné.
|
||||||
|
|
||||||
|
## Alignement adoption et validation
|
||||||
|
|
||||||
|
`docs/rules/230-ADOPTION.md` passe en révision `2` : la classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ne renforce plus implicitement un `SHOULD`. Un simple choix différent d'une recommandation ne devient pas un `OVERRIDE` obligatoire.
|
||||||
|
|
||||||
|
`docs/rules/400-VALIDATION.md` passe en révision `2` : une gate doit distinguer obligation et recommandation. Un `SHOULD` non suivi peut produire une observation, un diagnostic ou un point de revue, mais pas un `FAIL` par sa seule force PGR. Un projet peut rendre localement un choix obligatoire uniquement en matérialisant explicitement ce contrat local.
|
||||||
|
|
||||||
|
## Réconciliation ciblée des effets `SHOULD`
|
||||||
|
|
||||||
|
Les owners et artefacts suivants sont corrigés parce que `alpha.1` a démontré un renforcement concret :
|
||||||
|
|
||||||
|
- `docs/rules/500-LANGUAGES.md` révision `2` : un override est requis pour une contradiction réelle avec un `MUST / MUST NOT`, pas pour un simple écart à un `SHOULD` ;
|
||||||
|
- `docs/rules/530-TYPESCRIPT.md` révision `4` : choisir JavaScript malgré la recommandation TypeScript ne crée ni non-conformité, ni override, ni justification obligatoire ;
|
||||||
|
- `docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` révision `4` : la politique de lockfile reste une recommandation lorsqu'elle est marquée `SHOULD`, et la référence vivante Games est corrigée de `0.1.5` vers `0.1.6` ;
|
||||||
|
- `docs/rules/700-FRAMEWORKS.md` révision `3` : la composition conserve la force normative propre des règles héritées au lieu de traiter toute divergence comme override ;
|
||||||
|
- `docs/skeletons/003-WEB_FRONTEND.md` révision `2` : un choix JavaScript n'impose plus de justification automatique ;
|
||||||
|
- `docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md` révision `3` : une politique de lockfile différente n'exige plus automatiquement `OVERRIDE` + justification.
|
||||||
|
|
||||||
|
Les `MUST` réellement applicables de ces documents restent inchangés dans leur intention.
|
||||||
|
|
||||||
|
## Cohérence documentaire
|
||||||
|
|
||||||
|
- `README.md` présente `0.1.5-alpha.2` comme la tranche active sans déclarer la stable `0.1.4` remplacée ;
|
||||||
|
- `docs/000-README.md` marque les owners de sémantique comme réconciliés en `alpha.2` ;
|
||||||
|
- `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` passe en révision `2`, conserve les constats `alpha.1` comme observations historiques et enregistre la récupération `alpha.1.fix.1` ainsi que la mise en œuvre `alpha.2`.
|
||||||
|
|
||||||
|
`ROADMAP.md` et `CHANGELOG.md` restent inchangés. Les histories `0.1.4`, les adoptions Games/KSP et les futurs audits Rust/Clippy restent hors scope.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Appliquer le delta après commit/push de `alpha.1.fix.1`, puis exécuter depuis la racine du dépôt :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/alpha.1.md
|
||||||
|
test -f history/0.1.5/alpha.1.fix.1.md
|
||||||
|
test -f deltas/0.1.5/alpha.2.md
|
||||||
|
test ! -e history/0.1.5/alpha.2.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-alpha.2' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.md | grep -Fx 'PARTIAL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.fix.1.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 15 -->' RULES.md
|
||||||
|
grep -F 'forte recommandation non obligatoire' RULES.md
|
||||||
|
grep -F "n'exige pas automatiquement un \`OVERRIDE\`" RULES.md
|
||||||
|
grep -F "ne fait pas échouer à lui seul une gate" RULES.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F "ne crée pas à lui seul un \`OVERRIDE\` obligatoire" docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'MUST NOT exiger un override uniquement parce que la recommandation' docs/rules/230-ADOPTION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/400-VALIDATION.md
|
||||||
|
grep -F 'MUST NOT faire passer une tranche en `FAIL`' docs/rules/400-VALIDATION.md
|
||||||
|
grep -F "la gate évalue alors ce contrat local, pas le \`SHOULD\` PGR d'origine" docs/rules/400-VALIDATION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/500-LANGUAGES.md
|
||||||
|
grep -F "Un choix différent d'un \`SHOULD / SHOULD NOT\` général ne nécessite pas, à lui seul, un override" docs/rules/500-LANGUAGES.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/530-TYPESCRIPT.md
|
||||||
|
grep -F "n'exige pas automatiquement un \`OVERRIDE\` et ne crée pas une obligation de justification" docs/rules/530-TYPESCRIPT.md
|
||||||
|
! grep -F 'sauf incompatibilité documentée' docs/rules/530-TYPESCRIPT.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
grep -F "Lors de l'adoption \`0.1.6\`" docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
! grep -F "Lors de l'adoption \`0.1.5\`" docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
grep -F "ne requiert pas à lui seul un \`OVERRIDE\`" docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/700-FRAMEWORKS.md
|
||||||
|
grep -F "MAY choisir différemment d'un \`SHOULD / SHOULD NOT\`" docs/rules/700-FRAMEWORKS.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/skeletons/003-WEB_FRONTEND.md
|
||||||
|
grep -F "sans transformer un choix JavaScript en obligation de justification ou en \`OVERRIDE\`" docs/skeletons/003-WEB_FRONTEND.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
|
||||||
|
grep -F "n'exige pas à lui seul un \`OVERRIDE\` ni une justification" docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'un écart à cette recommandation ne crée ni non-conformité, ni `FAIL` de gate, ni `OVERRIDE` automatique' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md'}; print('0.1.5 alpha.2 history boundary: clean (105 closed prior pairs, current alpha.2 pending)')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 status --short
|
||||||
|
|
||||||
|
git add VERSION README.md RULES.md docs/000-README.md \
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md \
|
||||||
|
docs/rules/230-ADOPTION.md docs/rules/400-VALIDATION.md \
|
||||||
|
docs/rules/500-LANGUAGES.md docs/rules/530-TYPESCRIPT.md \
|
||||||
|
docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md docs/rules/700-FRAMEWORKS.md \
|
||||||
|
docs/skeletons/003-WEB_FRONTEND.md docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md \
|
||||||
|
deltas/0.1.5/alpha.2.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M RULES.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.1.5/alpha.2.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
M docs/rules/230-ADOPTION.md
|
||||||
|
M docs/rules/400-VALIDATION.md
|
||||||
|
M docs/rules/500-LANGUAGES.md
|
||||||
|
M docs/rules/530-TYPESCRIPT.md
|
||||||
|
M docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
M docs/rules/700-FRAMEWORKS.md
|
||||||
|
M docs/skeletons/003-WEB_FRONTEND.md
|
||||||
|
M docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur attendue
|
||||||
|
|
||||||
|
La revue doit confirmer que la tranche clarifie la force de `SHOULD` sans affaiblir les obligations existantes ; qu'aucun `SHOULD` n'est transformé en `MUST` par une gate, un mapping d'adoption, un skeleton ou un template ; et que les corrections Web ciblées restent des conséquences de la sémantique générale plutôt qu'une réouverture de la fondation Web.
|
||||||
|
|
||||||
|
Elle doit également confirmer que l'autonomie post-adoption n'est pas encore implémentée par `alpha.2`, que la frontière PGR / Knowledge n'est pas encore modifiée, et que les scopes `0.1.6` à `0.1.8` restent réservés.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire `history/0.1.5/alpha.2.md` à partir des résultats réellement observés. Dans la même réponse, fournir les commandes commit/push de `0.1.5-alpha.2`, puis préparer séparément `0.1.5-alpha.3` consacré à l'autonomie locale et au réalignement PGR volontaire.
|
||||||
|
|
||||||
|
### FAIL / PARTIAL / BLOCKED
|
||||||
|
|
||||||
|
Enregistrer le résultat réel dans `history/0.1.5/alpha.2.md` puis ouvrir `alpha.2.fix.N` ou un REPLAN selon la cause. Aucun changement réservé à l'autonomie `alpha.3` ou à la frontière Knowledge `alpha.4` ne doit être absorbé silencieusement dans la correction.
|
||||||
185
deltas/0.1.5/alpha.3.md
Normal file
185
deltas/0.1.5/alpha.3.md
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
<!-- file: deltas/0.1.5/alpha.3.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-alpha.3 — autonomie locale et réalignement PGR volontaire
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Stabiliser le contrat d'autonomie après instanciation ou adoption : une fois la baseline locale établie, le projet gouverne ses sessions et releases suivantes depuis ses propres owners, sans dépendance documentaire implicite vers PGR ni recherche automatique d'une version plus récente du référentiel.
|
||||||
|
|
||||||
|
La tranche définit également le seul mécanisme prévu pour revenir volontairement vers PGR : un réalignement explicite, borné, fondé sur un snapshot PGR précis choisi par le projet puis comparé à la baseline locale.
|
||||||
|
|
||||||
|
## Précondition
|
||||||
|
|
||||||
|
Le history `history/0.1.5/alpha.2.md` doit être présent avec statut `PASS` avant application de ce delta.
|
||||||
|
|
||||||
|
La séquence acquise reste conservée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PARTIAL
|
||||||
|
alpha.1.fix.1 PASS
|
||||||
|
alpha.2 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Le `PARTIAL` initial n'est pas réécrit et les histories précédents restent inchangés.
|
||||||
|
|
||||||
|
## Contrat d'autonomie
|
||||||
|
|
||||||
|
Après instanciation ou adoption :
|
||||||
|
|
||||||
|
```text
|
||||||
|
snapshot PGR explicitement choisi
|
||||||
|
↓
|
||||||
|
instanciation / adoption / adaptation
|
||||||
|
↓
|
||||||
|
baseline locale du projet
|
||||||
|
↓
|
||||||
|
autorité locale des sessions et releases suivantes
|
||||||
|
```
|
||||||
|
|
||||||
|
Le projet possède alors ses règles, plans, architecture, décisions et historiques applicables. PGR ne devient ni dépendance runtime/build, ni upstream documentaire implicite.
|
||||||
|
|
||||||
|
Le projet MUST NOT rechercher automatiquement « la dernière version de PGR » pour reprendre une session ou ouvrir une release suivante.
|
||||||
|
|
||||||
|
## Réalignement futur
|
||||||
|
|
||||||
|
Un réalignement PGR reste possible lorsqu'il est explicitement décidé. Il ne constitue pas une mise à jour continue.
|
||||||
|
|
||||||
|
L'opération doit :
|
||||||
|
|
||||||
|
1. identifier un snapshot PGR précis — version, tag, commit ou archive ;
|
||||||
|
2. repartir de la baseline locale autoritaire ;
|
||||||
|
3. comparer les owners PGR réellement applicables ;
|
||||||
|
4. classifier les écarts utiles selon `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
|
||||||
|
5. définir un scope et des validations proportionnés ;
|
||||||
|
6. préserver les histories et snapshots historiques du projet.
|
||||||
|
|
||||||
|
Entre deux réalignements explicitement décidés, la baseline locale reste suffisante et autoritaire.
|
||||||
|
|
||||||
|
## Owners réconciliés
|
||||||
|
|
||||||
|
- `RULES.md` révision `16` : autonomie générale, absence d'upstream PGR implicite et réalignement borné ;
|
||||||
|
- `docs/rules/220-SKELETONS.md` révision `2` : la baseline locale devient autoritaire dès l'instanciation et aucune version PGR plus récente n'est recherchée automatiquement ;
|
||||||
|
- `docs/rules/230-ADOPTION.md` révision `3` : contrat complet d'autorité locale et procédure de réalignement futur ;
|
||||||
|
- `docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` révision `5` : propagation du contrat au point d'entrée normatif local ;
|
||||||
|
- `docs/templates/007-EXISTING_PROJECT_ADOPTION.md` révision `2` : snapshot PGR choisi, baseline locale de sortie et pattern de réalignement explicite.
|
||||||
|
|
||||||
|
`docs/rules/210-WORKFLOW.md` révision `9` et `docs/templates/003-NEW_SESSION_PROMPT.md` révision `2` restent `KEEP` : leur reprise part déjà de la baseline autoritaire du projet courant et aucune contradiction n'a été démontrée.
|
||||||
|
|
||||||
|
## Cohérence documentaire
|
||||||
|
|
||||||
|
- `README.md` présente `0.1.5-alpha.3` comme tranche active ;
|
||||||
|
- `docs/000-README.md` identifie les owners d'autonomie réconciliés ;
|
||||||
|
- `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` passe en révision `3`, enregistre `alpha.2 PASS` et la mise en œuvre `alpha.3`.
|
||||||
|
|
||||||
|
`ROADMAP.md` et `CHANGELOG.md` restent inchangés. La frontière PGR / SaseDev Knowledge reste réservée à `alpha.4` ; Games `0.1.6`, KSP `0.1.7` et les audits Rust/Clippy `0.1.8` restent hors scope.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Après commit/push de `alpha.2` avec son history `PASS`, appliquer ce delta puis exécuter :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/alpha.2.md
|
||||||
|
test -f deltas/0.1.5/alpha.3.md
|
||||||
|
test ! -e history/0.1.5/alpha.3.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-alpha.3' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.md | grep -Fx 'PARTIAL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.2.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 16 -->' RULES.md
|
||||||
|
grep -F 'cette baseline et ses owners locaux deviennent l'autorité des sessions et releases suivantes' RULES.md
|
||||||
|
grep -F 'MUST NOT rechercher automatiquement « la dernière version de PGR »' RULES.md
|
||||||
|
grep -F 'réalignement futur avec PGR MAY être engagé comme opération explicite et bornée' RULES.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/220-SKELETONS.md
|
||||||
|
grep -F 'Cette baseline locale devient l'autorité de ses sessions et releases suivantes' docs/rules/220-SKELETONS.md
|
||||||
|
grep -F 'MUST NOT rechercher automatiquement une version PGR plus récente' docs/rules/220-SKELETONS.md
|
||||||
|
grep -F "snapshot PGR précis choisi par le projet" docs/rules/220-SKELETONS.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'elle devient l'autorité des sessions et releases suivantes du projet' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'MUST NOT rechercher automatiquement « la dernière version de PGR »' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F '## Autorité locale et réalignement futur' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'identifier le snapshot PGR choisi' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'Le réalignement ne doit pas être présenté comme une mise à jour automatique' docs/rules/230-ADOPTION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
grep -F "la baseline locale et ses owners deviennent l'autorité des sessions et releases suivantes" docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
grep -F 'MUST NOT rechercher automatiquement « la dernière version de PGR »' docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/templates/007-EXISTING_PROJECT_ADOPTION.md
|
||||||
|
grep -F 'snapshot PGR choisi' docs/templates/007-EXISTING_PROJECT_ADOPTION.md
|
||||||
|
grep -F '## Autorité après adoption' docs/templates/007-EXISTING_PROJECT_ADOPTION.md
|
||||||
|
grep -F 'réalignement PGR automatique : non' docs/templates/007-EXISTING_PROJECT_ADOPTION.md
|
||||||
|
grep -F 'Elles ne recherchent pas automatiquement « la dernière version de PGR »' docs/templates/007-EXISTING_PROJECT_ADOPTION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/templates/003-NEW_SESSION_PROMPT.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Sa gate opérateur du `2026-10-01` est `PASS`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Décisions de mise en œuvre `alpha.3`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'la frontière Knowledge reste réservée à `alpha.4`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md'}; print('0.1.5 alpha.3 history boundary: clean (106 closed prior pairs, current alpha.3 pending)')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 status --short
|
||||||
|
|
||||||
|
git add VERSION README.md RULES.md docs/000-README.md \
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md \
|
||||||
|
docs/rules/220-SKELETONS.md docs/rules/230-ADOPTION.md \
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||||
|
docs/templates/007-EXISTING_PROJECT_ADOPTION.md \
|
||||||
|
deltas/0.1.5/alpha.3.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
Le scope indexé attendu avant ajout du history est exactement :
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M RULES.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.1.5/alpha.3.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
M docs/rules/220-SKELETONS.md
|
||||||
|
M docs/rules/230-ADOPTION.md
|
||||||
|
M docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md
|
||||||
|
M docs/templates/007-EXISTING_PROJECT_ADOPTION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur attendue
|
||||||
|
|
||||||
|
La revue doit confirmer qu'un projet adopté reste effectivement gouvernable sans consulter PGR, que le réalignement futur est une opération explicite et non un abonnement implicite, et qu'aucune règle n'oblige un projet à suivre automatiquement les nouvelles releases PGR.
|
||||||
|
|
||||||
|
Elle doit aussi confirmer que `210-WORKFLOW.md` et `003-NEW_SESSION_PROMPT.md` restent corrects sans modification et que `alpha.3` ne commence ni la frontière Knowledge ni les adoptions Games/KSP.
|
||||||
186
deltas/0.1.5/alpha.4.md
Normal file
186
deltas/0.1.5/alpha.4.md
Normal file
@@ -0,0 +1,186 @@
|
|||||||
|
<!-- file: deltas/0.1.5/alpha.4.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-alpha.4 — frontière PGR / SaseDev Knowledge
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Stabiliser la frontière durable entre le référentiel normatif PGR et les contenus pratiques qui peuvent vivre dans une base de connaissances séparée.
|
||||||
|
|
||||||
|
PGR doit rester auto-suffisant pour comprendre et appliquer ses règles. SaseDev Knowledge MAY accueillir des howtos détaillés, recettes pratiques, snippets, exemples d'intégration, dépannage, comparatifs et variantes d'implémentation, mais ne devient ni owner normatif de PGR ni dépendance nécessaire à son interprétation.
|
||||||
|
|
||||||
|
La tranche ne déplace aucun contenu vers Knowledge et ne crée aucun lien de dépendance vers un dépôt externe.
|
||||||
|
|
||||||
|
## Précondition
|
||||||
|
|
||||||
|
Le history `history/0.1.5/alpha.3.md` doit être présent avec statut `PASS` avant application de ce delta.
|
||||||
|
|
||||||
|
La séquence acquise reste conservée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PARTIAL
|
||||||
|
alpha.1.fix.1 PASS
|
||||||
|
alpha.2 PASS
|
||||||
|
alpha.3 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Les histories précédents ne sont pas réécrits.
|
||||||
|
|
||||||
|
## Taxonomie stabilisée
|
||||||
|
|
||||||
|
PGR conserve les informations nécessaires à son propre contrat :
|
||||||
|
|
||||||
|
```text
|
||||||
|
PGR
|
||||||
|
règles et contrats de gouvernance
|
||||||
|
objectifs et architecture
|
||||||
|
owners normatifs
|
||||||
|
skeleton specifications minimales
|
||||||
|
templates nécessaires à un contrat réutilisable
|
||||||
|
validations directement liées aux règles
|
||||||
|
```
|
||||||
|
|
||||||
|
Les contenus suivants sont pratiques et MAY vivre dans une base de connaissances séparée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
contenus pratiques complémentaires
|
||||||
|
howtos détaillés
|
||||||
|
recettes pratiques
|
||||||
|
snippets
|
||||||
|
exemples d'intégration
|
||||||
|
dépannage
|
||||||
|
comparatifs
|
||||||
|
variantes d'implémentation
|
||||||
|
```
|
||||||
|
|
||||||
|
Cette classification est sémantique. Elle ne déclenche aucun déplacement automatique.
|
||||||
|
|
||||||
|
## Auto-suffisance
|
||||||
|
|
||||||
|
Une règle PGR doit rester interprétable depuis PGR lui-même. Un document pratique externe MAY aider à l'implémentation, mais MUST NOT être nécessaire pour déterminer la force, le scope ou les exigences d'une règle PGR.
|
||||||
|
|
||||||
|
SaseDev Knowledge est une destination possible pour les contenus pratiques, pas un upstream normatif. PGR MUST NOT dépendre de sa disponibilité.
|
||||||
|
|
||||||
|
Une extraction physique future exige une destination autoritaire explicitement fournie et vérifiée. `0.1.5-alpha.4` ne réalise aucune migration.
|
||||||
|
|
||||||
|
## Owners réconciliés
|
||||||
|
|
||||||
|
- `docs/objectives/001-PROJECT_OBJECTIVES.md` révision `2` : remplace « recette Markdown » par « spécification Markdown composable », ajoute l'auto-suffisance PGR et sépare les contenus pratiques externes ;
|
||||||
|
- `docs/architecture/002-GOVERNANCE_ARCHITECTURE.md` révision `5` : clarifie la nature du skeleton et formalise la frontière architecturale avec les contenus pratiques externes ;
|
||||||
|
- `docs/rules/300-DOCUMENTATION.md` révision `5` : devient l'owner documentaire de la taxonomie normative/pratique, de l'auto-suffisance et du caractère non automatique d'une extraction future.
|
||||||
|
|
||||||
|
Aucun owner Knowledge supplémentaire n'est créé.
|
||||||
|
|
||||||
|
## Cohérence documentaire
|
||||||
|
|
||||||
|
- `README.md` présente `0.1.5-alpha.4` comme tranche active ;
|
||||||
|
- `docs/000-README.md` présente les trois owners comme réconciliés en `alpha.4` ;
|
||||||
|
- `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` passe en révision `4`, enregistre `alpha.3 PASS` et les décisions de mise en œuvre `alpha.4`.
|
||||||
|
|
||||||
|
`RULES.md`, `ROADMAP.md` et `CHANGELOG.md` restent inchangés. Les adoptions Games `0.1.6`, KSP `0.1.7` et les audits Rust/Clippy `0.1.8` restent hors scope.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Après commit/push de `alpha.3` avec son history `PASS`, appliquer ce delta puis exécuter :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/alpha.3.md
|
||||||
|
test -f deltas/0.1.5/alpha.4.md
|
||||||
|
test ! -e history/0.1.5/alpha.4.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-alpha.4' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.md | grep -Fx 'PARTIAL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.2.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.3.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/objectives/001-PROJECT_OBJECTIVES.md
|
||||||
|
grep -F 'spécifications Markdown composables' docs/objectives/001-PROJECT_OBJECTIVES.md
|
||||||
|
grep -F 'rester auto-suffisant pour comprendre et appliquer les contrats normatifs PGR' docs/objectives/001-PROJECT_OBJECTIVES.md
|
||||||
|
grep -F 'howtos détaillés, recettes pratiques, snippets, exemples d’intégration, dépannage, comparatifs et variantes d’implémentation vivent dans une base de connaissances séparée' docs/objectives/001-PROJECT_OBJECTIVES.md
|
||||||
|
! grep -F 'recettes Markdown composables' docs/objectives/001-PROJECT_OBJECTIVES.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -F 'Un skeleton est une spécification Markdown composable' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -F '## Frontière avec les contenus pratiques externes' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -F 'PGR doit rester auto-suffisant pour comprendre et appliquer ses contrats normatifs' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -F 'SaseDev Knowledge est une destination possible' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
grep -F "MUST NOT dépendre d'un dépôt Knowledge" docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
! grep -F 'Un skeleton est une recette Markdown' docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F '## Frontière normative et pratique' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F 'SaseDev Knowledge MAY jouer ce rôle, sans devenir un owner normatif de PGR' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F 'PGR MUST rester auto-suffisant' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F "MUST NOT être requis pour déterminer la force, le scope ou les exigences d'une règle PGR" docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F 'Classifier un contenu comme pratique ne crée pas une obligation de déplacement' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F 'MUST NOT créer de dépendance de PGR vers SaseDev Knowledge' docs/rules/300-DOCUMENTATION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 4 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'La gate opérateur de `alpha.3` du `2026-10-01` est `PASS`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Décisions de mise en œuvre `alpha.4`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'ne créer aucun nouvel owner Knowledge' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 16 -->' RULES.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/230-ADOPTION.md
|
||||||
|
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md'}; print('0.1.5 alpha.4 history boundary: clean (107 closed prior pairs, current alpha.4 pending)')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
git diff --exit-code -- RULES.md ROADMAP.md CHANGELOG.md docs/rules/210-WORKFLOW.md docs/rules/230-ADOPTION.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 status --short
|
||||||
|
|
||||||
|
git add VERSION README.md docs/000-README.md \
|
||||||
|
docs/objectives/001-PROJECT_OBJECTIVES.md \
|
||||||
|
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
|
||||||
|
docs/rules/300-DOCUMENTATION.md \
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md \
|
||||||
|
deltas/0.1.5/alpha.4.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.5/alpha.4.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/architecture/002-GOVERNANCE_ARCHITECTURE.md
|
||||||
|
M docs/objectives/001-PROJECT_OBJECTIVES.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
M docs/rules/300-DOCUMENTATION.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Revue opérateur attendue
|
||||||
|
|
||||||
|
La revue doit confirmer que la frontière est sémantique et non une dépendance entre dépôts : PGR reste utilisable seul, Knowledge reste une destination pratique possible, aucun contenu n'est déplacé et aucun owner externe n'est requis pour interpréter une règle.
|
||||||
|
|
||||||
|
Elle doit aussi confirmer que la tranche ne modifie pas les contrats d'autonomie acquis en `alpha.3` et ne commence pas les adoptions Games/KSP.
|
||||||
169
deltas/0.1.5/beta.1.md
Normal file
169
deltas/0.1.5/beta.1.md
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
<!-- file: deltas/0.1.5/beta.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-beta.1 — réconciliation transversale
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Fermer la phase alpha de `0.1.5` en réconciliant transversalement les trois contrats acquis : sémantique `MUST / SHOULD / MAY`, autonomie de la baseline locale et frontière PGR / SaseDev Knowledge.
|
||||||
|
|
||||||
|
Le rescan préparatoire ne démontre aucun nouveau défaut normatif nécessitant une correction. `beta.1` est donc une tranche d'intégration et de preuve : elle documente les décisions de `KEEP`, rejoue les validations complètes et conserve les scopes futurs hors de la release courante.
|
||||||
|
|
||||||
|
## Préconditions
|
||||||
|
|
||||||
|
Le history `history/0.1.5/alpha.4.md` doit être présent avec statut `PASS` avant application de ce delta.
|
||||||
|
|
||||||
|
La séquence acquise doit rester :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PARTIAL
|
||||||
|
alpha.1.fix.1 PASS
|
||||||
|
alpha.2 PASS
|
||||||
|
alpha.3 PASS
|
||||||
|
alpha.4 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Les histories antérieurs ne sont pas réécrits.
|
||||||
|
|
||||||
|
## Réconciliation `SHOULD / SHOULD NOT`
|
||||||
|
|
||||||
|
Le rescan relit les owners vivants où une recommandation cohabite avec un `MUST`, une justification ou une contrainte conditionnelle.
|
||||||
|
|
||||||
|
Les clauses conservées ne renforcent pas le simple écart à `SHOULD / SHOULD NOT` : elles portent une propriété distincte de sécurité, identité, hygiène d'output ou maintenabilité. Les corrections ciblées d'`alpha.2` restent donc suffisantes et aucun owner normatif supplémentaire n'est modifié en `beta.1`.
|
||||||
|
|
||||||
|
Les contrats centraux restent :
|
||||||
|
|
||||||
|
```text
|
||||||
|
SHOULD / SHOULD NOT
|
||||||
|
forte recommandation non obligatoire
|
||||||
|
écart seul != non-conformité
|
||||||
|
écart seul != FAIL de gate
|
||||||
|
écart seul != OVERRIDE obligatoire
|
||||||
|
justification MAY être documentée si elle apporte une valeur durable
|
||||||
|
```
|
||||||
|
|
||||||
|
## Autonomie et snapshots
|
||||||
|
|
||||||
|
La réconciliation confirme que :
|
||||||
|
|
||||||
|
- la baseline locale et ses owners sont l'autorité des sessions/releases suivantes après instanciation/adoption ;
|
||||||
|
- PGR n'est pas un upstream documentaire implicite ;
|
||||||
|
- aucun mécanisme ne recherche automatiquement « la dernière version de PGR » ;
|
||||||
|
- un réalignement futur est une opération explicite et bornée, fondée sur un snapshot PGR choisi ;
|
||||||
|
- `210-WORKFLOW.md` et `003-NEW_SESSION_PROMPT.md` restent `KEEP`.
|
||||||
|
|
||||||
|
## Frontière PGR / Knowledge
|
||||||
|
|
||||||
|
PGR reste auto-suffisant pour déterminer la force, le scope et les exigences de ses règles. SaseDev Knowledge MAY accueillir des contenus pratiques complémentaires, mais ne devient ni owner normatif, ni source requise, ni dépendance de PGR.
|
||||||
|
|
||||||
|
Aucune migration physique n'est réalisée en `beta.1`.
|
||||||
|
|
||||||
|
## Trajectoire réconciliée
|
||||||
|
|
||||||
|
La référence vivante Games dans `540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` reste corrigée vers `0.1.6`.
|
||||||
|
|
||||||
|
Les références historiques qui décrivent un ancien horizon restent inchangées lorsqu'elles sont exactes dans leur contexte.
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.6 adoption sasedev-games RESERVED
|
||||||
|
0.1.7 adoption KSP RESERVED
|
||||||
|
0.1.8 audits Rust/Clippy RESERVED
|
||||||
|
0.1.9 NOT RESERVED
|
||||||
|
```
|
||||||
|
|
||||||
|
`beta.1` ne commence aucun de ces scopes.
|
||||||
|
|
||||||
|
## Modifications
|
||||||
|
|
||||||
|
- `VERSION` passe à `0.1.5-beta.1` ;
|
||||||
|
- `README.md` passe en révision `32` et présente la réconciliation bêta ;
|
||||||
|
- `docs/000-README.md` passe en révision `51` et indexe `beta.1` ;
|
||||||
|
- `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` passe en révision `5`, enregistre `alpha.4 PASS` et les résultats du rescan préparatoire ;
|
||||||
|
- aucun owner normatif, skeleton, template, validation, study ou history antérieur n'est modifié.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Après commit/push de `alpha.4` avec son history `PASS`, appliquer ce delta puis exécuter :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/alpha.4.md
|
||||||
|
test -f deltas/0.1.5/beta.1.md
|
||||||
|
test ! -e history/0.1.5/beta.1.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-beta.1' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.md | grep -Fx 'PARTIAL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.2.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.3.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.4.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 16 -->' RULES.md
|
||||||
|
grep -F 'forte recommandation non obligatoire' RULES.md
|
||||||
|
grep -F "n'exige pas automatiquement un \`OVERRIDE\`" RULES.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'MUST NOT rechercher automatiquement « la dernière version de PGR »' docs/rules/230-ADOPTION.md
|
||||||
|
grep -F 'identifier le snapshot PGR choisi' docs/rules/230-ADOPTION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/400-VALIDATION.md
|
||||||
|
grep -F 'MUST NOT faire passer une tranche en `FAIL`' docs/rules/400-VALIDATION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F 'PGR MUST rester auto-suffisant' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -F 'SaseDev Knowledge MAY jouer ce rôle, sans devenir un owner normatif de PGR' docs/rules/300-DOCUMENTATION.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/templates/003-NEW_SESSION_PROMPT.md
|
||||||
|
|
||||||
|
grep -F "Lors de l'adoption \`0.1.6\`" docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
! grep -F "Lors de l'adoption \`0.1.5\`" docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'La gate opérateur de `alpha.4` du `2026-10-01` est `PASS`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Réconciliation transversale préparée en `beta.1`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'KEEP des owners normatifs acquis' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md','beta.1.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md'}; print('0.1.5 beta.1 history boundary: clean (108 closed prior pairs, current beta.1 pending)')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
git diff --exit-code -- RULES.md ROADMAP.md CHANGELOG.md docs/objectives/001-PROJECT_OBJECTIVES.md docs/architecture/002-GOVERNANCE_ARCHITECTURE.md docs/rules/210-WORKFLOW.md docs/rules/220-SKELETONS.md docs/rules/230-ADOPTION.md docs/rules/300-DOCUMENTATION.md docs/rules/400-VALIDATION.md docs/rules/500-LANGUAGES.md docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md docs/rules/700-FRAMEWORKS.md docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md docs/skeletons/003-WEB_FRONTEND.md docs/templates/003-NEW_SESSION_PROMPT.md docs/templates/007-EXISTING_PROJECT_ADOPTION.md docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py README.md RULES.md ROADMAP.md CHANGELOG.md VERSION 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 status --short
|
||||||
|
|
||||||
|
git add VERSION README.md docs/000-README.md docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md deltas/0.1.5/beta.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scope Git attendu
|
||||||
|
|
||||||
|
```text
|
||||||
|
M README.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.1.5/beta.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Suite
|
||||||
|
|
||||||
|
Si la gate est `PASS`, produire `history/0.1.5/beta.1.md`, committer/pousser la tranche puis préparer `rc.1` : freeze des contrats stabilisés, présentation candidate, revue d'horizon bornée et préparation du handoff `0.1.6` uniquement si la trajectoire reste valide.
|
||||||
165
deltas/0.1.5/rc.1.fix.1.md
Normal file
165
deltas/0.1.5/rc.1.fix.1.md
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
<!-- file: deltas/0.1.5/rc.1.fix.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-rc.1.fix.1 — alignement des assertions documentaires RC
|
||||||
|
|
||||||
|
## Diagnostic
|
||||||
|
|
||||||
|
La gate opérateur de `0.1.5-rc.1` a validé le freeze fonctionnel, les `55/55` tests Python, les audits d'hygiène/Markdown et le scope Git, mais trois assertions exactes prévues par `rc.1` n'ont produit aucune correspondance :
|
||||||
|
|
||||||
|
```text
|
||||||
|
grep -F 'forte recommandation non obligatoire' CHANGELOG.md
|
||||||
|
grep -F 'aucun numéro de version Games n’est figé' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
```
|
||||||
|
|
||||||
|
`history/0.1.5/rc.1.md` enregistre donc `FAIL`.
|
||||||
|
|
||||||
|
Le diagnostic est strictement documentaire : les contrats normatifs, la décision d'horizon, le prompt `012` et les validations techniques restent acquis.
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Aligner les formulations de présentation avec les chaînes canoniques exigées par la gate RC sans rouvrir aucun owner normatif et sans commencer `rel.1` ou `0.1.6`.
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.5-rc.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.1.5/rc.1.fix.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
`README.md`, `ROADMAP.md`, `docs/000-README.md`, le prompt `012`, tous les owners normatifs, skeletons, templates, validations et histories antérieurs MUST rester inchangés.
|
||||||
|
|
||||||
|
## Corrections
|
||||||
|
|
||||||
|
`CHANGELOG.md` passe en révision `21` et emploie la formulation canonique `forte recommandation non obligatoire` pour `SHOULD / SHOULD NOT`.
|
||||||
|
|
||||||
|
`docs/studies/005-V0_1_5_HORIZON_REVIEW.md` passe en révision `2` et :
|
||||||
|
|
||||||
|
- contient explicitement la sous-chaîne `aucun numéro de version Games n’est figé` ;
|
||||||
|
- expose explicitement la classification canonique `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A` avant son détail ligne par ligne.
|
||||||
|
|
||||||
|
`docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` passe en révision `7` et conserve la vérité opérateur `rc.1 FAIL` ainsi que le scope borné du présent fix.
|
||||||
|
|
||||||
|
Aucune décision d'horizon n'est modifiée.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Après commit/push de `rc.1` avec son history `FAIL`, appliquer ce delta puis exécuter :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/rc.1.md
|
||||||
|
test -f deltas/0.1.5/rc.1.fix.1.md
|
||||||
|
test ! -e history/0.1.5/rc.1.fix.1.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-rc.1.fix.1' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/rc.1.md | grep -Fx 'FAIL'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 21 -->' CHANGELOG.md
|
||||||
|
grep -F 'forte recommandation non obligatoire' CHANGELOG.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'aucun numéro de version Games n’est figé' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'conserver `0.1.6` comme prochaine release' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'Aucun `0.1.9` n’est réservé' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 7 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Gate `rc.1` en échec documentaire et correctif `rc.1.fix.1`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'history/0.1.5/rc.1.md` enregistre donc le résultat réel `FAIL`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '`rel.1` reste bloqué tant que `rc.1.fix.1` n’est pas validé `PASS`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 33 -->' README.md
|
||||||
|
grep -Fx '<!-- version: 18 -->' ROADMAP.md
|
||||||
|
grep -Fx '<!-- version: 52 -->' docs/000-README.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 16 -->' RULES.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/230-ADOPTION.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/400-VALIDATION.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md','beta.1.md','rc.1.md','rc.1.fix.1.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md','beta.1.md','rc.1.md'}; print('0.1.5 rc.1.fix.1 history boundary: clean (110 closed prior pairs, current rc.1.fix.1 pending)')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
|
||||||
|
git diff --exit-code -- README.md ROADMAP.md docs/000-README.md \
|
||||||
|
prompts/012-V0_1_6_START_PROMPT.md RULES.md \
|
||||||
|
docs/objectives/001-PROJECT_OBJECTIVES.md \
|
||||||
|
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
|
||||||
|
docs/rules/210-WORKFLOW.md docs/rules/220-SKELETONS.md \
|
||||||
|
docs/rules/230-ADOPTION.md docs/rules/300-DOCUMENTATION.md \
|
||||||
|
docs/rules/400-VALIDATION.md docs/rules/500-LANGUAGES.md \
|
||||||
|
docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md \
|
||||||
|
docs/rules/700-FRAMEWORKS.md \
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||||
|
docs/skeletons/003-WEB_FRONTEND.md \
|
||||||
|
docs/templates/003-NEW_SESSION_PROMPT.md \
|
||||||
|
docs/templates/007-EXISTING_PROJECT_ADOPTION.md \
|
||||||
|
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 status --short
|
||||||
|
|
||||||
|
git add VERSION CHANGELOG.md \
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md \
|
||||||
|
docs/studies/005-V0_1_5_HORIZON_REVIEW.md \
|
||||||
|
deltas/0.1.5/rc.1.fix.1.md
|
||||||
|
|
||||||
|
git diff --cached --check
|
||||||
|
git status --short
|
||||||
|
```
|
||||||
|
|
||||||
|
## Scope Git attendu
|
||||||
|
|
||||||
|
```text
|
||||||
|
M CHANGELOG.md
|
||||||
|
M VERSION
|
||||||
|
A deltas/0.1.5/rc.1.fix.1.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
M docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
### PASS
|
||||||
|
|
||||||
|
Produire `history/0.1.5/rc.1.fix.1.md`, committer/pousser `0.1.5-rc.1.fix.1`, puis préparer `rel.1` comme promotion stable mécanique sans nouveau scope.
|
||||||
|
|
||||||
|
### FAIL
|
||||||
|
|
||||||
|
Enregistrer le résultat réel dans `history/0.1.5/rc.1.fix.1.md` et poursuivre sous `rc.1.fix.N`. Ne pas commencer `rel.1` tant que le correctif RC n'est pas `PASS`.
|
||||||
207
deltas/0.1.5/rc.1.md
Normal file
207
deltas/0.1.5/rc.1.md
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
<!-- file: deltas/0.1.5/rc.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5-rc.1 — freeze, revue d’horizon et handoff Games
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
Geler les trois contrats transversaux réconciliés par `beta.1`, préparer la présentation candidate de `0.1.5`, effectuer la revue d’horizon limitée prévue par le plan et préparer le handoff vers `0.1.6` uniquement puisque l’adoption Games reste la prochaine dépendance réelle.
|
||||||
|
|
||||||
|
La RC n’ajoute aucun nouveau contrat normatif et ne commence aucune adoption.
|
||||||
|
|
||||||
|
## Préconditions
|
||||||
|
|
||||||
|
Le history `history/0.1.5/beta.1.md` doit être présent avec statut `PASS` avant application de ce delta.
|
||||||
|
|
||||||
|
La séquence réelle doit rester :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PARTIAL
|
||||||
|
alpha.1.fix.1 PASS
|
||||||
|
alpha.2 PASS
|
||||||
|
alpha.3 PASS
|
||||||
|
alpha.4 PASS
|
||||||
|
beta.1 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Les owners stabilisés pendant `alpha.2` à `alpha.4` sont gelés sauf défaut démontré. Aucun défaut nouveau n’est introduit par la préparation RC.
|
||||||
|
|
||||||
|
## Revue d’horizon
|
||||||
|
|
||||||
|
`docs/studies/005-V0_1_5_HORIZON_REVIEW.md` confirme qu’aucun nouveau prérequis transversal ne doit précéder l’adoption réelle de `sasedev-games`.
|
||||||
|
|
||||||
|
La trajectoire reste :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.6 adoption sasedev-games
|
||||||
|
0.1.7 adoption khadhroony-solana-project
|
||||||
|
0.1.8 audits Rust/Clippy read-only
|
||||||
|
0.1.9 NOT RESERVED
|
||||||
|
```
|
||||||
|
|
||||||
|
La revue impose pour `0.1.6` une stable PGR `v0.1.5` réellement publiée/vérifiée et une archive Games récente explicitement autoritaire. Elle ne fige volontairement aucun numéro Games.
|
||||||
|
|
||||||
|
## Handoff 0.1.6
|
||||||
|
|
||||||
|
`prompts/012-V0_1_6_START_PROMPT.md` prépare `0.1.6-alpha.1` comme tranche d’intake et de cartographie avant migration.
|
||||||
|
|
||||||
|
Le prompt exige une classification `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A`, conserve la sémantique non obligatoire de `SHOULD / SHOULD NOT`, préserve les décisions locales Games et rappelle que la baseline Games devient l’autorité du projet après adoption.
|
||||||
|
|
||||||
|
Il interdit de généraliser automatiquement un ancien POC ou artefact historique sans applicabilité démontrée par le corpus Games fourni.
|
||||||
|
|
||||||
|
## Modifications
|
||||||
|
|
||||||
|
- `VERSION` passe à `0.1.5-rc.1` ;
|
||||||
|
- `README.md` passe en révision `33` et présente la candidate/freeze ;
|
||||||
|
- `CHANGELOG.md` passe en révision `20` et reçoit l’entrée `0.1.5 (candidate)` sans chronologie de tranches ;
|
||||||
|
- `ROADMAP.md` passe en révision `18` et enregistre la confirmation de trajectoire issue de la revue `0.1.5-rc.1` ;
|
||||||
|
- `docs/000-README.md` passe en révision `52` et indexe la revue d’horizon et le handoff `012` ;
|
||||||
|
- `docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md` passe en révision `6`, enregistre `beta.1 PASS` et le freeze RC ;
|
||||||
|
- `docs/studies/000-README.md` passe en révision `6` ;
|
||||||
|
- `docs/studies/005-V0_1_5_HORIZON_REVIEW.md` est créé ;
|
||||||
|
- `prompts/012-V0_1_6_START_PROMPT.md` est créé ;
|
||||||
|
- aucun owner normatif, skeleton, template ou contrat de validation stabilisé par les alphas n’est modifié.
|
||||||
|
|
||||||
|
## Gate opérateur
|
||||||
|
|
||||||
|
Après commit/push de `beta.1` avec son history `PASS`, appliquer ce delta puis exécuter :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/beta.1.md
|
||||||
|
test -f deltas/0.1.5/rc.1.md
|
||||||
|
test -f docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
test -f prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
test ! -e history/0.1.5/rc.1.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5-rc.1' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.md | grep -Fx 'PARTIAL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.1.fix.1.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.2.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.3.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/alpha.4.md | grep -Fx 'PASS'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/beta.1.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 33 -->' README.md
|
||||||
|
grep -F 'candidate `0.1.5-rc.1`' README.md
|
||||||
|
grep -F '`0.1.6` reste la prochaine release' README.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 20 -->' CHANGELOG.md
|
||||||
|
grep -Fx '## 0.1.5 (candidate)' CHANGELOG.md
|
||||||
|
grep -F 'forte recommandation non obligatoire' CHANGELOG.md
|
||||||
|
grep -F 'baseline locale et ses owners deviennent l’autorité' CHANGELOG.md
|
||||||
|
grep -F 'SaseDev Knowledge' CHANGELOG.md
|
||||||
|
grep -F 'adoption réelle de `sasedev-games` reste la cible `0.1.6`' CHANGELOG.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; s=Path('CHANGELOG.md').read_text(encoding='utf-8').split('## 0.1.5 (candidate)',1)[1].split('## 0.1.4',1)[0]; assert all(x not in s for x in ('alpha.1','alpha.2','alpha.3','alpha.4','beta.1','rc.1','rel.1')); print('0.1.5 candidate changelog: clean')"
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 18 -->' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.5`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
grep -F 'La revue limitée `0.1.5-rc.1` confirme' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 52 -->' docs/000-README.md
|
||||||
|
grep -F 'studies/005-V0_1_5_HORIZON_REVIEW.md' docs/000-README.md
|
||||||
|
grep -F 'prompts/012-V0_1_6_START_PROMPT.md' docs/000-README.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 6 -->' docs/studies/000-README.md
|
||||||
|
grep -F '005-V0_1_5_HORIZON_REVIEW.md' docs/studies/000-README.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 1 -->' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'conserver `0.1.6` comme prochaine release' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'aucun numéro de version Games n’est figé' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -F 'Aucun `0.1.9` n’est réservé' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 1 -->' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'tag Gitea `v0.1.5`' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'pgr-0.1.5-publish.001-report.md' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'archive récente et explicitement autoritaire de `sasedev-games`' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F '0.1.6-alpha.1' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'ne doivent pas rechercher automatiquement « la dernière version de PGR »' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'réservée à `0.1.7`' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
grep -F 'réservés à `0.1.8`' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 6 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'La gate opérateur de `beta.1` du `2026-10-01` est `PASS`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Freeze et revue d’horizon préparés en `rc.1`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '0.1.9 NOT RESERVED' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F '012-V0_1_6_START_PROMPT.md' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 16 -->' RULES.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/230-ADOPTION.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/400-VALIDATION.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; 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,'0.1.4':7}; assert all({p.name for p in Path('deltas',r).glob('*.md')} == {p.name for p in Path('history',r).glob('*.md')} and len(list(Path('deltas',r).glob('*.md'))) == n for r,n in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md','beta.1.md','rc.1.md'}; assert {p.name for p in Path('history/0.1.5').glob('*.md')} == {'alpha.1.md','alpha.1.fix.1.md','alpha.2.md','alpha.3.md','alpha.4.md','beta.1.md'}; print('0.1.5 rc.1 history boundary: clean (109 closed prior pairs, current rc.1 pending)')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
|
||||||
|
git diff --exit-code -- RULES.md \
|
||||||
|
docs/objectives/001-PROJECT_OBJECTIVES.md \
|
||||||
|
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md \
|
||||||
|
docs/rules/210-WORKFLOW.md docs/rules/220-SKELETONS.md \
|
||||||
|
docs/rules/230-ADOPTION.md docs/rules/300-DOCUMENTATION.md \
|
||||||
|
docs/rules/400-VALIDATION.md docs/rules/500-LANGUAGES.md \
|
||||||
|
docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md \
|
||||||
|
docs/rules/700-FRAMEWORKS.md \
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md \
|
||||||
|
docs/skeletons/003-WEB_FRONTEND.md \
|
||||||
|
docs/templates/003-NEW_SESSION_PROMPT.md \
|
||||||
|
docs/templates/007-EXISTING_PROJECT_ADOPTION.md \
|
||||||
|
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md
|
||||||
|
|
||||||
|
python3 -B -m unittest discover -s tests -v
|
||||||
|
|
||||||
|
python3 -B scripts/audit_text_hygiene.py \
|
||||||
|
README.md RULES.md ROADMAP.md CHANGELOG.md VERSION \
|
||||||
|
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 status --short
|
||||||
|
|
||||||
|
git add VERSION README.md CHANGELOG.md ROADMAP.md \
|
||||||
|
deltas/0.1.5/rc.1.md \
|
||||||
|
docs/000-README.md \
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md \
|
||||||
|
docs/studies/000-README.md \
|
||||||
|
docs/studies/005-V0_1_5_HORIZON_REVIEW.md \
|
||||||
|
prompts/012-V0_1_6_START_PROMPT.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.5/rc.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
M docs/studies/000-README.md
|
||||||
|
A docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
A prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
Si la gate est `PASS`, produire `history/0.1.5/rc.1.md`, committer/pousser `0.1.5-rc.1`, puis préparer `rel.1` comme promotion mécanique vers la stable `0.1.5`, sans rouvrir les contrats acquis ni commencer `0.1.6`.
|
||||||
156
deltas/0.1.5/rel.1.md
Normal file
156
deltas/0.1.5/rel.1.md
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
<!-- file: deltas/0.1.5/rel.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.5 rel.1 — promotion stable pré-tag
|
||||||
|
|
||||||
|
## Baseline et version
|
||||||
|
|
||||||
|
Baseline : `0.1.5-rc.1.fix.1`, avec `history/0.1.5/rc.1.fix.1.md` appliqué et committé. Ce delta MUST NOT être appliqué avant ce commit.
|
||||||
|
|
||||||
|
Version avant application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.5-rc.1.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
Version après application :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.5
|
||||||
|
```
|
||||||
|
|
||||||
|
`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 corrigée vers la stable `0.1.5` sans rouvrir les trois contrats stabilisés et sans commencer `0.1.6`.
|
||||||
|
|
||||||
|
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 `011` historique.
|
||||||
|
|
||||||
|
Aucun owner normatif, skeleton, template, audit Python, étude d'horizon ou prompt de reprise n'est modifié par `rel.1`.
|
||||||
|
|
||||||
|
La validation de cette tranche est **pré-tag**. Le tag `v0.1.5`, son archive source Gitea et le rapport `pgr-0.1.5-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.5` et la publication réelle du tag.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
REPLACE :
|
||||||
|
|
||||||
|
```text
|
||||||
|
VERSION
|
||||||
|
README.md
|
||||||
|
ROADMAP.md
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/000-README.md
|
||||||
|
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
ADD :
|
||||||
|
|
||||||
|
```text
|
||||||
|
deltas/0.1.5/rel.1.md
|
||||||
|
```
|
||||||
|
|
||||||
|
DELETE : aucun.
|
||||||
|
|
||||||
|
Le history `rc.1.fix.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.5/rc.1.fix.1.md` :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cat VERSION
|
||||||
|
|
||||||
|
test -f history/0.1.5/rc.1.fix.1.md
|
||||||
|
test -f deltas/0.1.5/rel.1.md
|
||||||
|
test -f prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
test -f docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
test ! -e history/0.1.5/rel.1.md
|
||||||
|
|
||||||
|
grep -Fx '0.1.5' VERSION
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/rc.1.md | grep -Fx 'FAIL'
|
||||||
|
grep -A2 '^## Statut$' history/0.1.5/rc.1.fix.1.md | grep -Fx 'PASS'
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 34 -->' README.md
|
||||||
|
grep -F 'La stable autoritaire courante est `0.1.5`' README.md
|
||||||
|
grep -F 'La release `0.1.5` stabilise la sémantique `MUST / SHOULD / MAY`' README.md
|
||||||
|
grep -F 'plan historique de la stable `0.1.5`' README.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 22 -->' CHANGELOG.md
|
||||||
|
grep -Fx '## 0.1.5' CHANGELOG.md
|
||||||
|
! grep -Fx '## 0.1.5 (candidate)' CHANGELOG.md
|
||||||
|
grep -F 'forte recommandation non obligatoire' CHANGELOG.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 19 -->' ROADMAP.md
|
||||||
|
grep -F -- '- `(x) 0.1.5`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.6`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.7`' ROADMAP.md
|
||||||
|
grep -F -- '- `( ) 0.1.8`' ROADMAP.md
|
||||||
|
! grep -F -- '- `( ) 0.1.9`' ROADMAP.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 53 -->' docs/000-README.md
|
||||||
|
grep -F 'plan historique de la stable `0.1.5`' docs/000-README.md
|
||||||
|
grep -F 'prompts/012-V0_1_6_START_PROMPT.md' docs/000-README.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 8 -->' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Gate `rc.1.fix.1` acquise et promotion stable' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'Le plan devient historique avec la stable `0.1.5`' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
grep -F 'pgr-0.1.5-publish.001-report.md' docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
|
||||||
|
grep -Fx '<!-- version: 16 -->' RULES.md
|
||||||
|
grep -Fx '<!-- version: 9 -->' docs/rules/210-WORKFLOW.md
|
||||||
|
grep -Fx '<!-- version: 3 -->' docs/rules/230-ADOPTION.md
|
||||||
|
grep -Fx '<!-- version: 5 -->' docs/rules/300-DOCUMENTATION.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/rules/400-VALIDATION.md
|
||||||
|
grep -Fx '<!-- version: 2 -->' docs/studies/005-V0_1_5_HORIZON_REVIEW.md
|
||||||
|
grep -Fx '<!-- version: 1 -->' prompts/012-V0_1_6_START_PROMPT.md
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; import re; expected={'alpha.1.md':'PARTIAL','alpha.1.fix.1.md':'PASS','alpha.2.md':'PASS','alpha.3.md':'PASS','alpha.4.md':'PASS','beta.1.md':'PASS','rc.1.md':'FAIL','rc.1.fix.1.md':'PASS'}; assert all(Path('deltas/0.1.5',n).is_file() and Path('history/0.1.5',n).is_file() and re.search(rf'## Statut\s+{st}\s',Path('history/0.1.5',n).read_text(encoding='utf-8')) for n,st in expected.items()); assert {p.name for p in Path('deltas/0.1.5').glob('*.md')} - {p.name for p in Path('history/0.1.5').glob('*.md')} == {'rel.1.md'}; print('0.1.5 rel.1 stable gate audit: clean (8 prior histories including alpha.1 PARTIAL and rc.1 FAIL/fix PASS, rel.1 pending)')"
|
||||||
|
|
||||||
|
python3 -B -c "from pathlib import Path; s=Path('CHANGELOG.md').read_text(encoding='utf-8').split('## 0.1.5',1)[1].split('## 0.1.4',1)[0]; assert all(x not in s for x in ('alpha.1','alpha.2','alpha.3','alpha.4','beta.1','rc.1','rc.1.fix.1','rel.1')); print('0.1.5 stable changelog: clean')"
|
||||||
|
|
||||||
|
git diff --exit-code -- history/0.1.4
|
||||||
|
|
||||||
|
git diff --exit-code -- RULES.md docs/objectives/001-PROJECT_OBJECTIVES.md docs/architecture/002-GOVERNANCE_ARCHITECTURE.md docs/rules/210-WORKFLOW.md docs/rules/220-SKELETONS.md docs/rules/230-ADOPTION.md docs/rules/300-DOCUMENTATION.md docs/rules/400-VALIDATION.md docs/rules/500-LANGUAGES.md docs/rules/530-TYPESCRIPT.md docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md docs/rules/700-FRAMEWORKS.md docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md docs/skeletons/003-WEB_FRONTEND.md docs/templates/003-NEW_SESSION_PROMPT.md docs/templates/007-EXISTING_PROJECT_ADOPTION.md docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md docs/studies/005-V0_1_5_HORIZON_REVIEW.md prompts/012-V0_1_6_START_PROMPT.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
|
||||||
|
|
||||||
|
git diff --check
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
git add VERSION README.md ROADMAP.md CHANGELOG.md deltas/0.1.5/rel.1.md docs/000-README.md docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_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.5/rel.1.md
|
||||||
|
M docs/000-README.md
|
||||||
|
M docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Transition après PASS
|
||||||
|
|
||||||
|
Si cette gate pré-tag est `PASS` :
|
||||||
|
|
||||||
|
1. produire `history/0.1.5/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.5`** sans suffixe `rel.1` ;
|
||||||
|
4. pousser `master` ;
|
||||||
|
5. vérifier un workspace propre ;
|
||||||
|
6. créer et pousser le tag annoté `v0.1.5` ;
|
||||||
|
7. télécharger l'archive Gitea du tag et produire `pgr-0.1.5-publish.001-report.md` après vérification indépendante ;
|
||||||
|
8. seulement après `publish.001 PASS`, ouvrir `0.1.6` avec `prompts/012-V0_1_6_START_PROMPT.md` et une archive Games récente explicitement autoritaire.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/000-README.md -->
|
<!-- file: docs/000-README.md -->
|
||||||
<!-- version: 4 -->
|
<!-- version: 53 -->
|
||||||
|
|
||||||
# Documentation PGR
|
# Documentation PGR
|
||||||
|
|
||||||
@@ -10,7 +10,9 @@ Ce fichier est l'index d'entrée de la documentation structurée de Project Gove
|
|||||||
- [`objectives/`](objectives/) — mission, objectifs durables, non-objectifs et contraintes globales ;
|
- [`objectives/`](objectives/) — mission, objectifs durables, non-objectifs et contraintes globales ;
|
||||||
- [`architecture/`](architecture/) — état architectural courant de PGR et profils applicables ;
|
- [`architecture/`](architecture/) — état architectural courant de PGR et profils applicables ;
|
||||||
- [`plans/`](plans/) — plans vivants des releases en cours, puis références historiques après fermeture ;
|
- [`plans/`](plans/) — plans vivants des releases en cours, puis références historiques après fermeture ;
|
||||||
|
- [`studies/`](studies/) — études bornées utilisées pour comparer des corpus, instruire une décision ou conserver une analyse avant normalisation ;
|
||||||
- [`rules/`](rules/) — règles normatives détaillées, organisées progressivement par scope ;
|
- [`rules/`](rules/) — règles normatives détaillées, organisées progressivement par scope ;
|
||||||
|
- [`skeletons/`](skeletons/) — spécifications Markdown de composition et d'initialisation de projets ;
|
||||||
- [`templates/`](templates/) — instructions d'adaptation des templates techniques et spécification du message manuel de reprise ;
|
- [`templates/`](templates/) — instructions d'adaptation des templates techniques et spécification du message manuel de reprise ;
|
||||||
- [`validation/`](validation/) — matrices de validation et contrats de preuve.
|
- [`validation/`](validation/) — matrices de validation et contrats de preuve.
|
||||||
|
|
||||||
@@ -18,9 +20,92 @@ 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.
|
Les templates techniques copiables sous `templates/` restent séparés des instructions documentaires sous `docs/templates/`. Les répertoires workflow de racine (`deltas/`, `history/`, `handoffs/`, `manifests/`, `prompts/`, `scripts/`) restent séparés de `docs/` parce qu'ils portent le processus de développement et de livraison lui-même.
|
||||||
|
|
||||||
## Points d'entrée de 0.0.3
|
## Points d'entrée de 0.1.5
|
||||||
|
|
||||||
|
- [`plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md`](plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md) — plan historique de la stable `0.1.5` : sémantique normative, autonomie locale, frontière PGR / Knowledge, réconciliation, correctif RC documentaire et handoff vers `0.1.6`.
|
||||||
|
- [`studies/004-V0_1_4_HORIZON_REVIEW.md`](studies/004-V0_1_4_HORIZON_REVIEW.md) — décision autoritaire de fermeture `0.1.4` qui place la release de gouvernance/autonomie avant les adoptions Games/KSP.
|
||||||
|
- [`../RULES.md`](../RULES.md), [`rules/230-ADOPTION.md`](rules/230-ADOPTION.md) et [`rules/400-VALIDATION.md`](rules/400-VALIDATION.md) — owners primaires réconciliés en `alpha.2` : `SHOULD / SHOULD NOT` est une forte recommandation non obligatoire, sans `FAIL` de gate ni `OVERRIDE` automatique pour un simple écart.
|
||||||
|
- [`rules/220-SKELETONS.md`](rules/220-SKELETONS.md), [`rules/230-ADOPTION.md`](rules/230-ADOPTION.md), [`skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md`](skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md) et [`templates/007-EXISTING_PROJECT_ADOPTION.md`](templates/007-EXISTING_PROJECT_ADOPTION.md) — owners réconciliés en `alpha.3` : baseline locale autoritaire, absence d'upstream PGR implicite et réalignement volontaire fondé sur un snapshot choisi.
|
||||||
|
- [`objectives/001-PROJECT_OBJECTIVES.md`](objectives/001-PROJECT_OBJECTIVES.md), [`architecture/002-GOVERNANCE_ARCHITECTURE.md`](architecture/002-GOVERNANCE_ARCHITECTURE.md) et [`rules/300-DOCUMENTATION.md`](rules/300-DOCUMENTATION.md) — owners réconciliés en `alpha.4` : PGR reste auto-suffisant pour ses contrats normatifs ; les contenus pratiques externes restent complémentaires, sans dépendance PGR vers Knowledge ni déplacement automatique.
|
||||||
|
- `beta.1` réconcilie les trois contrats sans nouvel owner normatif : les renforcements `SHOULD` connus restent corrigés, `210-WORKFLOW.md` et `003-NEW_SESSION_PROMPT.md` restent compatibles avec l’autonomie locale, et les références vivantes Games/KSP/audits restent respectivement réservées à `0.1.6`, `0.1.7` et `0.1.8`.
|
||||||
|
- [`studies/005-V0_1_5_HORIZON_REVIEW.md`](studies/005-V0_1_5_HORIZON_REVIEW.md) — revue limitée `rc.1` confirmant que l’adoption Games `0.1.6` reste la prochaine dépendance réelle sans nouveau prérequis transversal ni réservation de `0.1.9`.
|
||||||
|
- [`../prompts/012-V0_1_6_START_PROMPT.md`](../prompts/012-V0_1_6_START_PROMPT.md) — handoff préparé vers l’adoption réelle de `sasedev-games` en `0.1.6-alpha.1`, à utiliser uniquement après publication et vérification post-tag de `v0.1.5` avec un corpus Games autoritaire explicitement fourni.
|
||||||
|
- [`../prompts/011-V0_1_5_START_PROMPT.md`](../prompts/011-V0_1_5_START_PROMPT.md) — contrat de reprise exécuté pour ouvrir `0.1.5-alpha.1` à partir de la stable `v0.1.4` vérifiée.
|
||||||
|
|
||||||
|
## 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` ;
|
||||||
|
- [`studies/001-KSP_GAMES_RECONCILIATION.md`](studies/001-KSP_GAMES_RECONCILIATION.md) — inventaire comparatif des baselines KSP/Games et décisions de généralisation, maintien local ou différé.
|
||||||
|
- [`studies/002-TAURI_SKELETON_DECISION.md`](studies/002-TAURI_SKELETON_DECISION.md) — décision `alpha.9` sur la maturité du skeleton Tauri contrôlé et ses prérequis Web encore manquants.
|
||||||
|
- [`templates/004-FILE_FAMILY_CONTRACTS.md`](templates/004-FILE_FAMILY_CONTRACTS.md) — pattern facultatif pour expliciter les responsabilités et règles de modification de familles de fichiers locales lorsque la complexité le justifie.
|
||||||
|
- [`templates/005-RELEASE_PLAN.md`](templates/005-RELEASE_PLAN.md) — pattern de plan de release avec clôture/transition explicites et revue d'horizon proportionnée.
|
||||||
|
- [`validation/002-RUST_STYLE_AUDITS.md`](validation/002-RUST_STYLE_AUDITS.md) et [`validation/003-RUST_EXPORT_COMPLETENESS.md`](validation/003-RUST_EXPORT_COMPLETENESS.md) — contrats et limites des audits Rust monotâches réconciliés depuis les corpus réels.
|
||||||
|
- [`rules/700-FRAMEWORKS.md`](rules/700-FRAMEWORKS.md) et [`rules/710-TAURI.md`](rules/710-TAURI.md) — activation de la famille framework et premier profil Tauri 2 issu de la réconciliation KSP/Games.
|
||||||
|
- [`../prompts/006-V0_1_0_START_PROMPT.md`](../prompts/006-V0_1_0_START_PROMPT.md) — prompt de reprise préparé pour la première baseline réutilisable `0.1.0`, à utiliser seulement après publication et vérification post-tag de `0.0.5`.
|
||||||
|
|
||||||
|
## Points d'entrée de 0.0.4
|
||||||
|
|
||||||
- [`plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — périmètre et décisions de la release `0.0.3` ;
|
- [`plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md`](plans/003-V0_0_3_TEMPLATES_AUDITS_PLAN.md) — périmètre et décisions de la release `0.0.3` ;
|
||||||
|
- [`plans/004-V0_0_4_SKELETONS_PLAN.md`](plans/004-V0_0_4_SKELETONS_PLAN.md) — périmètre et décisions de la release `0.0.4` ;
|
||||||
|
- [`skeletons/000-README.md`](skeletons/000-README.md) — contrat de collection des skeleton specifications ;
|
||||||
|
- [`skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md`](skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md) — fondation de gouvernance locale composable et sans spécialisation technologique ;
|
||||||
|
- [`skeletons/002-RUST_CARGO_WORKSPACE.md`](skeletons/002-RUST_CARGO_WORKSPACE.md) — specialization Rust/Cargo workspace composable avec la fondation et les cinq templates existants ;
|
||||||
- [`templates/001-RUST_CARGO_TOOLING.md`](templates/001-RUST_CARGO_TOOLING.md) et [`templates/002-CARGO_MANIFESTS.md`](templates/002-CARGO_MANIFESTS.md) — adaptation des cinq fichiers Rust/Cargo copiables ;
|
- [`templates/001-RUST_CARGO_TOOLING.md`](templates/001-RUST_CARGO_TOOLING.md) et [`templates/002-CARGO_MANIFESTS.md`](templates/002-CARGO_MANIFESTS.md) — adaptation des cinq fichiers Rust/Cargo copiables ;
|
||||||
- [`templates/003-NEW_SESSION_PROMPT.md`](templates/003-NEW_SESSION_PROMPT.md) — spécification du message manuel après une stable publiée ;
|
- [`templates/003-NEW_SESSION_PROMPT.md`](templates/003-NEW_SESSION_PROMPT.md) — spécification du message manuel après une stable publiée ;
|
||||||
- [`validation/001-VALIDATION_MATRIX.md`](validation/001-VALIDATION_MATRIX.md) et [`validation/002-RUST_STYLE_AUDITS.md`](validation/002-RUST_STYLE_AUDITS.md) — gates PGR et limites des audits de style Rust facultatifs.
|
- [`validation/001-VALIDATION_MATRIX.md`](validation/001-VALIDATION_MATRIX.md), [`validation/002-RUST_STYLE_AUDITS.md`](validation/002-RUST_STYLE_AUDITS.md) et [`validation/003-RUST_EXPORT_COMPLETENESS.md`](validation/003-RUST_EXPORT_COMPLETENESS.md) — gates PGR et limites des audits Rust facultatifs.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/architecture/002-GOVERNANCE_ARCHITECTURE.md -->
|
<!-- file: docs/architecture/002-GOVERNANCE_ARCHITECTURE.md -->
|
||||||
<!-- version: 2 -->
|
<!-- version: 5 -->
|
||||||
|
|
||||||
# Architecture de gouvernance PGR
|
# Architecture de gouvernance PGR
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ Après instanciation, le projet possède sa copie et ne dépend plus de PGR.
|
|||||||
|
|
||||||
### Skeleton specification
|
### Skeleton specification
|
||||||
|
|
||||||
Un skeleton est une recette Markdown décrivant comment initialiser un type de projet ou composer plusieurs profils.
|
Un skeleton est une spécification Markdown composable décrivant comment initialiser un type de projet ou composer plusieurs profils.
|
||||||
|
|
||||||
Il décrit notamment les profils applicables, la structure requise ou optionnelle, les templates à utiliser, les points de décision, la politique de version et la validation de base.
|
Il décrit notamment les profils applicables, la structure requise ou optionnelle, les templates à utiliser, les points de décision, la politique de version et la validation de base. Le contrat transversal de sélection et de composition appartient à [`../rules/220-SKELETONS.md`](../rules/220-SKELETONS.md) ; les spécifications concrètes sont indexées sous [`../skeletons/`](../skeletons/000-README.md).
|
||||||
|
|
||||||
Un skeleton n'est pas un générateur et ne doit pas figer l'évolution future du projet.
|
Un skeleton n'est pas un générateur et ne doit pas figer l'évolution future du projet. Il orchestre des owners normatifs et des artefacts existants sans devenir lui-même propriétaire d'une règle déjà possédée ailleurs.
|
||||||
|
|
||||||
### Audit
|
### Audit
|
||||||
|
|
||||||
@@ -37,6 +37,16 @@ Les scripts `audit_*.py` sont read-only : ils ne modifient, ne formatent, ne gé
|
|||||||
|
|
||||||
Les audits PGR sont ajoutés progressivement à partir de besoins réels et de contrôles éprouvés. PGR ne cherche pas à anticiper un catalogue exhaustif d'audits.
|
Les audits PGR sont ajoutés progressivement à partir de besoins réels et de contrôles éprouvés. PGR ne cherche pas à anticiper un catalogue exhaustif d'audits.
|
||||||
|
|
||||||
|
## Frontière avec les contenus pratiques externes
|
||||||
|
|
||||||
|
PGR doit rester auto-suffisant pour comprendre et appliquer ses contrats normatifs. Les règles, owners, objectifs, décisions architecturales, skeleton specifications, templates nécessaires à un contrat réutilisable et validations directement liées aux règles restent possédés par PGR lorsqu'ils sont nécessaires à cette compréhension.
|
||||||
|
|
||||||
|
Les howtos détaillés, recettes pratiques, snippets, exemples d'intégration, dépannage, comparatifs et variantes d'implémentation MAY vivre dans une base de connaissances séparée. SaseDev Knowledge est une destination possible pour cette famille de contenus, mais sa disponibilité n'est pas une précondition d'utilisation de PGR.
|
||||||
|
|
||||||
|
Un contenu pratique externe MAY compléter PGR, mais MUST NOT devenir la source nécessaire pour déterminer ce qu'une règle PGR exige. PGR MUST NOT dépendre d'un dépôt Knowledge pour être interprétable ou applicable.
|
||||||
|
|
||||||
|
Cette frontière est sémantique avant d'être physique : classifier un contenu comme pratique ne déclenche pas automatiquement son déplacement. Une extraction future exige une destination autoritaire explicitement fournie et doit préserver dans PGR tout contrat nécessaire à son auto-suffisance.
|
||||||
|
|
||||||
## Instanciation d'un projet
|
## Instanciation d'un projet
|
||||||
|
|
||||||
Le flux conceptuel est :
|
Le flux conceptuel est :
|
||||||
@@ -44,17 +54,37 @@ Le flux conceptuel est :
|
|||||||
```text
|
```text
|
||||||
PGR rules + templates + skeleton specifications
|
PGR rules + templates + skeleton specifications
|
||||||
↓
|
↓
|
||||||
sélection humaine / IA
|
applicabilité + décisions du projet
|
||||||
↓
|
↓
|
||||||
nouveau projet
|
copie / adaptation contrôlée
|
||||||
↓
|
↓
|
||||||
copies et règles locales
|
validation de la baseline
|
||||||
↓
|
↓
|
||||||
projet autonome et gouverné
|
projet autonome et gouverné
|
||||||
```
|
```
|
||||||
|
|
||||||
Une évolution ultérieure de PGR ne modifie jamais automatiquement les projets déjà créés.
|
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
|
## 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.
|
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.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/architecture/003-RULE_PROFILE_MODEL.md -->
|
<!-- file: docs/architecture/003-RULE_PROFILE_MODEL.md -->
|
||||||
<!-- version: 2 -->
|
<!-- version: 8 -->
|
||||||
|
|
||||||
# Modèle de profils de règles PGR
|
# Modèle de profils de règles PGR
|
||||||
|
|
||||||
@@ -117,6 +117,16 @@ Cette relation interne ne modifie pas la hiérarchie globale. Une contrainte de
|
|||||||
|
|
||||||
Lorsque langage et build tool sont pratiquement indissociables pour le scope visé, PGR peut les documenter dans un même profil si cette fusion évite une séparation artificielle. Le choix du découpage doit suivre les responsabilités réelles, pas une taxonomie rigide.
|
Lorsque langage et build tool sont pratiquement indissociables pour le scope visé, PGR peut les documenter dans un même profil si cette fusion évite une séparation artificielle. Le choix du découpage doit suivre les responsabilités réelles, pas une taxonomie rigide.
|
||||||
|
|
||||||
|
## Baseline contrôlée et projet imposé
|
||||||
|
|
||||||
|
La même combinaison de technologies peut être gouvernée avec des degrés de liberté différents.
|
||||||
|
|
||||||
|
Pour une baseline créée et contrôlée par le projet, les profils sélectionnés s'appliquent intégralement puis une skeleton specification MAY fixer des choix réutilisables supplémentaires : layout, stack frontend, conventions de manifests ou organisation des fichiers.
|
||||||
|
|
||||||
|
Pour un projet existant ou imposé par un tiers, PGR doit d'abord préserver les contraintes externes réellement obligatoires. Toute divergence avec le profil préféré devient une règle project-specific ou une exception explicite et bornée ; elle ne modifie pas automatiquement le profil général.
|
||||||
|
|
||||||
|
Cette distinction évite deux erreurs opposées : forcer le skeleton interne d'une organisation sur un dépôt qu'elle ne contrôle pas, ou affaiblir ses propres conventions sous prétexte qu'un framework accepte plusieurs formes.
|
||||||
|
|
||||||
## Profils composites
|
## Profils composites
|
||||||
|
|
||||||
PGR ne crée pas automatiquement un profil composite pour chaque combinaison possible.
|
PGR ne crée pas automatiquement un profil composite pour chaque combinaison possible.
|
||||||
@@ -194,10 +204,97 @@ 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.
|
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.
|
||||||
|
|
||||||
|
Cette activation ne change pas la hiérarchie : Tauri ne devient propriétaire ni des règles Rust générales, ni d'Android, ni du choix du frontend. Il possède uniquement l'orchestration Tauri, sa configuration/capabilities, ses hooks, sa version applicative et les gates d'intégration propres au framework.
|
||||||
|
|
||||||
|
La famille `800 — architecture` reste réservée : aucune règle nouvelle n'en justifie encore la matérialisation.
|
||||||
|
|
||||||
La réconciliation a également confirmé qu'une règle générale ne doit pas être recopiée comme si le profil spécifique en devenait propriétaire. Un profil peut rappeler une conséquence spécifique au contexte, mais doit référencer l'owner général lorsque le contrat lui-même n'est pas spécialisé.
|
La réconciliation a également confirmé qu'une règle générale ne doit pas être recopiée comme si le profil spécifique en devenait propriétaire. Un profil peut rappeler une conséquence spécifique au contexte, mais doit référencer l'owner général lorsque le contrat lui-même n'est pas spécialisé.
|
||||||
|
|
||||||
## Instanciation future
|
## Owners frontend matérialisés en `0.1.1`
|
||||||
|
|
||||||
Les futures skeleton specifications sélectionneront les profils applicables et recopieront leurs règles pertinentes dans la baseline locale du projet créé.
|
L'audit Games/KSP et la revue opérateur de `0.1.1-alpha.1` justifient quatre owners distincts dans la famille `500` :
|
||||||
|
|
||||||
Le projet instancié restera autonome : la composition de profils sert à construire sa baseline initiale, pas à créer une dépendance dynamique vers PGR.
|
```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.
|
||||||
|
|
||||||
|
Le projet instancié reste autonome : la composition de profils sert à construire sa baseline initiale, pas à créer une dépendance dynamique vers PGR.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/objectives/001-PROJECT_OBJECTIVES.md -->
|
<!-- file: docs/objectives/001-PROJECT_OBJECTIVES.md -->
|
||||||
<!-- version: 1 -->
|
<!-- version: 2 -->
|
||||||
|
|
||||||
# Objectifs de Project Governance Rules
|
# Objectifs de Project Governance Rules
|
||||||
|
|
||||||
@@ -18,9 +18,11 @@ PGR doit permettre de :
|
|||||||
- favoriser des validations ciblées pendant le développement et des gates plus larges aux jalons appropriés ;
|
- favoriser des validations ciblées pendant le développement et des gates plus larges aux jalons appropriés ;
|
||||||
- automatiser les contrôles déterministes et fiables sans automatiser artificiellement les décisions nécessitant du jugement ;
|
- automatiser les contrôles déterministes et fiables sans automatiser artificiellement les décisions nécessitant du jugement ;
|
||||||
- fournir des templates techniques éprouvés sans créer de dépendance vers PGR après instanciation ;
|
- fournir des templates techniques éprouvés sans créer de dépendance vers PGR après instanciation ;
|
||||||
- décrire des skeletons de projets sous forme de recettes Markdown composables plutôt que de générateurs rigides ;
|
- décrire des skeletons de projets sous forme de spécifications Markdown composables plutôt que de générateurs rigides ;
|
||||||
- supporter plusieurs langages, plateformes et frameworks sans chercher une uniformité artificielle ;
|
- supporter plusieurs langages, plateformes et frameworks sans chercher une uniformité artificielle ;
|
||||||
- conserver une traçabilité historique utile tout en gardant les documents vivants lisibles ;
|
- conserver une traçabilité historique utile tout en gardant les documents vivants lisibles ;
|
||||||
|
- rester auto-suffisant pour comprendre et appliquer les contrats normatifs PGR, sans dépendre d’un howto, snippet ou dépôt documentaire externe ;
|
||||||
|
- permettre que les howtos détaillés, recettes pratiques, snippets, exemples d’intégration, dépannage, comparatifs et variantes d’implémentation vivent dans une base de connaissances séparée lorsqu’une telle séparation apporte une valeur réelle ;
|
||||||
- permettre des règles project-specific et des exceptions explicites sans contaminer les règles générales ;
|
- permettre des règles project-specific et des exceptions explicites sans contaminer les règles générales ;
|
||||||
- privilégier la sécurité, l'explicité, la maintenabilité et la proportionnalité.
|
- privilégier la sécurité, l'explicité, la maintenabilité et la proportionnalité.
|
||||||
|
|
||||||
@@ -45,6 +47,7 @@ PGR n'a pas pour objectif de :
|
|||||||
- créer des audits regex pour remplacer le jugement architectural ;
|
- créer des audits regex pour remplacer le jugement architectural ;
|
||||||
- réimplémenter les fonctionnalités des toolchains officielles sans bénéfice réel ;
|
- réimplémenter les fonctionnalités des toolchains officielles sans bénéfice réel ;
|
||||||
- maintenir automatiquement les projets créés à partir de PGR ;
|
- maintenir automatiquement les projets créés à partir de PGR ;
|
||||||
|
- devenir une base exhaustive de howtos, recettes, snippets ou dépannage lorsque ces contenus ne sont pas nécessaires pour comprendre ou appliquer un contrat PGR ;
|
||||||
- imposer une stratégie Git complexe ou une topologie universelle de branches.
|
- imposer une stratégie Git complexe ou une topologie universelle de branches.
|
||||||
|
|
||||||
## Critères de succès à terme
|
## Critères de succès à terme
|
||||||
|
|||||||
158
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
Normal file
158
docs/plans/004-V0_0_4_SKELETONS_PLAN.md
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<!-- file: docs/plans/004-V0_0_4_SKELETONS_PLAN.md -->
|
||||||
|
<!-- version: 3 -->
|
||||||
|
|
||||||
|
# Plan 0.0.4 — skeleton specifications et composition
|
||||||
|
|
||||||
|
## Statut et sources
|
||||||
|
|
||||||
|
Plan historique créé pendant `0.0.4-alpha.1` après audit indépendant de la stable publiée `v0.0.3` demandé par `prompts/004-V0_0_4_START_PROMPT.md`. Les tranches `alpha.1` à `alpha.3` sont `PASS`. `alpha.4` a enregistré `FAIL` sur sa gate d'instanciation, puis `alpha.4.fix.1` a corrigé cette gate et est `PASS`. `beta.1` a enregistré `FAIL` sur une erreur de syntaxe de sa gate de réconciliation, puis `beta.1.fix.1` a rejoué la réconciliation et est `PASS`. La gate opérateur de `rc.1` est `PASS` : intégration documentaire, prompt `005`, cinq TOML et instanciation temporaire Rust/Cargo avec `cargo metadata`, `fmt`, `check` et `clippy -D warnings` ont été validés. Le scope fonctionnel est gelé et `rel.001` ne réalise qu'une promotion stable pré-tag.
|
||||||
|
|
||||||
|
La baseline autoritaire est l'archive source fournie `pgr-v0.0.3.zip`, déclarée téléchargée depuis le tag Gitea `v0.0.3`. Son SHA-256 vérifié pendant le cadrage est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
517fb46ada098fdc221ae53a8ff4b409b81e0244ec5ce4d0e6fca0c3da61b866
|
||||||
|
```
|
||||||
|
|
||||||
|
Le rapport externe `pgr-0.0.3-publish.001-report.md` est fourni séparément, conclut `PASS` et annonce le même hash. Il atteste une vérification post-tag distincte et ne fait pas partie de la stable. L'archive source ne contient pas `.git`, ce qui est conforme au contrat de reprise ; l'identité du commit et du tag décrite dans le rapport n'est pas déduite du contenu du ZIP.
|
||||||
|
|
||||||
|
Les règles applicables au cadrage sont `RULES.md`, les familles `200`, `210`, `300`, `400`, `500`, `510`, `520`, `600`, `610`, ainsi que `docs/architecture/003-RULE_PROFILE_MODEL.md`. Les guides `docs/templates/001` à `003`, les cinq modèles Rust/Cargo, les trois audits Markdown et les deux audits facultatifs de style Rust complètent l'inventaire réel de la stable.
|
||||||
|
|
||||||
|
## Audit indépendant de la stable `v0.0.3`
|
||||||
|
|
||||||
|
L'archive fournie est lisible et son contenu distribué est cohérent dans les contrôles effectués :
|
||||||
|
|
||||||
|
- SHA-256 égal au rapport post-tag ;
|
||||||
|
- `140` entrées ZIP : `115` fichiers et `25` répertoires, avec une seule racine `pgr/` ;
|
||||||
|
- test CRC propre, aucun doublon, aucune collision de casse, aucun chemin absolu ou avec traversée `..`, aucun chemin Windows ambigu et aucun lien symbolique ;
|
||||||
|
- extraction propre de `115` fichiers ; `VERSION` contient exactement `0.0.3` suivi d'un retour à la ligne ; `.git` est absent comme attendu ;
|
||||||
|
- les fichiers distribués sont UTF-8, sans octet NUL, retour CR, espace de fin de ligne ou retour final manquant ;
|
||||||
|
- aucun chemin distribué de build/cache ou secret contrôlé n'est présent ; `.settings/org.eclipse.core.resources.prefs` reste l'exception Eclipse versionnée prévue ;
|
||||||
|
- `99` fichiers Markdown possèdent des headers `file/version` mécaniquement conformes ;
|
||||||
|
- les trois audits Markdown sont propres : `99` fichiers pour les headers, `3` tableaux et `79` liens locaux ;
|
||||||
|
- les `15` tests Python ciblés réussissent ;
|
||||||
|
- les cinq fichiers TOML sous `templates/rust-cargo/` se parsèrent correctement ;
|
||||||
|
- les deux audits de style Rust facultatifs n'ont pas de corpus Rust produit à inspecter dans PGR ; leur comportement est couvert par `tests/test_rust_audits.py` et leur sélection doit rester explicite dans un projet destinataire.
|
||||||
|
|
||||||
|
La chaîne workflow est complète :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.0.1 : 12 deltas / 12 histories
|
||||||
|
0.0.2 : 12 deltas / 12 histories
|
||||||
|
0.0.3 : 10 deltas / 10 histories
|
||||||
|
```
|
||||||
|
|
||||||
|
Chaque delta possède son history homonyme. Les histories `0.0.3`, de `alpha.1` à `rel.001`, sont tous `PASS`. Les échecs historiques des séries antérieures sont conservés comme snapshots et sont suivis par leurs corrections explicites ; ils ne sont pas réécrits rétroactivement.
|
||||||
|
|
||||||
|
Les limites annoncées restent visibles et cohérentes : l'audit des liens ne valide pas les anchors, l'audit des headers ne juge pas la pertinence sémantique d'une révision, les audits Rust utilisent une analyse lexicale ciblée et l'archive source ne prouve pas elle-même une référence Git distante. Aucun de ces points ne constitue un défaut bloquant de la stable.
|
||||||
|
|
||||||
|
## Revue des règles, profils et propriétaires
|
||||||
|
|
||||||
|
La hiérarchie normative reste cohérente avec le modèle de profils : règles générales, langage/écosystème, plateforme, puis scopes plus spécifiques et exceptions explicites. Aucun profil n'est applicable par simple fréquence ou provenance historique.
|
||||||
|
|
||||||
|
Les responsabilités utiles à `0.0.4` sont distinctes :
|
||||||
|
|
||||||
|
- `200` possède le lifecycle et le rôle de `alpha.1` comme gate de cadrage ;
|
||||||
|
- `210` possède plans, deltas, histories, prompts, baselines et séparation pré-tag/post-tag ;
|
||||||
|
- `300` possède rôles documentaires, documents vivants, snapshots et headers ;
|
||||||
|
- `400` possède la sélection proportionnelle des preuves et l'autorité du gate opérateur ;
|
||||||
|
- `500` et `600` possèdent les contrats communs des profils langage et plateforme ;
|
||||||
|
- `510`, `520` et `610` possèdent respectivement Rust/Cargo, Java/Maven/Gradle et Android ;
|
||||||
|
- `docs/architecture/003-RULE_PROFILE_MODEL.md` possède le modèle de composition et interdit les profils composites sans contrat propre réel.
|
||||||
|
|
||||||
|
La séparation règle / template / skeleton / audit de `docs/architecture/002-GOVERNANCE_ARCHITECTURE.md` reste adaptée. `0.0.4` doit l'étendre par des artefacts concrets sans déplacer les propriétaires normatifs existants.
|
||||||
|
|
||||||
|
## Inventaire des capacités disponibles pour des skeletons
|
||||||
|
|
||||||
|
### Fondation gouvernée PGR — prête à être spécifiée
|
||||||
|
|
||||||
|
Une baseline de projet gouverné constitue une fondation composable, pas une architecture applicative. Les contrats nécessaires existent déjà : versioning, workflow, documentation, validation et modèle de profils. Le skeleton devra indiquer quels artefacts locaux créer ou copier, comment sélectionner les règles réellement applicables et quelles décisions restent propres au projet.
|
||||||
|
|
||||||
|
Il ne doit pas recopier l'historique de PGR, imposer toutes les familles de règles ni créer une dépendance dynamique vers le dépôt PGR.
|
||||||
|
|
||||||
|
### Rust/Cargo workspace — prêt à être spécifié
|
||||||
|
|
||||||
|
Le besoin est suffisamment couvert par des artefacts réels : profil `510`, deux guides d'adaptation, cinq templates Rust/Cargo et deux audits de style facultatifs documentés. Le skeleton pourra composer une fondation gouvernée avec `500 + 510` et sélectionner uniquement les templates nécessaires.
|
||||||
|
|
||||||
|
Les décisions destinataire restent explicites : nom du projet et des crates, version de release, édition/toolchain, métadonnées de publication, membres du workspace, dépendances et features, politique `Cargo.lock`, chemin des artefacts Cargo, seuils Clippy, politique de lints et sélection éventuelle des audits de style. Les valeurs d'exemple `0.1.0`, `2024`, `project-name`, `project-core-lib`, les seuils Clippy et les chemins de build ne deviennent jamais universels.
|
||||||
|
|
||||||
|
### Java / Maven / Gradle — différé
|
||||||
|
|
||||||
|
Le profil `520` définit des règles, mais PGR ne possède encore aucun template Maven/Gradle ou corpus technique éprouvé à instancier. Le choix Maven/Gradle, la politique de wrapper et les versions de toolchain doivent être déterminés dans un chantier justifié avant de produire un skeleton concret.
|
||||||
|
|
||||||
|
### Android — différé
|
||||||
|
|
||||||
|
Le profil `610` définit la structure de responsabilité et les décisions Android, mais aucun template AGP/Gradle, manifest applicatif, matrice SDK ou projet réel n'existe dans PGR. Un skeleton Android serait prématuré avant ces pièces et avant la sélection explicite de sa composition avec Java/Gradle ou un autre stack réel.
|
||||||
|
|
||||||
|
### Web, JNI, Tauri et autres familles absentes — différés
|
||||||
|
|
||||||
|
Ces domaines ne possèdent pas encore tous leurs propriétaires normatifs et templates nécessaires. `0.0.4` ne crée pas de profils ou skeletons placeholders pour eux.
|
||||||
|
|
||||||
|
## Contrat visé pour une skeleton specification
|
||||||
|
|
||||||
|
La tranche de composition devra fixer un contrat commun minimal. Chaque skeleton doit au moins permettre d'identifier :
|
||||||
|
|
||||||
|
```text
|
||||||
|
applicabilité et objectif
|
||||||
|
profils/règles sélectionnés
|
||||||
|
fichiers à créer, copier ou adapter
|
||||||
|
templates applicables et source de leurs choix
|
||||||
|
décisions obligatoires propres au destinataire
|
||||||
|
options et exceptions explicites
|
||||||
|
ordre de composition
|
||||||
|
validation initiale proportionnée
|
||||||
|
éléments volontairement hors scope
|
||||||
|
```
|
||||||
|
|
||||||
|
Un skeleton reste une procédure Markdown. Il ne génère pas le projet, ne télécharge pas de dépendances, ne remplace pas les toolchains et ne fige pas l'architecture future. Après instanciation, le projet possède ses copies locales et ses décisions.
|
||||||
|
|
||||||
|
Les règles communes de sélection et de composition doivent avoir un propriétaire normatif unique sous `docs/rules/`. Les spécifications concrètes vivront dans une collection documentaire dédiée créée seulement avec son premier contenu réel. Les fichiers techniques copiables restent sous `templates/` et leurs instructions d'adaptation sous `docs/templates/`.
|
||||||
|
|
||||||
|
## Découpage prévisionnel de `0.0.4`
|
||||||
|
|
||||||
|
### alpha.1 — audit de stable et cadrage
|
||||||
|
|
||||||
|
Vérifier indépendamment `v0.0.3`, le rapport post-tag, les règles `200` à `610`, les cinq templates Rust/Cargo, les trois audits Markdown, les deux audits Rust facultatifs et la chaîne de deltas/histories. Inventorier les skeletons réellement justifiés et fixer le présent plan avant toute matérialisation importante.
|
||||||
|
|
||||||
|
### alpha.2 — contrat de composition des skeletons
|
||||||
|
|
||||||
|
Créer le propriétaire normatif des règles de sélection et de composition des skeletons, puis la collection documentaire des skeleton specifications avec son index. Définir la frontière entre règles copiées/adaptées, templates techniques, décisions propres au projet, overrides et validation. Réconcilier les index et l'architecture sans créer encore de domaine technologique supplémentaire.
|
||||||
|
|
||||||
|
Le nom et le numéro exacts du document normatif seront choisis à l'application selon la responsabilité finale ; le plan ne transforme pas un chemin prévisionnel en règle déjà active.
|
||||||
|
|
||||||
|
### alpha.3 — fondation de projet gouverné
|
||||||
|
|
||||||
|
Matérialiser une première specification composable décrivant la baseline de gouvernance locale d'un projet utilisant PGR : version, règles sélectionnées, documentation minimale, workflow réellement retenu et validation initiale. Elle doit rester proportionnée et permettre d'omettre les collections ou artefacts sans contenu réel.
|
||||||
|
|
||||||
|
Cette fondation n'est ni un framework ni une architecture applicative et ne doit pas recopier les deltas, histories ou décisions propres au dépôt PGR.
|
||||||
|
|
||||||
|
### alpha.4 — skeleton Rust/Cargo workspace
|
||||||
|
|
||||||
|
Matérialiser la première specialization technologique en composant la fondation gouvernée avec `500 + 510`, les cinq templates Rust/Cargo et les guides d'adaptation existants. Documenter les décisions destinataire avant copie et les audits facultatifs explicitement sélectionnés.
|
||||||
|
|
||||||
|
La gate doit inclure une instanciation temporaire minimale ou une vérification équivalente lorsque la toolchain Rust est disponible, afin de distinguer la validité syntaxique des templates de leur adoption correcte. Cette preuve ne transforme pas PGR lui-même en workspace Rust.
|
||||||
|
|
||||||
|
### beta.1 — réconciliation interne
|
||||||
|
|
||||||
|
Vérifier ownership, liens, index, absence de duplication normative, non-universalisation des valeurs d'exemple, limites des audits et cohérence des deux premières specifications. Confirmer explicitement que Java/Android/Web/JNI/Tauri restent différés tant que leurs pièces requises manquent.
|
||||||
|
|
||||||
|
Aucun chantier de réconciliation complète avec KSP ou Games n'entre ici : la roadmap réserve cette mission à `0.0.5`.
|
||||||
|
|
||||||
|
La première gate `beta.1` a enregistré `FAIL` uniquement parce qu'une chaîne Python de contrôle contenait une apostrophe non échappée. `beta.1.fix.1` a corrigé la gate sans modifier de contenu vivant et a confirmé la réconciliation : owners distincts, trois documents skeletons seulement, valeurs Rust/Cargo adaptables, limites des audits explicites, cinq TOML valides et domaines différés toujours absents.
|
||||||
|
|
||||||
|
### rc.1 — gate de release candidate
|
||||||
|
|
||||||
|
Geler le scope, préparer l'entrée `0.0.4` du changelog et le prompt `005` de `0.0.5` si la trajectoire est confirmée. Rejouer les validations documentaires, tests et smokes réellement invalidés par la release.
|
||||||
|
|
||||||
|
Le scope gelé comprend le contrat transversal `220-SKELETONS.md`, l'index de collection, la fondation gouvernée `001`, la spécialisation Rust/Cargo `002` et l'utilisation des cinq templates Rust/Cargo déjà présents. Aucun nouveau domaine technologique, générateur, template, audit ou règle normative n'entre en RC. La trajectoire `0.0.5` reste celle de la roadmap : réconciliation réelle de PGR avec `khadhroony-solana-project` et `sasedev-games`, à partir de baselines explicites qui devront être fournies à cette future session plutôt que déduites d'un état local implicite.
|
||||||
|
|
||||||
|
### stable — 0.0.4
|
||||||
|
|
||||||
|
La gate opérateur de `rc.1` est `PASS`. Le delta `rel.001` prépare mécaniquement la stable `0.0.4` : `VERSION`, présentation du dépôt et des index, statut de la roadmap, conversion de l'entrée candidate du changelog et clôture du présent plan comme référence historique. Aucun nouveau skeleton, profil, template, audit ou domaine technologique n'est ajouté pendant cette promotion.
|
||||||
|
|
||||||
|
Le résultat réel de la gate pré-tag appartient à `history/0.0.4/rel.001.md`, produit après exécution opérateur. Le commit stable et le tag `v0.0.4` suivent uniquement un `PASS`. La vérification de l'archive effectivement publiée depuis Gitea et le rapport `pgr-0.0.4-publish.001-report.md` constituent ensuite une preuve post-tag séparée ; ils ne sont pas présumés par le delta ni par le history pré-tag.
|
||||||
|
|
||||||
|
## Points de décision et stratégie de validation
|
||||||
|
|
||||||
|
Un REPLAN devient nécessaire si la fondation gouvernée exige des templates génériques inexistants pour rester actionnable, si le contrat de composition duplique des règles existantes au lieu de les référencer, si le skeleton Rust impose une architecture plus étroite que le profil `510`, ou si l'instanciation minimale révèle qu'un template technique ne peut pas être adopté sans nouvelle décision normative.
|
||||||
|
|
||||||
|
Les tranches documentaires utilisent les trois audits Markdown et les contrôles Git applicables. Toute modification des scripts ou de leurs contrats rejoue leurs tests ciblés. Toute modification d'un template Rust/Cargo vérifie sa syntaxe et, lorsqu'elle prétend à une instanciation fonctionnelle, une gate Cargo proportionnée dans un environnement temporaire. Aucun build Java/Android n'est demandé tant qu'aucun artefact concret de ces écosystèmes n'entre dans le scope.
|
||||||
222
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
Normal file
222
docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
<!-- file: docs/plans/005-V0_0_5_RECONCILIATION_PLAN.md -->
|
||||||
|
<!-- version: 16 -->
|
||||||
|
|
||||||
|
# Plan 0.0.5 — réconciliation réelle avec KSP et sasedev-games
|
||||||
|
|
||||||
|
## Statut et sources
|
||||||
|
|
||||||
|
Plan historique créé pendant `0.0.5-alpha.1` conformément à `prompts/005-V0_0_5_START_PROMPT.md`. La release a confronté PGR à deux baselines autoritaires fournies sans présumer qu'elles avaient déjà adopté PGR.
|
||||||
|
|
||||||
|
Sources contrôlées :
|
||||||
|
|
||||||
|
```text
|
||||||
|
pgr-v0.0.4.zip 7137bb084f017362323a2043d13ba71490be15b8786adc8d645981bf455b80ae
|
||||||
|
khadhroony-solana-project-v0.3.16.zip db3cc1b3fc3fb07ee864b02e2a7346c673d4cf63b33e8e872aca6c6458856ca0
|
||||||
|
games-v0.3.5.zip 5f5fdee1a271386766d059657d6eaa831acdc263b3e722fed738808335c0a105
|
||||||
|
```
|
||||||
|
|
||||||
|
Le rapport externe `pgr-0.0.4-publish.001-report.md` est `PASS` et annonce le même hash pour la stable PGR. L'étude détaillée et les limites de l'environnement sont consignées dans [`../studies/001-KSP_GAMES_RECONCILIATION.md`](../studies/001-KSP_GAMES_RECONCILIATION.md).
|
||||||
|
|
||||||
|
## Mission et garde-fous
|
||||||
|
|
||||||
|
`0.0.5` doit améliorer PGR à partir des besoins réellement répétés dans KSP et Games sans transformer leurs conventions historiques en règles universelles.
|
||||||
|
|
||||||
|
Les deux projets ne sont pas encore gouvernés par PGR. Par conséquent :
|
||||||
|
|
||||||
|
- aucune divergence de leurs archives n'est qualifiée de défaut PGR par défaut ;
|
||||||
|
- aucune migration de KSP ou Games n'appartient au scope de cette release ;
|
||||||
|
- aucune ancienne tranche, nomenclature ou chaîne history n'est reconstruite rétroactivement ;
|
||||||
|
- tout nouvel owner PGR doit correspondre à un besoin réutilisable et non à un simple copier-coller de projet ;
|
||||||
|
- les règles métier, architecture, protocoles, distribution et infrastructure spécifiques restent locales.
|
||||||
|
|
||||||
|
## Résultat du cadrage alpha.1
|
||||||
|
|
||||||
|
L'audit classe la majorité des mécanismes de gouvernance, documentation, validation et Rust/Cargo comme déjà `OWNED` par PGR. Les améliorations candidates réellement communes sont bornées à quatre axes :
|
||||||
|
|
||||||
|
1. **prompt de démarrage de projet** : le contrat actuel de `210-WORKFLOW.md` est plus minimal que les prompts opératoires éprouvés dans les deux corpus ;
|
||||||
|
2. **contrats documentaires locaux** : les deux projets utilisent un registre de responsabilités de fichiers/familles qui peut devenir un pattern facultatif de la fondation ;
|
||||||
|
3. **façade Rust et export completeness** : les deux projets partagent pratiquement le même audit spécialisé, alors que PGR n'en fournit pas encore de version réutilisable ;
|
||||||
|
4. **Tauri** : le framework est utilisé indépendamment et de manière répétée dans les deux corpus, ce qui fournit enfin une base réelle pour activer la famille framework `700` sans généraliser Vite/Web/JNI au-delà des preuves disponibles.
|
||||||
|
|
||||||
|
Les audits composites, le Web autonome, WASM, JNI, règles serveur, distribution Games et frontières métier KSP restent différés ou locaux.
|
||||||
|
|
||||||
|
## REPLAN alpha.4 — lifecycle inter-release et horizon
|
||||||
|
|
||||||
|
La gate `alpha.3.fix.1` a validé son correctif local. Une revue séparée du plan, de `ROADMAP.md` et des historiques de conception PGR `0.0.1` à `0.0.4` a ensuite confirmé un besoin général non couvert explicitement par le forecast initial : PGR sait piloter une release active, mais n'assigne pas encore assez strictement **où/quand sa fermeture et sa transition sont préparées**, ni **quand l'horizon des versions futures doit être rediscuté**.
|
||||||
|
|
||||||
|
Les historiques montrent que plusieurs briques avaient déjà été décidées séparément — moment du `CHANGELOG`, `ROADMAP`, prompt suivant, `REPLAN`, abandon/supersession, continuation inter-session, handoff et distinction `rel.001`/`publish.001`. Le problème n'est donc pas d'inventer un second workflow, mais de les relier dans le contrat du plan et d'éviter qu'elles restent implicites.
|
||||||
|
|
||||||
|
Ce constat déclenche le point de décision `REPLAN` prévu par `alpha.1`. Aucun travail antérieur n'est invalidé. Les anciennes tranches `alpha.4` à `alpha.6` sont décalées d'un numéro et restent dans le scope.
|
||||||
|
|
||||||
|
## Trajectoire prévisionnelle
|
||||||
|
|
||||||
|
### alpha.1 — audit indépendant, étude et plan
|
||||||
|
|
||||||
|
Vérifier la stable PGR, son rapport post-tag et les deux archives externes ; exécuter les audits statiques disponibles ; classifier les écarts ; créer l'étude et le présent plan. Aucun changement normatif, script réutilisable, profil framework ou skeleton nouveau dans cette tranche.
|
||||||
|
|
||||||
|
### alpha.2 — contrat générique des prompts de démarrage
|
||||||
|
|
||||||
|
Renforcer l'owner `210-WORKFLOW.md` pour les prompts versionnés sans recopier les règles locales KSP/Games. Fournir une spécification réutilisable couvrant au minimum : baseline autoritaire, ordre de lecture, état déjà validé, mission/résultat, scope/hors-scope, décisions gelées/ouvertes, première gate, trajectoire prévisionnelle et validations.
|
||||||
|
|
||||||
|
Le template manuel `003-NEW_SESSION_PROMPT.md` reste distinct : il sert au court message remis après publication, alors que cette tranche porte le prompt versionné du projet.
|
||||||
|
|
||||||
|
### alpha.3 — pattern de contrats de fichiers/familles
|
||||||
|
|
||||||
|
Étendre `300-DOCUMENTATION.md` et la fondation `001` uniquement si nécessaire pour décrire un registre local facultatif des fichiers ou familles dont le rôle et les règles de modification méritent d'être explicites. Fournir une spécification/template documentaire courte plutôt qu'un catalogue universel.
|
||||||
|
|
||||||
|
Le pattern ne doit pas imposer `FILE_CONTRACTS.md` à un petit projet, ni recopier les rôles déjà possédés par PGR. Le correctif `alpha.3.fix.1` a en outre renforcé l'audit des tables Markdown fenced sans modifier ce scope fonctionnel.
|
||||||
|
|
||||||
|
### alpha.4 — REPLAN : clôture, transition et revue d'horizon
|
||||||
|
|
||||||
|
Formaliser le lifecycle inter-release qui manquait au plan initial :
|
||||||
|
|
||||||
|
- imposer à un plan de release suffisamment complexe d'attribuer noir sur blanc les responsabilités de clôture/transition ;
|
||||||
|
- définir la revue d'horizon sans imposer un nombre artificiel de versions futures ;
|
||||||
|
- expliciter le passage `idea/study → décision durable → roadmap/plan` ;
|
||||||
|
- confirmer qu'une discussion stratégique peut vivre dans une session séparée sans changer `VERSION` ;
|
||||||
|
- rendre spontané le message manuel de reprise lorsque la prochaine cible est connue ;
|
||||||
|
- permettre la livraison `history courant + delta suivant` dans une même réponse lorsque la suite est déterministe, tout en maintenant deux archives et l'ordre commit/apply ;
|
||||||
|
- fournir un pattern réutilisable de plan de release pour l'adoption future dans KSP, Games et d'autres projets.
|
||||||
|
|
||||||
|
Cette tranche ne commence pas l'audit Rust ni le profil Tauri.
|
||||||
|
|
||||||
|
### alpha.5 — audit Rust de façade/export completeness
|
||||||
|
|
||||||
|
Extraire le noyau réellement commun de `audit_rust_export_completeness.py`, l'aligner avec `510-RUST_CARGO.md`, documenter son caractère facultatif et ses limites, et ajouter des tests positifs/négatifs.
|
||||||
|
|
||||||
|
La réconciliation a révélé que le script historique ne découvrait que `crates/*/Cargo.toml` : il couvrait les `22` packages KSP mais aucun des `23` packages Games imbriqués sous des sous-familles. La variante PGR corrige donc la découverte récursive et distingue aussi les cibles `lib`/`bin` d'un même package pour ne pas confondre plusieurs crates Rust compilées séparément.
|
||||||
|
|
||||||
|
La première livraison `alpha.5` a ensuite révélé un second défaut de scope pendant la revue opérateur : elle ne détectait que les chemins internes longs tels que `crate::module::Item`, alors que le contrat attendu impose `crate::Item` pour **toute référence intra-crate à un item partagé**, y compris un nom nu dans son module propriétaire. La gate mécanique était verte mais l'acceptation fonctionnelle est donc `FAIL`; `alpha.5.fix.1` corrige ce blind spot sans commencer Tauri.
|
||||||
|
|
||||||
|
Mesure `alpha.5.fix.1` en `--report-only --summary-only` : KSP `0.3.16` = `1525` lignes candidates `RUST-IMPORT-201` sur `22` packages ; Games `0.3.5` = `181` lignes candidates sur `23` packages (`2 RUST-API-201`, `179 RUST-IMPORT-201`). Ces nombres forment un inventaire d'adoption future, pas une non-conformité rétroactive des baselines.
|
||||||
|
|
||||||
|
Cette tranche ne réimporte pas `audit_rust_general_rules.py` en bloc et ne réintroduit pas le diagnostic historique de résolution `crate::X` déjà possédé par le compilateur. Toute autre règle déjà possédée par Rustfmt, Clippy, le compilateur ou les audits PGR existants reste chez son owner actuel.
|
||||||
|
|
||||||
|
### alpha.6 — premier profil framework : Tauri
|
||||||
|
|
||||||
|
La preuve commune est confirmée : `6` applications Tauri KSP et `2` applications Tauri Games partagent Tauri 2, un host Rust/Cargo, `tauri-build`, `tauri.conf.json`, des capability files, des hooks frontend et un `frontendDist`. Les valeurs applicatives divergent suffisamment pour exclure toute copie de ports, fenêtres, CSP, bundles, plugins ou commandes frontend particulières.
|
||||||
|
|
||||||
|
La première livraison active `700-FRAMEWORKS.md` et `710-TAURI.md`, mais la gate opérateur est `FAIL` pour deux raisons : le contrôle Python ciblé du delta contient une chaîne multilignes invalide et la revue fonctionnelle exige de mieux distinguer le profil Tauri universel des conventions d'instanciation des projets contrôlés. `alpha.6.fix.1` corrige donc le gate et explicite que le host Tauri hérite intégralement des règles Rust sélectionnées, que WASM reste normalement une unité séparée et que l'ajout manuel de plugins à partir de leur documentation officielle est une stratégie valide.
|
||||||
|
|
||||||
|
Les préférences récurrentes de l'organisation — frontend sous `frontend/`, Vite, TypeScript, Sass, Bootstrap et contrôle explicite des dépendances — sont consignées comme **candidat de skeleton**, pas comme invariants de `710-TAURI.md`. Un projet imposé de l'extérieur peut conserver une structure différente via ses règles project-specific.
|
||||||
|
|
||||||
|
La politique `gen/` n'est pas généralisée : les sorties purement reproductibles restent générées, mais les projets mobiles modifiés intentionnellement doivent être classifiés selon leur rôle réel. L'échec du POC Tauri mobile Games ne constitue pas un rejet général de Tauri Android/iOS pour les autres produits.
|
||||||
|
|
||||||
|
La gate `alpha.6.fix.1` révèle un second défaut de quoting Python (`l'extérieur` dans une chaîne simple) et la revue opérateur demande une seconde passe sur les règles réelles KSP/Games. `alpha.6.fix.2` corrige le gate et renforce la convention des projets contrôlés avec le layout direct sans `src-tauri/`, `lib.rs`/`main.rs`/`tauri.rs`, TS-RS lorsque le frontend TypeScript partage des DTO Rust, modules de fenêtres/responsabilités et préférence pour l'intégration explicite des plugins. Les règles Rust générales et la nomenclature des crates restent volontairement dans `alpha.7/alpha.8`.
|
||||||
|
|
||||||
|
La gate mécanique de `alpha.6.fix.2` est propre, mais la revue fonctionnelle révèle une troisième divergence : KSP et Games avaient tous deux converti la réduction du churn de version en préférence pour l'absence de `tauri.conf.json > version` et la stagnation de `package.json`. Cette solution ne doit pas devenir une règle PGR. `alpha.6.fix.3` restaure la classification générale `CANONICAL` / `MIRROR-EXACT` / `MIRROR-STABLE` et définit pour Tauri/frontend une synchronisation de jalon `X.Y.Z` par défaut, sans bump à chaque tranche.
|
||||||
|
|
||||||
|
Comme `fix.3` atteint le seuil de revue obligatoire des correctifs, le plan est réexaminé : résultat `CONTINUE`. Le scope Tauri reste cohérent et borné après cette correction ; les chantiers Rust `alpha.7`/`alpha.8` et la décision de skeleton `alpha.9` restent séparés et ne sont pas absorbés par le fix.
|
||||||
|
|
||||||
|
### alpha.7 — profil Rust strict, chemins et nomenclature explicite
|
||||||
|
|
||||||
|
La réconciliation des règles versionnées KSP/Games retient KSP comme référence stricte et Games comme contrôle de généralisation. Pour une nouvelle baseline contrôlée, `510-RUST_CARGO.md` impose désormais Rust 2024, réserve `use` aux traits réellement nécessaires, exige les chemins publics explicites les plus courts pour les autres symboles, les réexports internes `self::`, la façade crate-root et `crate::Item`, et conserve le contrôle de flux explicite sans `unwrap`, `expect` ni `?` en production.
|
||||||
|
|
||||||
|
La nomenclature des crates devient également explicite : préfixe projet/abréviation obligatoire ; responsabilité puis rôle/cible lisibles lorsque ce classificateur apporte une information réelle. La forme recommandée est `<project>-<responsibility>-<role-or-target>` sans figer les vocabulaires KSP/Games ni imposer de renommage rétroactif. Les projets externes ou historiquement contraints peuvent documenter un override borné.
|
||||||
|
|
||||||
|
Le skeleton Rust/Cargo et le guide de manifest reflètent ces choix. Aucun gros audit composite n'est importé ; le marqueur KSP spécifique des trait imports n'est pas généralisé et les contrôles déjà possédés par Clippy, rustc ou l'audit de façade restent chez leur owner.
|
||||||
|
|
||||||
|
La gate mécanique `alpha.7` est propre, mais la revue fonctionnelle post-gate montre que cette première matérialisation ne donnait pas encore de contrat architectural aux suffixes. `alpha.7.fix.1` complète donc la tranche sans la replanifier : `-api` devient un vrai contrat extensible/passif et n'est jamais créé par symétrie ; `-lib` identifie l'implémentation réutilisable ; les exécutables sont des packages distincts et minces par défaut ; `tracing` et un owner de logging commun sont fortement recommandés dans les workspaces multi-runtime. L'ancienne préférence KSP pour un worker mixte lib/bin n'est pas généralisée. Tauri reste l'exception framework actuelle et impose des noms de targets lib/bin réellement distincts.
|
||||||
|
|
||||||
|
### alpha.8 — formatage Rust structurel et audits monotâches
|
||||||
|
|
||||||
|
La réconciliation des anciens audits composites KSP/Games attribue désormais chaque propriété à un owner précis. Rustfmt reste propriétaire du formatage et du tri qu'il sait réellement réécrire dans un bloc contigu. Les audits PGR existants conservent `blank_lines` et `const_blocks`; quatre extractions monotâches complètent le profil : `item_spacing`, `module_order`, `trait_import_blocks` et `reexport_blocks`.
|
||||||
|
|
||||||
|
La mesure sur l'ensemble des sources `crates/**/*.rs` est propre pour les quatre nouveaux audits dans KSP `0.3.16` (`603` fichiers) et Games `0.3.5` (`87` fichiers). `blank_lines` est également propre sur ces corpus. `const_blocks` reste explicitement opt-in : son exécution globale remonte `18` signaux KSP, dont des tables/schémas à ordre intentionnel, contre `0` Games.
|
||||||
|
|
||||||
|
Le profil strict des nouvelles baselines contrôlées retient donc les règles mécaniques de lignes vides, séparation exacte des items distincts, modules production/tests, bloc de traits et blocs de réexports. PGR n'automatise pas un ordre global `enum → struct → impl → fn`, ni un tri visible/privé lorsque la structure métier peut être plus informative. Aucun parser Rust général ni audit composite n'est introduit.
|
||||||
|
|
||||||
|
### alpha.9 — décision de skeleton Tauri pour projets contrôlés — DEFER
|
||||||
|
|
||||||
|
La revue de readiness confirme que le host est suffisamment cadré : `510-RUST_CARGO.md` possède les règles Rust et le packaging, `710-TAURI.md` possède le layout contrôlé, l'exception `lib + bin`, `tauri.rs`, TS-RS à la frontière host/frontend, les plugins/capabilities, les versions produit et les gates d'orchestration Tauri. Les `8` hosts observés confirment également le layout direct sans `src-tauri/`, `frontend/`, Vite et TypeScript.
|
||||||
|
|
||||||
|
En revanche, PGR ne possède encore aucun profil Web/Vite/TypeScript/Sass. Le candidat organisationnel Vite + TypeScript + Sass + Bootstrap ne peut donc pas être instancié sans que le skeleton devienne de fait propriétaire de règles frontend, ce qui contredirait `220-SKELETONS.md` et le modèle de profils. La décision `alpha.9` est donc `DEFER` : aucun skeleton Tauri `003` n'est créé dans `0.0.5`.
|
||||||
|
|
||||||
|
Le futur skeleton reste un candidat explicite et devra au minimum composer la fondation de gouvernance, le skeleton Rust/Cargo, le profil Tauri et les owners Web alors disponibles. Il pourra ensuite sélectionner le layout direct, `frontend/`, Vite + TypeScript + Sass, Bootstrap comme baseline de présentation lorsque pertinente, TS-RS pour les DTO Rust partagés, intégration explicite des plugins/capabilities et séparation de WASM par défaut. Ces choix ne deviennent pas des règles Web dans la présente release.
|
||||||
|
|
||||||
|
La condition de sortie du `DEFER` est la matérialisation d'owners Web suffisants pour posséder la structure des sources frontend, la chaîne Vite/TypeScript, Sass/CSS, les artefacts de build et leur validation sans duplication normative dans le skeleton. La décision détaillée est enregistrée dans `docs/studies/002-TAURI_SKELETON_DECISION.md`.
|
||||||
|
|
||||||
|
### beta.1 — réconciliation intégrée
|
||||||
|
|
||||||
|
Rejouer la matrice de l'étude sur l'état PGR obtenu. Vérifier : owner unique, navigation, absence de règles KSP/Games aspirées par accident, caractère facultatif des patterns/audits concernés, cohérence des skeletons et domaines encore différés.
|
||||||
|
|
||||||
|
La réconciliation intégrée confirme que les owners créés ou renforcés par `0.0.5` restent bornés à leur responsabilité : prompt versionné, contrats documentaires facultatifs, lifecycle inter-release, profil/audits Rust stricts et profil Tauri. Les architectures métier KSP/Games, Android/JNI spécifique, Web autonome et distribution restent hors du noyau central tant qu'un owner réutilisable n'est pas justifié.
|
||||||
|
|
||||||
|
Le `DEFER` du skeleton Tauri contrôlé est suffisamment décidé pour devenir une trajectoire explicitement différée dans `ROADMAP.md`, sans numéro de release réservé. Les trois candidats plus larges de revue d'horizon restent volontairement hors de la roadmap engagée tant qu'une décision macro n'existe pas.
|
||||||
|
|
||||||
|
La mission `0.1.0` reste suffisamment connue : `prompts/006-V0_1_0_START_PROMPT.md` est préparé dans cette tranche comme prompt candidat de reprise. Il exige l'audit complet de la stable `0.0.5`, la consolidation d'un plan `0.1.0-alpha.1` proportionné et une revue d'horizon avant fermeture ; il ne transforme pas le skeleton Tauri différé en obligation de `0.1.0`.
|
||||||
|
|
||||||
|
Cette tranche réconcilie ainsi la documentation durable et confirme que le présent plan possède un contrat de fermeture exécutable avant `rc.1`.
|
||||||
|
|
||||||
|
La gate opérateur de `beta.1` est `PASS` : `48/48` tests Python, les trois audits Markdown, le contrôle d'intégration ciblé et les contrôles Git sont propres. La phase beta est donc fermée sans correctif.
|
||||||
|
|
||||||
|
### rc.1 — scope gelé et gate candidate
|
||||||
|
|
||||||
|
La RC gèle le scope fonctionnel de `0.0.5` sur les capacités déjà validées : contrats de reprise/lifecycle, profil Rust strict et ses audits monotâches, profil Tauri 2, réconciliation KSP/Games et décision `DEFER` du skeleton Tauri contrôlé. Aucun nouvel owner, skeleton, template, script d'audit ou domaine technique n'entre dans la candidate.
|
||||||
|
|
||||||
|
`CHANGELOG.md` reçoit l'entrée candidate `0.0.5` orientée utilisateurs. `ROADMAP.md` reste inchangé : `0.0.5` demeure en cours jusqu'à la promotion stable, `0.1.0` reste la prochaine release engagée et le skeleton Tauri reste `(d)` sans numéro de release. `prompts/006-V0_1_0_START_PROMPT.md` est vérifié comme prompt candidat de reprise et n'est pas modifié si son contrat est déjà correct.
|
||||||
|
|
||||||
|
La gate RC rejoue la suite Python complète, les audits Markdown et un contrôle d'intégrité historique de toutes les tranches `0.0.5`. Elle vérifie également la présence des owners/audits effectivement livrés et l'absence de skeleton Tauri `003`. Les validations lexicales déjà couvertes par la suite de tests ne sont pas dupliquées par un nouvel audit composite.
|
||||||
|
|
||||||
|
Aucune version postérieure à `0.1.0` n'est inventée à cette étape.
|
||||||
|
|
||||||
|
La gate opérateur de `rc.1` est `PASS` : `48/48` tests Python, les trois audits Markdown, le contrôle d'intégrité des `16` histories antérieurs et les contrôles Git sont propres. Le scope fonctionnel est donc gelé pour la promotion stable.
|
||||||
|
|
||||||
|
### stable — 0.0.5
|
||||||
|
|
||||||
|
Promouvoir mécaniquement la RC validée : synchroniser `VERSION`, README/index, `ROADMAP.md`, `CHANGELOG.md` et statut du présent plan sans ajouter de nouveau besoin commun. Après history PASS, commit et tag `v0.0.5`, vérifier séparément l'archive publiée.
|
||||||
|
|
||||||
|
La vérification post-tag doit produire, si le mécanisme reste retenu, `pgr-0.0.5-publish.001-report.md` extérieur au tag. Le message manuel final doit alors indiquer spontanément à l'opérateur de fournir l'archive taggée et ce rapport avec le prompt `006` lors de la session `0.1.0`.
|
||||||
|
|
||||||
|
La promotion `rel.001` clôt le présent plan sans modifier le scope fonctionnel : `VERSION = 0.0.5`, `ROADMAP.md` marque `0.0.5` terminé, le changelog perd son marqueur `candidate`, les index décrivent le plan comme historique et le prompt `006` reste conditionnel à la publication effective du tag et à son rapport post-tag PASS.
|
||||||
|
|
||||||
|
La gate opérateur de `rel.001` est toutefois `FAIL` pour un défaut strictement local à sa commande de validation : l'assertion Python qui cherchait le heading `## 0.0.5` a été livrée avec une chaîne simple coupée par un retour à la ligne et provoque `SyntaxError: unterminated string literal`. Les audits Markdown et les contrôles Git exécutés ensuite sont propres ; aucun défaut du contenu stable n'est établi. `rel.001.fix.1` corrige uniquement cette preuve de clôture, conserve `VERSION = 0.0.5` et ne rouvre pas le scope fonctionnel.
|
||||||
|
|
||||||
|
## Clôture et transition
|
||||||
|
|
||||||
|
Le présent plan attribue dès maintenant les responsabilités de fermeture :
|
||||||
|
|
||||||
|
- la documentation directement liée à chaque capacité évolue dans sa tranche ;
|
||||||
|
- `beta.1` réalise la réconciliation durable globale et prépare le prompt suivant si sa mission est connue ;
|
||||||
|
- `rc.1` porte le scope freeze, l'entrée `CHANGELOG` candidate, la vérification `ROADMAP` et le prompt suivant candidat ;
|
||||||
|
- `rel.001`/stable finalise `CHANGELOG`, marque `0.0.5` terminée dans `ROADMAP`, ferme le présent plan et effectue le promotion gate pré-tag ;
|
||||||
|
- `publish.001` vérifie l'archive réellement produite après le tag et fournit la preuve externe requise par la reprise suivante ;
|
||||||
|
- aucune de ces opérations ne doit être repoussée implicitement à la session `0.1.0`.
|
||||||
|
|
||||||
|
## Revue d'horizon
|
||||||
|
|
||||||
|
Pour PGR, la prochaine release engagée est `0.1.0 — première baseline réutilisable`. La trajectoire au-delà n'est pas suffisamment décidée et reste volontairement ouverte ; ce n'est pas un défaut de roadmap.
|
||||||
|
|
||||||
|
`0.0.5` ne doit donc pas inventer `0.1.1`, `0.2.0` ou un catalogue de versions futures. Le plan de `0.1.0-alpha.1` devra en revanche identifier un moment de revue d'horizon avant sa fermeture, une fois la baseline réutilisable suffisamment concrète pour juger la suite. Cette revue pourra se tenir dans une session stratégique séparée sans modifier `VERSION`.
|
||||||
|
|
||||||
|
Ses sorties autorisées seront : étendre la roadmap avec des objectifs réellement décidés, maintenir l'horizon ouvert avec un prochain déclencheur, différer/mettre en pause la trajectoire ou constater qu'un objectif macro est accompli.
|
||||||
|
|
||||||
|
Trois **candidats d'horizon**, sans numéro de release réservé ni engagement de réalisation, sont maintenant identifiés pour cette revue :
|
||||||
|
|
||||||
|
1. maturation de profils techniques composables par langage, framework, target/plateforme et préoccupation transverse — par exemple observability/logging, Web/TypeScript/Vite/Sass, Android, WASM, networking ou persistence — toujours à partir de corpus réels avant normalisation ;
|
||||||
|
2. profil de projet documentaire/spécification, avec `saselang-bible` comme corpus pilote possible pour tester gouvernance normative, terminologie, décisions, exemples, compatibilité et traduction lorsque la documentation est elle-même le produit ;
|
||||||
|
3. audit du noyau PGR hors développement logiciel afin d'identifier ce qui est réellement universel et ce qui doit rester dans un profil `software`, sans inventer les règles métier de domaines spécialisés.
|
||||||
|
|
||||||
|
Ces sujets restent au stade `horizon candidat`. Ils ne deviennent `Study`, `ROADMAP` ou plan de release qu'après décision explicite selon `300-DOCUMENTATION.md`.
|
||||||
|
|
||||||
|
## Points de décision
|
||||||
|
|
||||||
|
Un REPLAN est requis si :
|
||||||
|
|
||||||
|
- le contrat de prompt devient une copie exhaustive des règles plutôt qu'un artefact de reprise ;
|
||||||
|
- le pattern de contrats de fichiers ajoute plus de cérémonie qu'il n'en retire ;
|
||||||
|
- le lifecycle de clôture impose des documents ou versions futures sans valeur opérationnelle ;
|
||||||
|
- la revue d'horizon devient un quota de versions à prévoir plutôt qu'un mécanisme de décision ;
|
||||||
|
- l'audit de façade Rust ne peut pas être séparé proprement des conventions strictes KSP/Games ;
|
||||||
|
- le profil Tauri universel absorbe des choix de skeleton/frontend qui devraient rester project-specific ou appartenir à un owner Web ;
|
||||||
|
- la réconciliation Rust stricte ne peut pas être séparée en owners fiables et audits monotâches ;
|
||||||
|
- le skeleton Tauri n'apporte pas de décisions réutilisables au-delà du profil framework et des conventions explicites de projets contrôlés ;
|
||||||
|
- une autre divergence des corpus apparaît comme un besoin commun critique non couvert par ce plan.
|
||||||
|
|
||||||
|
## Stratégie de validation
|
||||||
|
|
||||||
|
Les tranches documentaires rejouent les trois audits Markdown et la suite Python PGR. Toute modification d'un script ajoute ou adapte des tests ciblés avant la suite globale. Les templates/configurations structurées sont parsés ou exercés avec l'outil le plus fiable disponible.
|
||||||
|
|
||||||
|
PGR ne compile pas KSP ou Games comme gate de sa propre release : ces projets servent de corpus de pression. Une validation croisée MAY exécuter leurs audits statiques sur leurs archives fournies lorsque cela vérifie une propriété précise, mais ne remplace jamais leurs propres gates opérateur.
|
||||||
|
|
||||||
|
La toolchain Cargo n'étant pas disponible dans l'environnement de préparation de `alpha.1`, aucune preuve Cargo externe n'est revendiquée pour cette tranche. La gate PGR reste documentaire et structurelle.
|
||||||
310
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
Normal file
310
docs/plans/006-V0_1_0_REUSABLE_BASELINE_PLAN.md
Normal 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`.
|
||||||
506
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
Normal file
506
docs/plans/007-V0_1_1_WEB_FRONTEND_FOUNDATION_PLAN.md
Normal 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.
|
||||||
467
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
Normal file
467
docs/plans/008-V0_1_2_JAVA_GRADLE_REEVALUATION_PLAN.md
Normal 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.
|
||||||
617
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
Normal file
617
docs/plans/009-V0_1_3_ANDROID_REEVALUATION_PLAN.md
Normal 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.
|
||||||
433
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
Normal file
433
docs/plans/010-V0_1_4_TAURI_REEVALUATION_PLAN.md
Normal 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`.
|
||||||
397
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
Normal file
397
docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
<!-- file: docs/plans/011-V0_1_5_NORMATIVE_AUTONOMY_PLAN.md -->
|
||||||
|
<!-- version: 8 -->
|
||||||
|
|
||||||
|
# Plan 0.1.5 — sémantique normative, autonomie et frontière PGR / Knowledge
|
||||||
|
|
||||||
|
## Objet
|
||||||
|
|
||||||
|
`0.1.5` stabilise trois contrats transversaux décidés par la revue d’horizon `0.1.4` avant toute nouvelle adoption réelle : la force de `MUST / SHOULD / MAY`, l’autonomie d’un projet après instanciation ou adoption, et la frontière entre le référentiel normatif PGR et les contenus pratiques candidats à SaseDev Knowledge.
|
||||||
|
|
||||||
|
La release ne doit ni réécrire mécaniquement toutes les recommandations existantes, ni traiter PGR comme un upstream vivant des projets déjà adoptés, ni déplacer du contenu vers Knowledge sans corpus de destination autoritaire.
|
||||||
|
|
||||||
|
## Baseline et preuves d’ouverture
|
||||||
|
|
||||||
|
La baseline autoritaire est l’archive du tag Gitea `v0.1.4`.
|
||||||
|
|
||||||
|
```text
|
||||||
|
archive canonique pgr-v0.1.4.zip
|
||||||
|
archive reçue pgr-v0.1.4(1).zip
|
||||||
|
SHA-256 9f85ac16a5ad9fd788df51883b6ebf592602c5189d94e338a86edab2288b8f77
|
||||||
|
CRC PASS
|
||||||
|
VERSION 0.1.4
|
||||||
|
racine ZIP pgr/
|
||||||
|
fichiers 310
|
||||||
|
répertoires 44
|
||||||
|
symlink 0
|
||||||
|
.git dans l'archive absent — attendu pour une archive de tag
|
||||||
|
```
|
||||||
|
|
||||||
|
La publication post-tag associée a été clôturée `PASS` sous `pgr-0.1.4-publish.001-report.md`. Sa preuve établit le SHA canonique ci-dessus, la publication de la stable `0.1.4` et l’autorisation du handoff vers `prompts/011-V0_1_5_START_PROMPT.md`.
|
||||||
|
|
||||||
|
Le replay indépendant de la baseline avant préparation de `alpha.1` confirme :
|
||||||
|
|
||||||
|
```text
|
||||||
|
tests Python 55/55 PASS
|
||||||
|
audit hygiène texte 309 fichiers PASS
|
||||||
|
audit headers Markdown 282 fichiers PASS
|
||||||
|
audit tables Markdown 11 tables / 282 fichiers PASS
|
||||||
|
audit liens Markdown 357 liens locaux / 282 fichiers PASS
|
||||||
|
JSON 2 fichiers parsés
|
||||||
|
TOML 5 fichiers parsés
|
||||||
|
deltas historiques 103
|
||||||
|
histories historiques 103
|
||||||
|
appariement delta/history exact pour 0.0.1 à 0.1.4
|
||||||
|
```
|
||||||
|
|
||||||
|
La séquence `0.1.4` est conservée telle que publiée :
|
||||||
|
|
||||||
|
```text
|
||||||
|
alpha.1 PASS
|
||||||
|
alpha.2 FAIL
|
||||||
|
alpha.2.fix.1 PASS
|
||||||
|
alpha.3 PASS
|
||||||
|
beta.1 PASS
|
||||||
|
rc.1 PASS
|
||||||
|
rel.1 PASS
|
||||||
|
```
|
||||||
|
|
||||||
|
Le `FAIL` de `alpha.2` et son correctif restent des faits historiques ; `0.1.5` ne les réécrit pas.
|
||||||
|
|
||||||
|
## Sources de cadrage
|
||||||
|
|
||||||
|
La release part au minimum de :
|
||||||
|
|
||||||
|
- `RULES.md` ;
|
||||||
|
- `docs/rules/200-GOVERNANCE.md` ;
|
||||||
|
- `docs/rules/210-WORKFLOW.md` ;
|
||||||
|
- `docs/rules/220-SKELETONS.md` ;
|
||||||
|
- `docs/rules/230-ADOPTION.md` ;
|
||||||
|
- `docs/rules/400-VALIDATION.md` ;
|
||||||
|
- `docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` ;
|
||||||
|
- `docs/templates/003-NEW_SESSION_PROMPT.md` ;
|
||||||
|
- `docs/templates/007-EXISTING_PROJECT_ADOPTION.md` ;
|
||||||
|
- `docs/studies/004-V0_1_4_HORIZON_REVIEW.md` ;
|
||||||
|
- `prompts/011-V0_1_5_START_PROMPT.md`.
|
||||||
|
|
||||||
|
Les owners et artefacts adjacents ne sont modifiés que lorsqu’une ambiguïté transversale réelle les concerne.
|
||||||
|
|
||||||
|
## Contrats cibles
|
||||||
|
|
||||||
|
### Force normative
|
||||||
|
|
||||||
|
La release doit rendre non ambigu le contrat suivant :
|
||||||
|
|
||||||
|
```text
|
||||||
|
MUST / MUST NOT obligation ou interdiction normative
|
||||||
|
SHOULD / SHOULD NOT forte recommandation non obligatoire
|
||||||
|
MAY possibilité neutre
|
||||||
|
```
|
||||||
|
|
||||||
|
Un écart à un `SHOULD` ou `SHOULD NOT` :
|
||||||
|
|
||||||
|
- ne constitue pas à lui seul une non-conformité ;
|
||||||
|
- ne fait pas échouer à lui seul une gate ;
|
||||||
|
- n’exige pas automatiquement un `OVERRIDE` ;
|
||||||
|
- peut être documenté lorsque la raison apporte une valeur durable de maintenance, architecture ou reprise.
|
||||||
|
|
||||||
|
Une contradiction avec un `MUST` réellement applicable reste distincte et continue d’exiger le traitement prévu par l’owner concerné, l’exception ou l’override autorisé.
|
||||||
|
|
||||||
|
### Autonomie après instanciation ou adoption
|
||||||
|
|
||||||
|
Le cycle cible est :
|
||||||
|
|
||||||
|
```text
|
||||||
|
snapshot PGR explicitement choisi
|
||||||
|
↓
|
||||||
|
instanciation / adoption / adaptation
|
||||||
|
↓
|
||||||
|
baseline locale du projet
|
||||||
|
↓
|
||||||
|
autorité locale pour les sessions et releases suivantes
|
||||||
|
```
|
||||||
|
|
||||||
|
Après établissement de la baseline locale, le projet destinataire ne recherche pas automatiquement une version PGR plus récente et ne traite pas PGR comme une dépendance documentaire implicite. Un réalignement futur reste possible uniquement comme opération explicite et bornée, à partir d’un nouveau snapshot PGR choisi et d’une nouvelle comparaison des écarts.
|
||||||
|
|
||||||
|
### Frontière PGR / SaseDev Knowledge
|
||||||
|
|
||||||
|
PGR reste auto-suffisant pour comprendre et appliquer ses exigences.
|
||||||
|
|
||||||
|
PGR conserve notamment les contrats normatifs et de gouvernance, les owners, les skeleton specifications minimales, les templates nécessaires à un contrat réutilisable et les validations directement liées aux règles.
|
||||||
|
|
||||||
|
Les howtos détaillés, recettes pratiques, snippets, exemples d’intégration, dépannage, comparatifs et variantes d’implémentation sont des candidats à Knowledge. Cette classification n’autorise aucun déplacement automatique pendant `0.1.5` et ne crée aucune dépendance de PGR vers Knowledge.
|
||||||
|
|
||||||
|
## Inventaire transversal `alpha.1`
|
||||||
|
|
||||||
|
L’inventaire a recherché les formulations `SHOULD / SHOULD NOT`, les contrats d’override, l’autonomie post-adoption et les termes qui confondent spécification normative et recette pratique.
|
||||||
|
|
||||||
|
Sur le corpus normatif/documentaire courant analysé, `29` fichiers contiennent au moins un `SHOULD` ou `SHOULD NOT`, pour `242` occurrences textuelles brutes. Ce volume interdit une conversion mécanique : la majorité de ces recommandations sont légitimes et doivent seulement hériter d’une sémantique globale claire.
|
||||||
|
|
||||||
|
### Ambiguïtés normatives observées en `alpha.1`
|
||||||
|
|
||||||
|
Avant `alpha.2`, `RULES.md` décrivait `SHOULD / SHOULD NOT` comme un comportement attendu avec dérogation lorsque l’alternative était « mieux adaptée et justifiée ». Cette formulation pouvait rendre la justification obligatoire et a désigné `RULES.md` comme owner primaire de la clarification.
|
||||||
|
|
||||||
|
Avant `alpha.2`, `RULES.md` exigeait aussi un override pour toute contradiction intentionnelle sans distinguer explicitement une contradiction à une obligation d’un simple choix différent d’une recommandation.
|
||||||
|
|
||||||
|
Avant `alpha.2`, `docs/rules/400-VALIDATION.md` ne précisait pas qu’un écart à un `SHOULD` ne peut pas, à lui seul, faire échouer une gate.
|
||||||
|
|
||||||
|
Avant `alpha.2`, `docs/rules/230-ADOPTION.md` définissait `OVERRIDE` comme le remplacement ou raffinement d’une règle PGR applicable. Sans clarification de la force normative, cette définition pouvait pousser à créer un override pour une simple recommandation non suivie.
|
||||||
|
|
||||||
|
`docs/rules/500-LANGUAGES.md` et `docs/rules/700-FRAMEWORKS.md` utilisaient des formulations d’exception/override pouvant renforcer accidentellement un `SHOULD` ; `alpha.2` les a donc inclus dans la réconciliation ciblée.
|
||||||
|
|
||||||
|
Les cas concrets observés pendant `alpha.1` confirmaient que l’ambiguïté n’était pas théorique :
|
||||||
|
|
||||||
|
- `docs/rules/530-TYPESCRIPT.md` associe une recommandation à une incompatibilité documentée ;
|
||||||
|
- `docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` demandait alors, pour la politique de lockfile, soit l’adoption de la recommandation soit un `OVERRIDE` ;
|
||||||
|
- `docs/skeletons/003-WEB_FRONTEND.md` exigeait une justification lorsqu’une nouvelle baseline durable n’adoptait pas la recommandation TypeScript ;
|
||||||
|
- `docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md` imposait une décision locale ou un `OVERRIDE` avec justification pour une politique de lockfile différente.
|
||||||
|
|
||||||
|
Ces cas ont été retenus pour une correction ciblée en `alpha.2`, sans affaiblir les `MUST` réellement applicables.
|
||||||
|
|
||||||
|
### Ambiguïté de trajectoire observée en `alpha.1`
|
||||||
|
|
||||||
|
Avant `alpha.2`, `docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` conservait une référence vivante à « l’adoption `0.1.5` de Games ». La revue d’horizon `0.1.4` avait déplacé cette adoption en `0.1.6`. `alpha.2` corrige cette référence vivante sans modifier les plans, études, prompts ou histories qui décrivent correctement l’ancien horizon dans leur contexte historique.
|
||||||
|
|
||||||
|
### Autonomie — acquis à conserver
|
||||||
|
|
||||||
|
Plusieurs contrats sont déjà compatibles avec la cible :
|
||||||
|
|
||||||
|
- `docs/objectives/001-PROJECT_OBJECTIVES.md` interdit de créer une dépendance vers PGR après instanciation et exclut la maintenance automatique des projets créés ;
|
||||||
|
- `docs/architecture/002-GOVERNANCE_ARCHITECTURE.md` dit déjà que le projet possède sa copie et qu’une évolution ultérieure de PGR ne le modifie pas automatiquement ;
|
||||||
|
- `docs/rules/220-SKELETONS.md` attribue les fichiers, décisions et règles locales au projet après instanciation ;
|
||||||
|
- `docs/templates/003-NEW_SESSION_PROMPT.md` repart de la baseline stable du projet lui-même et ne reconstruit pas une source absente ;
|
||||||
|
- `docs/templates/007-EXISTING_PROJECT_ADOPTION.md` conclut déjà sur un projet autonome.
|
||||||
|
|
||||||
|
Ces acquis doivent être consolidés plutôt que réécrits en bloc.
|
||||||
|
|
||||||
|
### Autonomie — gaps à fermer
|
||||||
|
|
||||||
|
`RULES.md` interdit seulement la dépendance runtime/build et doit expliciter l’absence d’upstream documentaire PGR implicite.
|
||||||
|
|
||||||
|
`docs/rules/230-ADOPTION.md` doit établir clairement que la baseline locale devient l’autorité des sessions/releases suivantes et qu’un réalignement PGR ultérieur est une opération explicite.
|
||||||
|
|
||||||
|
`docs/rules/220-SKELETONS.md`, `docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md` et `docs/templates/007-EXISTING_PROJECT_ADOPTION.md` doivent propager ce contrat au point d’instanciation/adoption. Une éventuelle dépendance documentaire externe explicitement choisie par un projet reste sa décision locale ; elle ne transforme pas PGR en upstream implicite.
|
||||||
|
|
||||||
|
`docs/rules/210-WORKFLOW.md` et `docs/templates/003-NEW_SESSION_PROMPT.md` sont, à ce stade, classés `KEEP` sauf contradiction découverte pendant la réconciliation : leur notion de baseline autoritaire est déjà celle du projet courant.
|
||||||
|
|
||||||
|
### Frontière Knowledge — ambiguïtés confirmées
|
||||||
|
|
||||||
|
`docs/objectives/001-PROJECT_OBJECTIVES.md` et `docs/architecture/002-GOVERNANCE_ARCHITECTURE.md` qualifient encore un skeleton de « recette Markdown ». Or `0.1.5` réserve précisément les recettes pratiques à la famille de contenus candidats à Knowledge. Le terme doit être remplacé par une formulation de type « spécification Markdown composable » afin de préserver la nature normative/structurelle du skeleton.
|
||||||
|
|
||||||
|
`docs/rules/300-DOCUMENTATION.md` est l’owner naturel pour formaliser la frontière documentaire sans créer un owner Knowledge artificiel. PGR ne doit pas créer une règle ou une collection dédiée uniquement parce que Knowledge existe comme produit séparé.
|
||||||
|
|
||||||
|
## Owners issus de l'inventaire
|
||||||
|
|
||||||
|
L'inventaire `alpha.1` a fixé les owners ci-dessous. Leur modification reste répartie par tranche afin de ne pas mélanger sémantique normative, autonomie et frontière Knowledge.
|
||||||
|
|
||||||
|
```text
|
||||||
|
sémantique primaire
|
||||||
|
RULES.md MODIFY alpha.2
|
||||||
|
docs/rules/230-ADOPTION.md MODIFY alpha.2 puis alpha.3
|
||||||
|
docs/rules/400-VALIDATION.md MODIFY alpha.2
|
||||||
|
|
||||||
|
réconciliation ciblée des effets SHOULD
|
||||||
|
docs/rules/500-LANGUAGES.md MODIFY alpha.2
|
||||||
|
docs/rules/530-TYPESCRIPT.md MODIFY alpha.2
|
||||||
|
docs/rules/540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md MODIFY alpha.2
|
||||||
|
docs/rules/700-FRAMEWORKS.md MODIFY alpha.2
|
||||||
|
docs/skeletons/003-WEB_FRONTEND.md MODIFY alpha.2
|
||||||
|
docs/templates/008-WEB_TYPESCRIPT_PACKAGE.md MODIFY alpha.2
|
||||||
|
|
||||||
|
autonomie
|
||||||
|
RULES.md MODIFY alpha.3
|
||||||
|
docs/rules/220-SKELETONS.md MODIFY alpha.3
|
||||||
|
docs/rules/230-ADOPTION.md MODIFY alpha.3
|
||||||
|
docs/skeletons/001-PROJECT_GOVERNANCE_FOUNDATION.md MODIFY alpha.3
|
||||||
|
docs/templates/007-EXISTING_PROJECT_ADOPTION.md MODIFY alpha.3
|
||||||
|
docs/rules/210-WORKFLOW.md KEEP / REVIEW
|
||||||
|
docs/templates/003-NEW_SESSION_PROMPT.md KEEP / REVIEW
|
||||||
|
|
||||||
|
frontière PGR / Knowledge
|
||||||
|
docs/objectives/001-PROJECT_OBJECTIVES.md MODIFY alpha.4
|
||||||
|
docs/architecture/002-GOVERNANCE_ARCHITECTURE.md MODIFY alpha.4
|
||||||
|
docs/rules/300-DOCUMENTATION.md MODIFY alpha.4
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun nouveau owner Knowledge n’est prévu par défaut.
|
||||||
|
|
||||||
|
## Progression acquise avant `beta.1`
|
||||||
|
|
||||||
|
La première gate `alpha.1` a acquis les tests et audits principaux mais n'a pas exécuté toutes les assertions contractuelles prévues par son delta. Son history conserve donc le résultat réel `PARTIAL`.
|
||||||
|
|
||||||
|
`alpha.1.fix.1` a été limité à l'acquisition des preuves manquantes : trajectoire ROADMAP, frontière delta/history, assertions du prompt `011`, assertions du présent plan et audits documentaires. Cette récupération est `PASS` et n'a modifié aucun owner normatif.
|
||||||
|
|
||||||
|
La tranche `alpha.2` a ensuite appliqué la sémantique centrale sans réécrire les `242` occurrences de recommandations. Les modifications ont été bornées aux owners et artefacts où l'inventaire avait démontré un renforcement accidentel ou une référence vivante obsolète : `RULES.md`, `230`, `400`, `500`, `530`, `540`, `700`, le skeleton Web `003` et le guide `008`. Sa gate opérateur du `2026-10-01` est `PASS` avec `55/55` tests et les audits documentaires propres.
|
||||||
|
|
||||||
|
Décisions acquises en `alpha.2` :
|
||||||
|
|
||||||
|
- `SHOULD / SHOULD NOT` devient explicitement une forte recommandation non obligatoire ;
|
||||||
|
- un écart à cette recommandation ne crée ni non-conformité, ni `FAIL` de gate, ni `OVERRIDE` automatique ;
|
||||||
|
- un projet MAY documenter la raison d'un écart lorsqu'elle apporte une valeur durable ;
|
||||||
|
- les contradictions avec des obligations `MUST / MUST NOT` restent soumises aux contrats d'exception/override applicables ;
|
||||||
|
- la référence vivante à l'adoption Games est corrigée de `0.1.5` vers `0.1.6` ;
|
||||||
|
- l'autonomie post-adoption est mise en œuvre par `alpha.3` ; la frontière Knowledge reste réservée à `alpha.4`.
|
||||||
|
|
||||||
|
Décisions de mise en œuvre `alpha.3` :
|
||||||
|
|
||||||
|
- après instanciation ou adoption, la baseline locale et ses owners deviennent l'autorité des sessions/releases suivantes ;
|
||||||
|
- PGR ne devient ni dépendance documentaire implicite ni upstream à suivre et aucun mécanisme ne doit rechercher automatiquement « la dernière version de PGR » ;
|
||||||
|
- un réalignement futur exige une opération explicitement décidée et bornée, fondée sur un snapshot PGR précis choisi par le projet ;
|
||||||
|
- ce réalignement compare le snapshot choisi à la baseline locale, reclassifie les écarts utiles et préserve les histories au lieu de mettre à jour silencieusement la gouvernance ;
|
||||||
|
- `210-WORKFLOW.md` et `003-NEW_SESSION_PROMPT.md` restent `KEEP` : leur contrat de reprise depuis la baseline autoritaire du projet est déjà compatible ;
|
||||||
|
- la frontière PGR / SaseDev Knowledge reste réservée à `alpha.4`.
|
||||||
|
|
||||||
|
La gate opérateur de `alpha.3` du `2026-10-01` est `PASS` avec `55/55` tests, les audits documentaires propres et le scope Git attendu. Le contrat d'autonomie locale est donc acquis avant ouverture de `alpha.4`.
|
||||||
|
|
||||||
|
Décisions de mise en œuvre `alpha.4` :
|
||||||
|
|
||||||
|
- remplacer les formulations « recette Markdown » des skeletons par « spécification Markdown composable » afin de ne pas confondre contrat structurel PGR et recette pratique ;
|
||||||
|
- formaliser dans `300-DOCUMENTATION.md` une frontière documentaire où PGR possède les éléments nécessaires à ses contrats normatifs et où les howtos détaillés, recettes, snippets, exemples, dépannage, comparatifs et variantes MAY vivre dans une base de connaissances séparée ;
|
||||||
|
- mentionner SaseDev Knowledge uniquement comme destination pratique possible, jamais comme owner normatif ni dépendance requise ;
|
||||||
|
- imposer l'auto-suffisance de PGR : aucun howto/snippet externe ne peut être nécessaire pour déterminer la force, le scope ou les exigences d'une règle PGR ;
|
||||||
|
- conserver toute migration physique hors scope de `0.1.5` tant qu'une destination Knowledge autoritaire n'est pas explicitement fournie et vérifiée ;
|
||||||
|
- ne créer aucun nouvel owner Knowledge et ne modifier aucun history antérieur.
|
||||||
|
|
||||||
|
La gate opérateur de `alpha.4` du `2026-10-01` est `PASS` avec `55/55` tests, les audits documentaires propres, les owners hors scope inchangés et le scope Git attendu. La frontière PGR / Knowledge est donc acquise avant ouverture de `beta.1`.
|
||||||
|
|
||||||
|
## Réconciliation transversale préparée en `beta.1`
|
||||||
|
|
||||||
|
Le rescan préparatoire de la baseline post-`alpha.4` n'a démontré aucun nouveau défaut normatif exigeant une modification d'owner.
|
||||||
|
|
||||||
|
Les formulations `SHOULD / SHOULD NOT` des owners vivants ont été relues avec attention lorsqu'un `MUST`, une justification ou une contrainte conditionnelle apparaissait dans le même contexte. Les cas conservés portent des responsabilités distinctes et ne transforment pas le simple écart à la recommandation en non-conformité : outputs/caches générés à ignorer lorsqu'ils restent dans l'arbre, ouverture réseau/CORS à borner, identité Android à rendre explicite, dépendance Sass interne à garder visible/révisable et surface de sécurité Tauri à décider explicitement.
|
||||||
|
|
||||||
|
La réconciliation confirme également :
|
||||||
|
|
||||||
|
- `RULES.md`, `230-ADOPTION.md` et `400-VALIDATION.md` portent une sémantique cohérente : un écart à `SHOULD / SHOULD NOT` ne crée à lui seul ni `FAIL`, ni `OVERRIDE`, ni justification obligatoire ;
|
||||||
|
- `220-SKELETONS.md`, `230-ADOPTION.md`, `001-PROJECT_GOVERNANCE_FOUNDATION.md` et `007-EXISTING_PROJECT_ADOPTION.md` conservent la baseline locale comme autorité et le réalignement PGR comme opération explicite sur snapshot choisi ;
|
||||||
|
- `210-WORKFLOW.md` et `003-NEW_SESSION_PROMPT.md` restent `KEEP` : aucune recherche automatique de version PGR plus récente n'y est introduite ;
|
||||||
|
- `001-PROJECT_OBJECTIVES.md`, `002-GOVERNANCE_ARCHITECTURE.md` et `300-DOCUMENTATION.md` maintiennent PGR auto-suffisant et Knowledge strictement complémentaire ;
|
||||||
|
- la référence vivante Games dans `540-JAVASCRIPT_PACKAGE_ECOSYSTEM.md` pointe bien vers `0.1.6` ; les anciennes mentions `0.1.5` conservées dans des études/index historiques restent des descriptions de l'horizon de leur époque et ne sont pas réécrites ;
|
||||||
|
- les scopes Games `0.1.6`, KSP `0.1.7` et audits Rust/Clippy `0.1.8` restent réservés et aucun `0.1.9` n'est créé.
|
||||||
|
|
||||||
|
Décision `beta.1` : **KEEP des owners normatifs acquis**. La tranche documente et valide la réconciliation ; elle n'ajoute aucun owner, ne modifie aucune règle normative et ne commence aucun scope futur.
|
||||||
|
|
||||||
|
La gate opérateur de `beta.1` du `2026-10-01` est `PASS` avec `55/55` tests, l'audit d'hygiène texte propre sur `321` fichiers, les audits Markdown propres et le scope Git attendu. La phase de réconciliation est donc acquise avant ouverture de `rc.1`.
|
||||||
|
|
||||||
|
## Freeze et revue d’horizon préparés en `rc.1`
|
||||||
|
|
||||||
|
`rc.1` gèle les owners normatifs acquis : aucune règle, skeleton, template ou validation stabilisés pendant `alpha.2` à `alpha.4` n'est réouvert sans défaut démontré.
|
||||||
|
|
||||||
|
La revue d'horizon limitée matérialisée dans `docs/studies/005-V0_1_5_HORIZON_REVIEW.md` conclut qu'aucun nouveau prérequis transversal ne doit précéder l'adoption Games. La trajectoire reste :
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.1.6 adoption sasedev-games
|
||||||
|
0.1.7 adoption khadhroony-solana-project
|
||||||
|
0.1.8 audits Rust/Clippy read-only
|
||||||
|
0.1.9 NOT RESERVED
|
||||||
|
```
|
||||||
|
|
||||||
|
Le prompt `012-V0_1_6_START_PROMPT.md` prépare donc une reprise `0.1.6-alpha.1` à partir d'une future stable PGR `v0.1.5` réellement publiée et d'une archive Games récente explicitement autoritaire. Il impose un intake/cartographie avant toute migration et conserve le contrat d'autonomie locale après adoption.
|
||||||
|
|
||||||
|
La RC ne commence ni l'adoption Games, ni KSP, ni les audits `0.1.8`.
|
||||||
|
|
||||||
|
## Gate `rc.1` en échec documentaire et correctif `rc.1.fix.1`
|
||||||
|
|
||||||
|
La gate opérateur de `rc.1` du `2026-10-01` conserve les `55/55` tests `PASS`, les audits documentaires propres, le freeze des owners et le scope Git attendu, mais trois assertions textuelles exactes du delta n'ont produit aucune correspondance. Le history `history/0.1.5/rc.1.md` enregistre donc le résultat réel `FAIL`.
|
||||||
|
|
||||||
|
Le correctif `rc.1.fix.1` est borné à la présentation documentaire :
|
||||||
|
|
||||||
|
- employer dans `CHANGELOG.md` la formule canonique `forte recommandation non obligatoire` attendue par la gate ;
|
||||||
|
- rendre explicite dans la revue d'horizon que `aucun numéro de version Games n’est figé` ;
|
||||||
|
- matérialiser la classification canonique `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER / N/A` dans cette même étude ;
|
||||||
|
- ne modifier aucun owner normatif, skeleton, template, contrat de validation, roadmap, handoff `012` ou history antérieur.
|
||||||
|
|
||||||
|
`rel.1` reste bloqué tant que `rc.1.fix.1` n’est pas validé `PASS`.
|
||||||
|
|
||||||
|
## Gate `rc.1.fix.1` acquise et promotion stable
|
||||||
|
|
||||||
|
La gate opérateur de `rc.1.fix.1` du `2026-10-01` est `PASS` : les trois assertions documentaires qui avaient fait échouer `rc.1` correspondent désormais, les `55/55` tests passent, les audits d'hygiène/Markdown sont propres et le scope Git est exactement celui du correctif.
|
||||||
|
|
||||||
|
Le history `history/0.1.5/rc.1.fix.1.md` conserve ce `PASS` sans modifier le `FAIL` historique de `rc.1`.
|
||||||
|
|
||||||
|
`rel.1` peut donc promouvoir mécaniquement la candidate vers la stable `0.1.5`. Cette promotion :
|
||||||
|
|
||||||
|
- fixe `VERSION` à `0.1.5` ;
|
||||||
|
- retire le marqueur `candidate` du changelog ;
|
||||||
|
- marque `0.1.5` terminé dans la roadmap ;
|
||||||
|
- présente `README.md`, l'index documentaire et le présent plan comme état stable/historique ;
|
||||||
|
- conserve `0.1.6` Games, `0.1.7` KSP et `0.1.8` audits comme trajectoire engagée ;
|
||||||
|
- ne commence aucun scope `0.1.6` et ne réserve aucun `0.1.9`.
|
||||||
|
|
||||||
|
Après un history `rel.1` `PASS`, le commit produit MUST être `0.1.5` sans suffixe `rel.1`, puis le tag annoté `v0.1.5` et son archive doivent être publiés et vérifiés indépendamment. Le rapport `pgr-0.1.5-publish.001-report.md` ne peut être produit qu'après cette publication réelle.
|
||||||
|
|
||||||
|
Le plan devient historique avec la stable `0.1.5`.
|
||||||
|
|
||||||
|
## Trajectoire de release
|
||||||
|
|
||||||
|
### `alpha.1` — intake, audit transversal et plan
|
||||||
|
|
||||||
|
- vérifier la baseline stable `0.1.4` et sa chaîne delta/history ;
|
||||||
|
- relire le handoff `011` et la revue d’horizon `004` ;
|
||||||
|
- inventorier les ambiguïtés normatives, d’autonomie et de frontière Knowledge ;
|
||||||
|
- proposer les owners exacts ;
|
||||||
|
- ne modifier aucune règle normative.
|
||||||
|
|
||||||
|
### `alpha.2` — sémantique normative et conséquences de gate/adoption
|
||||||
|
|
||||||
|
- stabiliser `MUST / SHOULD / MAY` dans l’owner primaire ;
|
||||||
|
- aligner `230-ADOPTION.md` et `400-VALIDATION.md` ;
|
||||||
|
- corriger les cas concrets où une recommandation est transformée en justification/override obligatoire ;
|
||||||
|
- corriger la référence vivante obsolète à l’adoption Games `0.1.5` ;
|
||||||
|
- conserver les obligations réelles et les histories inchangées.
|
||||||
|
|
||||||
|
### `alpha.3` — autonomie locale et réalignement volontaire
|
||||||
|
|
||||||
|
- expliciter la baseline locale comme autorité après instanciation/adoption ;
|
||||||
|
- interdire la recherche automatique de « la dernière PGR » dans le contrat d’adoption ;
|
||||||
|
- définir le réalignement futur comme scope explicite fondé sur un snapshot choisi ;
|
||||||
|
- propager le contrat aux skeleton/patterns concernés sans réécriture des documents déjà corrects.
|
||||||
|
|
||||||
|
### `alpha.4` — frontière PGR / SaseDev Knowledge
|
||||||
|
|
||||||
|
- clarifier la taxonomie normative/pratique ;
|
||||||
|
- remplacer les formulations « recette Markdown » qui brouillent la nature des skeleton specifications ;
|
||||||
|
- maintenir PGR auto-suffisant ;
|
||||||
|
- ne déplacer aucun contenu vers Knowledge sans destination autoritaire fournie.
|
||||||
|
|
||||||
|
### `beta.1` — réconciliation transversale
|
||||||
|
|
||||||
|
- rescanner toutes les formulations `SHOULD / SHOULD NOT` pour détecter les renforcements accidentels restants ;
|
||||||
|
- vérifier les références à l’autonomie, aux snapshots et aux overrides ;
|
||||||
|
- rechercher les références vivantes devenues obsolètes après la revue d’horizon ;
|
||||||
|
- vérifier que Games `0.1.6`, KSP `0.1.7` et les audits Rust `0.1.8` n’ont pas été commencés ;
|
||||||
|
- exécuter les validations PGR complètes et proportionnées.
|
||||||
|
|
||||||
|
### `rc.1` — freeze et handoff
|
||||||
|
|
||||||
|
- figer les contrats stabilisés ;
|
||||||
|
- mettre à jour la présentation stable/candidate et la roadmap selon l’état réellement atteint ;
|
||||||
|
- préparer le prompt de reprise suivant uniquement si la trajectoire vers `0.1.6` reste valide ;
|
||||||
|
- effectuer une revue d’horizon limitée aux dépendances réellement révélées par `0.1.5`.
|
||||||
|
|
||||||
|
### `rel.1` — promotion stable
|
||||||
|
|
||||||
|
- promouvoir la RC validée sans nouveau scope fonctionnel ;
|
||||||
|
- produire le history réel de clôture ;
|
||||||
|
- préparer la publication/tag stable puis sa vérification post-tag selon le workflow PGR.
|
||||||
|
|
||||||
|
## Hors scope maintenu
|
||||||
|
|
||||||
|
`0.1.5` ne commence pas :
|
||||||
|
|
||||||
|
- l’adoption réelle de `sasedev-games`, réservée à `0.1.6` ;
|
||||||
|
- l’adoption réelle de `khadhroony-solana-project`, réservée à `0.1.7` ;
|
||||||
|
- les audits Rust/Clippy read-only, réservés à `0.1.8` ;
|
||||||
|
- une réouverture du domaine Tauri sans défaut transversal démontré ;
|
||||||
|
- une migration physique vers SaseDev Knowledge ;
|
||||||
|
- une conversion globale de tous les `SHOULD` en `MUST` ou `MAY`.
|
||||||
|
|
||||||
|
## Gate de planification `alpha.1` — historique
|
||||||
|
|
||||||
|
`alpha.1` était prête à validation opérateur lorsque :
|
||||||
|
|
||||||
|
- la baseline `0.1.4` a été rejouée proprement ;
|
||||||
|
- l’historique `0.1.4` reste intact, y compris `alpha.2 FAIL` puis `alpha.2.fix.1 PASS` ;
|
||||||
|
- les ambiguïtés ci-dessus sont traçables à des owners existants ;
|
||||||
|
- aucune règle normative n’est modifiée par la tranche ;
|
||||||
|
- le plan conserve une séparation explicite entre sémantique, autonomie et frontière Knowledge ;
|
||||||
|
- les scopes `0.1.6`, `0.1.7` et `0.1.8` restent réservés.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/rules/000-README.md -->
|
<!-- file: docs/rules/000-README.md -->
|
||||||
<!-- version: 10 -->
|
<!-- version: 16 -->
|
||||||
|
|
||||||
# Index des règles PGR
|
# Index des règles PGR
|
||||||
|
|
||||||
@@ -12,14 +12,24 @@ Les règles générales actuellement nécessaires restent dans `RULES.md`. La fa
|
|||||||
## Familles actives
|
## Familles actives
|
||||||
|
|
||||||
- [`200-GOVERNANCE.md`](200-GOVERNANCE.md) — versioning, lifecycle des releases, fixes, cadrage, replan et abandon/supersession.
|
- [`200-GOVERNANCE.md`](200-GOVERNANCE.md) — versioning, lifecycle des releases, fixes, cadrage, replan et abandon/supersession.
|
||||||
- [`210-WORKFLOW.md`](210-WORKFLOW.md) — contrats des artefacts workflow, ordre delta/history/commit, reprise et baselines de release.
|
- [`210-WORKFLOW.md`](210-WORKFLOW.md) — contrats des artefacts workflow, ordre delta/history/commit, prompts versionnés, reprise et baselines de release.
|
||||||
|
- [`220-SKELETONS.md`](220-SKELETONS.md) — contrat commun des skeleton specifications, sélection des profils/templates, décisions, overrides et validation.
|
||||||
|
- [`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.
|
- [`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.
|
- [`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.
|
- [`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.
|
- [`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.
|
- [`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.
|
- [`610-ANDROID.md`](610-ANDROID.md) — profil plateforme Android et règles réutilisables de compatibilité, packaging et validation.
|
||||||
|
- [`700-FRAMEWORKS.md`](700-FRAMEWORKS.md) — contrat commun des profils framework et de leur composition avec les owners déjà applicables.
|
||||||
|
- [`710-TAURI.md`](710-TAURI.md) — profil Tauri 2 et règles réutilisables d'orchestration native/frontend, sécurité et validation.
|
||||||
|
|
||||||
Le modèle transversal d'ownership, d'applicabilité et de composition est décrit dans [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
Le modèle transversal d'ownership, d'applicabilité et de composition est décrit dans [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/rules/200-GOVERNANCE.md -->
|
<!-- file: docs/rules/200-GOVERNANCE.md -->
|
||||||
<!-- version: 2 -->
|
<!-- version: 5 -->
|
||||||
|
|
||||||
# Governance rules
|
# Governance rules
|
||||||
|
|
||||||
@@ -38,9 +38,20 @@ Lorsqu'un dépôt utilise le fichier racine `VERSION`, ce fichier :
|
|||||||
|
|
||||||
Un manifeste technique MAY refléter exactement `VERSION` lorsque son propre contrat l'exige. Un autre mécanisme de versioning MAY rester indépendant lorsqu'il possède une sémantique différente, par exemple un `versionCode` Android, une révision de document ou une version de protocole.
|
Un manifeste technique MAY refléter exactement `VERSION` lorsque son propre contrat l'exige. Un autre mécanisme de versioning MAY rester indépendant lorsqu'il possède une sémantique différente, par exemple un `versionCode` Android, une révision de document ou une version de protocole.
|
||||||
|
|
||||||
PGR MUST NOT imposer une égalité globale entre tous les champs contenant un numéro de version.
|
PGR MUST NOT imposer une égalité globale entre tous les champs contenant un numéro de version. Pour éviter à la fois les divergences silencieuses et le churn mécanique, chaque valeur de version durable SHOULD être classée selon son rôle réel. Les catégories réutilisables sont notamment :
|
||||||
|
|
||||||
Un champ de version qui n'est ni requis par l'écosystème ni utile au projet SHOULD être omis plutôt que maintenu comme duplication décorative.
|
- `CANONICAL` — identité SemVer exacte de l'unité de release, normalement portée par `VERSION` ;
|
||||||
|
- `MIRROR-EXACT` — miroir technique qui suit exactement `VERSION`, prereleases et fixes compris ;
|
||||||
|
- `MIRROR-STABLE` — miroir du jalon produit `X.Y.Z` ciblé, stable pendant `X.Y.Z-alpha.*`, `beta.*`, `rc.*` et leurs fixes ;
|
||||||
|
- `INDEPENDENT-COUNTER` — compteur technique monotone possédant sa propre sémantique ;
|
||||||
|
- `INDEPENDENT-SCHEMA` — version de protocole, format ou schéma indépendante du produit ;
|
||||||
|
- `DOCUMENT-REVISION` — révision interne d'un document ou artefact documentaire.
|
||||||
|
|
||||||
|
Seul un `MIRROR-EXACT` est normalement modifié à chaque changement de `VERSION`. Un `MIRROR-STABLE` SHOULD être fixé ou vérifié lorsque la cible `X.Y.Z` est ouverte, puis ne pas être réécrit uniquement parce qu'une tranche passe de `alpha.N` à `alpha.N+1`, à un `.fix.N`, à une beta ou à une RC. La promotion stable vérifie qu'il représente toujours la release publiée.
|
||||||
|
|
||||||
|
Lorsqu'une prerelease est réellement distribuée comme artefact installable distinct et que son écosystème exige une identité de package propre, le champ concerné peut devenir `MIRROR-EXACT` ou suivre des jalons explicitement définis. Cette décision appartient au plan de versioning/packaging du projet ; elle ne doit pas résulter d'une égalité globale implicite.
|
||||||
|
|
||||||
|
Un champ de version qui n'est ni requis par l'écosystème ni utile au projet SHOULD être omis plutôt que maintenu comme duplication décorative. Réciproquement, PGR MUST NOT imposer la suppression d'un champ utile uniquement pour éviter de le modifier à chaque prerelease : il faut d'abord lui attribuer la bonne classe de synchronisation.
|
||||||
|
|
||||||
## Schéma SemVer PGR
|
## Schéma SemVer PGR
|
||||||
|
|
||||||
@@ -66,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.
|
`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 :
|
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é ;
|
- `X = 0` indique que le contrat public durable n'est pas encore stabilisé ;
|
||||||
@@ -89,7 +102,9 @@ Cette convention pré-1.0 complète SemVer sans modifier sa syntaxe.
|
|||||||
- les études ou décisions encore ouvertes ;
|
- les études ou décisions encore ouvertes ;
|
||||||
- les principaux risques et contraintes ;
|
- les principaux risques et contraintes ;
|
||||||
- la stratégie de validation et les smokes nécessaires ;
|
- la stratégie de validation et les smokes nécessaires ;
|
||||||
- le dimensionnement des tranches.
|
- le dimensionnement des tranches ;
|
||||||
|
- lorsque la release possède un plan dédié, les responsabilités de clôture et de transition vers la suite ;
|
||||||
|
- l'état de l'horizon de roadmap et, lorsqu'il devient court ou incertain, le moment prévu pour le réexaminer.
|
||||||
|
|
||||||
Une tranche cible généralement un volume de travail cohérent et vérifiable. Une durée de l'ordre de 15 à 30 minutes MAY servir d'heuristique de découpage, mais MUST NOT être traitée comme une deadline ou un quota.
|
Une tranche cible généralement un volume de travail cohérent et vérifiable. Une durée de l'ordre de 15 à 30 minutes MAY servir d'heuristique de découpage, mais MUST NOT être traitée comme une deadline ou un quota.
|
||||||
|
|
||||||
@@ -113,6 +128,16 @@ La promotion stable MUST néanmoins exécuter son propre gate proportionné pour
|
|||||||
|
|
||||||
Le tag stable canonique est `vX.Y.Z`.
|
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.
|
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
|
## Correctifs de tranche
|
||||||
@@ -145,6 +170,8 @@ ABANDON
|
|||||||
|
|
||||||
Une interruption de conversation ou de session MUST NOT créer artificiellement une nouvelle version. Le même état de version et de tranche continue tant que le scope reste valable.
|
Une interruption de conversation ou de session MUST NOT créer artificiellement une nouvelle version. Le même état de version et de tranche continue tant que le scope reste valable.
|
||||||
|
|
||||||
|
Une revue stratégique de versions futures MAY également se tenir dans une session séparée. Cette frontière de conversation n'est ni une release, ni une phase SemVer, ni une raison de modifier `VERSION`. Si la discussion produit une décision durable à matérialiser dans le dépôt, cette modification passe ensuite par une tranche gouvernée appropriée.
|
||||||
|
|
||||||
## Abandon et supersession
|
## Abandon et supersession
|
||||||
|
|
||||||
Une version ou prerelease commencée n'est pas forcée vers stable uniquement pour préserver une séquence esthétique.
|
Une version ou prerelease commencée n'est pas forcée vers stable uniquement pour préserver une séquence esthétique.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/rules/210-WORKFLOW.md -->
|
<!-- file: docs/rules/210-WORKFLOW.md -->
|
||||||
<!-- version: 3 -->
|
<!-- version: 9 -->
|
||||||
|
|
||||||
# Workflow artifact rules
|
# Workflow artifact rules
|
||||||
|
|
||||||
@@ -49,13 +49,25 @@ docs/plans/
|
|||||||
|
|
||||||
Un plan :
|
Un plan :
|
||||||
|
|
||||||
- SHOULD être créé pendant le cadrage lorsque plusieurs tranches ou décisions doivent être coordonnées ;
|
- SHOULD être créé ou consolidé pendant `alpha.1` lorsque plusieurs tranches ou décisions doivent être coordonnées ;
|
||||||
- MAY évoluer lorsque le plan change réellement ;
|
- MAY évoluer lorsque la réalité invalide le forecast ;
|
||||||
- SHOULD NOT être modifié à chaque tranche uniquement pour recopier l'avancement ;
|
- SHOULD NOT être modifié à chaque tranche uniquement pour recopier l'avancement ;
|
||||||
- MUST distinguer prévision et état réellement observé ;
|
- MUST distinguer prévision et état réellement observé ;
|
||||||
- MUST NOT remplacer ROADMAP, delta ou history.
|
- MUST NOT remplacer ROADMAP, delta ou history.
|
||||||
|
|
||||||
Un changement substantiel du plan MAY être porté par une tranche REPLAN conformément aux règles de gouvernance.
|
Lorsqu'un plan existe pour une release gouvernée par le workflow PGR, il MUST aussi rendre explicites, de manière proportionnée :
|
||||||
|
|
||||||
|
- la mission, le scope et le hors-scope actuellement applicables ;
|
||||||
|
- la stratégie de validation et les gates qui conditionnent réellement la fermeture ;
|
||||||
|
- la trajectoire prévisionnelle des responsabilités, sans transformer le forecast en promesse immuable ;
|
||||||
|
- une section ou un bloc **clôture et transition** indiquant où seront traités la réconciliation documentaire durable, le `CHANGELOG`, la mise à jour de `ROADMAP`, le prompt ou handoff de reprise, la fermeture du plan et la promotion/publication ;
|
||||||
|
- l'état de la **revue d'horizon** : soit elle n'est pas nécessaire parce que la roadmap possède déjà un horizon suffisant, soit son déclencheur et le moment où elle sera instruite sont identifiés.
|
||||||
|
|
||||||
|
Le plan MUST NOT inventer une version future uniquement pour remplir la rubrique de transition. Lorsque la cible suivante n'est pas suffisamment décidée, il l'indique explicitement et planifie une revue d'horizon ou un handoff approprié plutôt que de fabriquer un numéro, une mission ou un prompt.
|
||||||
|
|
||||||
|
Un changement substantiel du plan MAY être porté par une tranche REPLAN conformément aux règles de gouvernance. Le corps du plan reste l'état de pilotage actuellement applicable ; les deltas et histories conservent le détail historique des changements. PGR n'impose pas un journal `Revisions` alimenté à chaque tranche.
|
||||||
|
|
||||||
|
À la clôture `completed`, `abandoned` ou `superseded`, le plan devient principalement historique. Il ne doit plus être réécrit pour refléter silencieusement la connaissance acquise dans des releases ultérieures.
|
||||||
|
|
||||||
## Delta
|
## Delta
|
||||||
|
|
||||||
@@ -74,6 +86,8 @@ alpha.3.md
|
|||||||
alpha.3.fix.1.md
|
alpha.3.fix.1.md
|
||||||
beta.1.md
|
beta.1.md
|
||||||
rc.1.md
|
rc.1.md
|
||||||
|
rel.1.md
|
||||||
|
rel.1.fix.1.md
|
||||||
```
|
```
|
||||||
|
|
||||||
Un delta MUST :
|
Un delta MUST :
|
||||||
@@ -135,8 +149,32 @@ 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é.
|
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.
|
Delta et history MUST rester des livraisons séparées afin que la preuve observée ne soit pas confondue avec l'intention prospective.
|
||||||
|
|
||||||
|
Lorsque la gate courante est `PASS` et que la tranche suivante est déjà déterminée par le plan sans décision ouverte, le générateur SHOULD préparer et remettre dans la même réponse :
|
||||||
|
|
||||||
|
```text
|
||||||
|
archive history de la tranche courante
|
||||||
|
+
|
||||||
|
archive delta de la tranche suivante
|
||||||
|
```
|
||||||
|
|
||||||
|
Les deux archives restent séparées. Cette optimisation de flux n'autorise jamais l'application du delta suivant avant l'application du history courant et le commit complet de la tranche.
|
||||||
|
|
||||||
|
Le delta suivant SHOULD NOT être anticipé lorsqu'une décision opérateur, un REPLAN non résolu, un abandon/supersession, une preuve externe post-tag ou toute autre dépendance peut encore modifier sa baseline ou son scope.
|
||||||
|
|
||||||
|
## 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
|
## Commit de tranche
|
||||||
|
|
||||||
Le commit d'une tranche doit représenter l'état complet de cette tranche, y compris son history.
|
Le commit d'une tranche doit représenter l'état complet de cette tranche, y compris son history.
|
||||||
@@ -150,9 +188,63 @@ current delta changes
|
|||||||
|
|
||||||
doivent être présents, alors que le delta suivant MUST rester absent.
|
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
|
## Manifest de suppression
|
||||||
|
|
||||||
@@ -173,9 +265,9 @@ S'il existe :
|
|||||||
|
|
||||||
Un manifest ne doit pas exister vide uniquement pour satisfaire une structure théorique.
|
Un manifest ne doit pas exister vide uniquement pour satisfaire une structure théorique.
|
||||||
|
|
||||||
## Prompt de démarrage
|
## Prompt de démarrage versionné
|
||||||
|
|
||||||
Un prompt de démarrage transmet la mission et le contexte nécessaires à une nouvelle version ou à une reprise explicitement prévue.
|
Un prompt de démarrage versionné transmet le contrat de reprise nécessaire pour ouvrir une nouvelle version depuis une baseline autoritaire sans reconstruire implicitement l'état du projet depuis une conversation antérieure, un workspace non fourni ou une mémoire informelle.
|
||||||
|
|
||||||
Le chemin canonique est :
|
Le chemin canonique est :
|
||||||
|
|
||||||
@@ -185,19 +277,55 @@ prompts/NNN-VX_Y_Z_START_PROMPT.md
|
|||||||
|
|
||||||
`NNN` est monotone à l'échelle du dépôt.
|
`NNN` est monotone à l'échelle du dépôt.
|
||||||
|
|
||||||
Le prompt :
|
Le prompt MUST rester un artefact de reprise et de cadrage. Il référence les règles, plans, histories, handoffs ou documents techniques qui possèdent déjà le détail ; il MUST NOT les recopier exhaustivement ni devenir une seconde source normative concurrente.
|
||||||
|
|
||||||
- doit transmettre la mission, la baseline et les règles de reprise utiles ;
|
### Contrat minimal
|
||||||
- MUST NOT devenir une copie exhaustive du plan ou de l'historique ;
|
|
||||||
- SHOULD être finalisé à la clôture stable de la version précédente lorsqu'il prépare la version suivante.
|
|
||||||
|
|
||||||
Une interruption au milieu d'une version MUST NOT produire artificiellement le prompt de la version suivante.
|
Le prompt MUST couvrir, sous des titres adaptés au projet plutôt que selon une forme imposée, les éléments suivants lorsqu'ils sont applicables :
|
||||||
|
|
||||||
Lors d'une nouvelle session ouverte depuis une stable publiée, une courte consigne manuelle MAY identifier l'archive du tag, le rapport post-tag lorsqu'il existe réellement, le prompt versionné à lire et la première gate. [`../templates/003-NEW_SESSION_PROMPT.md`](../templates/003-NEW_SESSION_PROMPT.md) décrit une forme réutilisable ; elle ne remplace ni le prompt versionné ni la preuve de publication.
|
1. **baseline autoritaire et cible** — identifier la source exacte depuis laquelle la version doit être ouverte, la version cible et la première tranche attendue ; préciser les limites matérielles de cette source, par exemple l'absence normale de `.git` dans une archive de tag ;
|
||||||
|
2. **ordre de lecture** — nommer les points d'entrée normatifs, plans, histories, handoffs ou documents de subsystem qui doivent être lus avant de modifier le projet lorsqu'un ordre est nécessaire pour reconstruire correctement le contexte ;
|
||||||
|
3. **état déjà acquis** — résumer uniquement les résultats stables nécessaires à la reprise et les décisions qui ne doivent pas être redébattues sans preuve nouvelle ; cet état MUST rester traçable à la baseline ou aux artefacts cités ;
|
||||||
|
4. **mission et résultat attendu** — décrire ce que la version doit rendre vrai ou livrer, sans substituer un catalogue de tâches à l'objectif ;
|
||||||
|
5. **scope et hors-scope** — borner les changements autorisés et les sujets explicitement différés afin d'éviter qu'une reprise étende silencieusement la release ;
|
||||||
|
6. **décisions gelées et questions ouvertes** — distinguer les choix déjà établis des décisions que la première tranche doit encore instruire ; une valeur non prouvée MUST rester ouverte plutôt qu'être figée arbitrairement ;
|
||||||
|
7. **première gate** — définir l'objectif de la première tranche, les lectures/audits ou preuves préalables attendus et, lorsque nécessaire, les travaux interdits avant fermeture de ce gate ;
|
||||||
|
8. **trajectoire prévisionnelle** — fournir uniquement le forecast nécessaire pour dimensionner la release et ordonner les responsabilités ; il reste non contraignant et peut être scindé, fusionné ou replanifié selon les preuves ;
|
||||||
|
9. **validation et responsabilité** — rappeler les familles de gates pertinentes, les validations déjà imposées par les règles applicables et toute séparation importante entre préparation, exécution opérateur et preuve observée, sans déclarer réussie une commande qui n'a pas été exécutée.
|
||||||
|
|
||||||
|
Un projet MAY regrouper plusieurs de ces éléments dans une même section lorsque le résultat reste explicite et non ambigu. Le prompt n'a pas à reproduire littéralement cette numérotation.
|
||||||
|
|
||||||
|
### Sources externes et données manquantes
|
||||||
|
|
||||||
|
Lorsqu'une release dépend de snapshots, corpus, rapports ou autres sources externes, le prompt MUST identifier celles qui sont réellement autoritaires pour la reprise et définir le comportement lorsque l'une d'elles manque.
|
||||||
|
|
||||||
|
L'absence d'une source attendue MUST être signalée. Le travail doit alors être borné à ce que les preuves disponibles permettent réellement de conclure ; le prompt MUST NOT autoriser à reconstituer silencieusement une version, un commit, un contenu ou un résultat depuis une conversation antérieure ou un workspace non fourni.
|
||||||
|
|
||||||
|
Une preuve externe complète la baseline seulement pour les propriétés qu'elle établit. Elle ne remplace pas l'audit de la source effectivement fournie à la nouvelle session.
|
||||||
|
|
||||||
|
### Décisions acquises et détails locaux
|
||||||
|
|
||||||
|
Le prompt SHOULD citer les décisions acquises qui empêchent une régression ou une réouverture inutile, mais il SHOULD pointer vers leur owner documentaire lorsque leur explication détaillée existe déjà.
|
||||||
|
|
||||||
|
Les contraintes locales de langage, plateforme, framework, architecture ou métier restent chez leurs owners respectifs. Leur présence dans un prompt de projet ne les élève pas au rang de règle générale PGR.
|
||||||
|
|
||||||
|
Le prompt MAY imposer un ordre de lecture détaillé ou une matrice de questions lorsque la taille du projet le justifie. Un petit projet SHOULD conserver une forme plus courte si elle couvre le même contrat de reprise.
|
||||||
|
|
||||||
|
### Création et clôture
|
||||||
|
|
||||||
|
Lorsque la version suivante est suffisamment connue, son prompt SHOULD être amorcé pendant la consolidation finale, vérifié pendant la RC et finalisé pendant la promotion stable. Il MUST être présent dans la stable taggée qui prépare cette reprise.
|
||||||
|
|
||||||
|
Lorsque la cible suivante n'est pas suffisamment connue, PGR MUST NOT fabriquer un prompt de version, un numéro ou une mission pour respecter une cérémonie. Le plan et la roadmap indiquent alors que l'horizon reste ouvert et un handoff `NEXT` ou une revue d'horizon porte la continuité nécessaire.
|
||||||
|
|
||||||
|
Une interruption au milieu d'une version MUST NOT produire artificiellement le prompt de la version suivante. La reprise de la tranche courante utilise son état committé et, si nécessaire, un handoff conforme au présent document.
|
||||||
|
|
||||||
|
Lorsqu'une stable publiée possède une cible suivante connue, le générateur MUST remettre spontanément à l'opérateur, après la vérification post-tag applicable, une courte consigne manuelle identifiant l'archive du tag, le rapport post-tag lorsqu'il existe réellement, le prompt versionné à lire et la première gate. [`../templates/003-NEW_SESSION_PROMPT.md`](../templates/003-NEW_SESSION_PROMPT.md) décrit cette forme courte ; elle reste distincte du prompt versionné et ne remplace ni son contrat détaillé ni la preuve de publication.
|
||||||
|
|
||||||
|
Si une preuve post-tag externe est requise pour la prochaine reprise, le prompt versionné MAY annoncer à l'avance son nom attendu mais MUST la décrire comme une preuve future extérieure au tag. La consigne manuelle finale ne la présente comme `PASS` qu'après sa production et sa vérification réelles.
|
||||||
|
|
||||||
## Handoff
|
## Handoff
|
||||||
|
|
||||||
Un handoff est un snapshot de continuité utilisé lorsqu'un travail doit être repris sans changer artificiellement de version ou de tranche.
|
Un handoff est un snapshot de continuité utilisé lorsqu'un travail doit être repris à une frontière de session ou de responsabilité sans changer artificiellement de version ou de tranche. Un REPLAN traité entièrement dans la même session n'a pas besoin d'un handoff uniquement pour laisser une trace : delta, history et plan possèdent déjà cette trace.
|
||||||
|
|
||||||
Le chemin canonique est :
|
Le chemin canonique est :
|
||||||
|
|
||||||
@@ -217,9 +345,21 @@ SUPERSEDE
|
|||||||
NEXT
|
NEXT
|
||||||
```
|
```
|
||||||
|
|
||||||
Le handoff SHOULD enregistrer uniquement les informations nécessaires à une reprise fiable : état de version/tranche, résultat déjà acquis, travail restant, risques ou décisions ouvertes et commandes pertinentes.
|
Selon le besoin réel, un handoff SHOULD permettre de retrouver sans mémoire conversationnelle :
|
||||||
|
|
||||||
Une fois livré comme snapshot de reprise, il SHOULD être traité comme historique plutôt que réécrit continuellement.
|
- son type, la version source et une cible éventuelle ;
|
||||||
|
- la baseline autoritaire et le dernier état opérateur validé ;
|
||||||
|
- le dernier delta validé et tout delta livré mais encore en attente ;
|
||||||
|
- l'état du plan, le travail terminé et le travail restant ;
|
||||||
|
- les décisions acquises, les questions ouvertes et les validations restantes ;
|
||||||
|
- le prompt applicable lorsqu'il existe ;
|
||||||
|
- l'instruction exacte de reprise et, lorsque cela aide l'opérateur, un court texte copiable vers la nouvelle session.
|
||||||
|
|
||||||
|
Un petit handoff n'a pas à répéter les champs sans valeur pour son cas. Il référence les owners existants plutôt que recopier leurs règles.
|
||||||
|
|
||||||
|
Un `NEXT` après stable peut transmettre une version suivante connue. Si l'horizon est volontairement ouvert, il peut au contraire transmettre explicitement le besoin de revue d'horizon sans inventer une release.
|
||||||
|
|
||||||
|
Une fois livré comme snapshot de reprise, un handoff SHOULD être traité comme historique plutôt que réécrit continuellement.
|
||||||
|
|
||||||
Un changement de conversation ou de session n'est jamais, à lui seul, une raison de changer `VERSION`.
|
Un changement de conversation ou de session n'est jamais, à lui seul, une raison de changer `VERSION`.
|
||||||
|
|
||||||
@@ -255,7 +395,13 @@ published source archive
|
|||||||
post-tag verification
|
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.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.
|
||||||
|
|
||||||
## Conservation et immutabilité
|
## Conservation et immutabilité
|
||||||
|
|
||||||
|
|||||||
125
docs/rules/220-SKELETONS.md
Normal file
125
docs/rules/220-SKELETONS.md
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<!-- file: docs/rules/220-SKELETONS.md -->
|
||||||
|
<!-- version: 2 -->
|
||||||
|
|
||||||
|
# Skeleton specification rules
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
Ce document définit le contrat transversal des skeleton specifications PGR : applicabilité, sélection des règles et profils, composition de skeletons, usage des templates, décisions propres au projet, overrides, instanciation et validation initiale.
|
||||||
|
|
||||||
|
Il ne définit pas les règles propres à une technologie. Les profils restent possédés par leurs documents normatifs, notamment le modèle de composition de [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md). Les règles de validation restent possédées par [`400-VALIDATION.md`](400-VALIDATION.md) et le workflow delta/history par [`210-WORKFLOW.md`](210-WORKFLOW.md).
|
||||||
|
|
||||||
|
Les skeleton specifications concrètes vivent sous [`../skeletons/`](../skeletons/000-README.md).
|
||||||
|
|
||||||
|
## Nature d'un skeleton
|
||||||
|
|
||||||
|
Un skeleton PGR est une spécification Markdown procédurale permettant de construire une baseline locale cohérente à partir de règles, profils, templates et décisions explicites.
|
||||||
|
|
||||||
|
Un skeleton MUST NOT devenir :
|
||||||
|
|
||||||
|
- un générateur obligatoire de projet ;
|
||||||
|
- une dépendance runtime ou build vers PGR ;
|
||||||
|
- un nouveau propriétaire implicite de règles déjà possédées ailleurs ;
|
||||||
|
- un moyen de figer une architecture au-delà du scope qu'il déclare ;
|
||||||
|
- un catalogue de technologies ou de fichiers créés par anticipation.
|
||||||
|
|
||||||
|
Après instanciation, le projet destinataire possède ses fichiers, ses décisions et ses règles locales. Cette baseline locale devient l'autorité de ses sessions et releases suivantes. Une évolution ultérieure de PGR ne modifie pas automatiquement ce projet et le projet MUST NOT rechercher automatiquement une version PGR plus récente.
|
||||||
|
|
||||||
|
Un réalignement futur MAY être décidé explicitement. Il doit alors partir d'un snapshot PGR précis choisi par le projet, comparer ce snapshot à la baseline locale et appliquer uniquement les écarts explicitement retenus. Ce réalignement est une nouvelle opération bornée ; il ne transforme pas PGR en upstream documentaire permanent.
|
||||||
|
|
||||||
|
## Applicabilité
|
||||||
|
|
||||||
|
Chaque skeleton MUST rendre explicites son objectif et les faits qui déterminent son applicabilité.
|
||||||
|
|
||||||
|
L'applicabilité MUST reposer sur le besoin réel du projet : type de baseline recherchée, langage ou écosystème utilisé, plateforme ciblée, framework réellement présent ou autre propriété concrète du scope.
|
||||||
|
|
||||||
|
Un skeleton MUST NOT être appliqué uniquement parce qu'il est fréquent, recommandé dans un autre projet ou disponible dans PGR.
|
||||||
|
|
||||||
|
Un skeleton spécialisé MAY déclarer un autre skeleton comme fondation. Cette relation doit être explicite et ne rend pas les spécialisations sœurs applicables entre elles.
|
||||||
|
|
||||||
|
## Contenu minimal d'une specification
|
||||||
|
|
||||||
|
Une skeleton specification MUST permettre d'identifier sans ambiguïté :
|
||||||
|
|
||||||
|
- son objectif et son applicabilité ;
|
||||||
|
- les règles et profils sélectionnés ou requis ;
|
||||||
|
- les autres skeletons dont elle dépend éventuellement pour sa composition ;
|
||||||
|
- les fichiers à créer, copier, adapter ou omettre ;
|
||||||
|
- les templates techniques utilisés et les décisions d'adaptation associées ;
|
||||||
|
- les décisions obligatoires qui appartiennent au projet destinataire ;
|
||||||
|
- les options, exceptions et overrides explicitement permis ;
|
||||||
|
- l'ordre d'instanciation lorsque cet ordre est significatif ;
|
||||||
|
- la validation initiale proportionnée ;
|
||||||
|
- les éléments volontairement hors scope.
|
||||||
|
|
||||||
|
La structure Markdown exacte MAY varier si ces responsabilités restent clairement séparées. PGR MUST NOT imposer des sections vides uniquement pour respecter un format cérémoniel.
|
||||||
|
|
||||||
|
## Sélection des règles et profils
|
||||||
|
|
||||||
|
Un skeleton sélectionne les owners normatifs applicables ; il ne redéfinit pas leur contenu.
|
||||||
|
|
||||||
|
La sélection des profils MUST respecter l'applicabilité, la hiérarchie et la résolution définies dans [`../architecture/003-RULE_PROFILE_MODEL.md`](../architecture/003-RULE_PROFILE_MODEL.md).
|
||||||
|
|
||||||
|
Lorsqu'une règle générale est déjà applicable sans spécialisation, le skeleton SHOULD la référencer plutôt que la recopier comme si elle lui appartenait. Lors de l'instanciation, le projet destinataire doit néanmoins disposer localement des règles nécessaires à son fonctionnement autonome, sous la forme documentaire réellement adaptée à son propre référentiel.
|
||||||
|
|
||||||
|
Un skeleton MUST NOT sélectionner toute la bibliothèque PGR par défaut. Les profils ou familles sans rapport avec le projet restent absents.
|
||||||
|
|
||||||
|
## Templates et artefacts techniques
|
||||||
|
|
||||||
|
Un template reste un artefact technique copiable distinct du skeleton et de la règle qui justifie son usage.
|
||||||
|
|
||||||
|
Lorsqu'un skeleton utilise un template, il MUST identifier le template source et les valeurs qui doivent être revues ou adaptées avant adoption. Une valeur d'exemple, un placeholder, une version de toolchain, un nom de crate, un chemin de build ou un seuil de lint présent dans un template MUST NOT devenir une valeur universelle par simple copie.
|
||||||
|
|
||||||
|
Un skeleton MAY demander de copier un template tel quel seulement lorsque le contrat du template indique qu'aucune décision locale n'est requise pour le scope visé.
|
||||||
|
|
||||||
|
Un skeleton MUST NOT télécharger des dépendances, installer des toolchains ou exécuter implicitement des commandes externes à la place du projet destinataire. Ces opérations peuvent faire partie d'une validation explicitement demandée lorsque l'environnement et le scope les justifient.
|
||||||
|
|
||||||
|
## Décisions propres au projet
|
||||||
|
|
||||||
|
Toute décision qui ne découle pas d'une règle applicable ou d'une contrainte technique établie reste une décision du projet destinataire.
|
||||||
|
|
||||||
|
Le skeleton MUST distinguer une obligation normative d'une valeur d'exemple, d'un choix recommandé et d'une option libre lorsque cette distinction est nécessaire pour éviter une adoption accidentelle.
|
||||||
|
|
||||||
|
Les décisions nécessaires à une baseline fonctionnelle MUST être résolues ou laissées comme entrées explicites avant que l'instanciation soit présentée comme terminée. Un choix encore ouvert MUST NOT être converti silencieusement en règle ou valeur par défaut arbitraire.
|
||||||
|
|
||||||
|
Les décisions locales SHOULD être consignées dans les documents ou configurations qui les possèdent durablement dans le projet créé, et non uniquement dans une trace temporaire d'instanciation.
|
||||||
|
|
||||||
|
## Composition de plusieurs skeletons
|
||||||
|
|
||||||
|
La composition SHOULD partir de la fondation la plus générale explicitement requise, puis ajouter les spécialisations réellement applicables.
|
||||||
|
|
||||||
|
Un skeleton spécialisé SHOULD référencer les responsabilités déjà couvertes par sa fondation plutôt que les recopier. Il MAY ajouter des fichiers, décisions, templates ou validations propres à son scope.
|
||||||
|
|
||||||
|
L'ordre de composition ne crée aucune priorité normative implicite. Une règle plus spécifique ne remplace une règle plus générale que selon la hiérarchie normative, un profil applicable ou une exception explicitement documentée.
|
||||||
|
|
||||||
|
Si deux skeletons applicables exigent des choix incompatibles sans relation de spécialisation ou override défini, l'instanciation MUST s'arrêter sur cette décision au lieu de choisir arbitrairement le dernier appliqué.
|
||||||
|
|
||||||
|
PGR SHOULD NOT créer un skeleton composite pour chaque combinaison de technologies. Un skeleton composite n'est justifié que lorsqu'une interaction réelle possède des étapes, artefacts ou décisions qui ne peuvent pas être correctement possédés par les skeletons composants.
|
||||||
|
|
||||||
|
## Overrides et exceptions
|
||||||
|
|
||||||
|
Un override ou une exception MUST identifier la règle, le template, le choix ou l'étape concerné, son scope et sa raison.
|
||||||
|
|
||||||
|
Un skeleton MAY prévoir des points d'override lorsqu'ils correspondent à une variabilité légitime du projet. Il MUST NOT utiliser cette possibilité pour affaiblir silencieusement une règle applicable ou masquer une incompatibilité entre profils.
|
||||||
|
|
||||||
|
Une exception propre au projet est possédée par le projet destinataire après instanciation. Elle ne devient pas automatiquement une règle générale PGR.
|
||||||
|
|
||||||
|
## Validation de l'instanciation
|
||||||
|
|
||||||
|
Chaque skeleton MUST définir une validation initiale proportionnée à ce qu'il matérialise réellement.
|
||||||
|
|
||||||
|
La validation SHOULD utiliser le mécanisme le plus fiable disponible : parseur ou build tool officiel, linter, audit structurel read-only, test ciblé ou revue humaine selon la propriété à prouver.
|
||||||
|
|
||||||
|
Lorsqu'un skeleton prétend produire une baseline directement utilisable par une toolchain, une instanciation temporaire MAY être utilisée pour vérifier les fichiers copiés ou adaptés. Les ressources temporaires SHOULD être isolées et nettoyées après la gate.
|
||||||
|
|
||||||
|
La réussite d'un audit structurel ne remplace pas une validation de toolchain lorsque le contrat à prouver appartient à cette toolchain. Inversement, PGR SHOULD NOT imposer un build coûteux lorsqu'une propriété purement documentaire ou structurelle suffit à la tranche.
|
||||||
|
|
||||||
|
Une prévalidation réalisée lors de la préparation d'un delta ne remplace jamais la gate opérateur autoritaire définie par les règles de validation.
|
||||||
|
|
||||||
|
## Évolution
|
||||||
|
|
||||||
|
Une skeleton specification est un document vivant tant qu'elle reste la specification courante de son type de projet. Sa révision interne suit les règles documentaires PGR.
|
||||||
|
|
||||||
|
Modifier un skeleton PGR n'altère pas rétroactivement les projets déjà instanciés. Une migration depuis une ancienne baseline est une décision explicite du projet concerné.
|
||||||
|
|
||||||
|
PGR matérialise un nouveau skeleton uniquement lorsqu'un besoin réel, des owners normatifs suffisants et les artefacts nécessaires existent. Une technologie encore insuffisamment cadrée reste différée plutôt que représentée par un skeleton placeholder.
|
||||||
145
docs/rules/230-ADOPTION.md
Normal file
145
docs/rules/230-ADOPTION.md
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<!-- file: docs/rules/230-ADOPTION.md -->
|
||||||
|
<!-- version: 3 -->
|
||||||
|
|
||||||
|
# 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. Une fois la baseline locale établie, elle devient l'autorité des sessions et releases suivantes du projet. Le projet destinataire ne devient pas dépendant runtime, build ou documentaire implicite du dépôt PGR et MUST NOT rechercher automatiquement « la dernière version de 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
|
||||||
|
```
|
||||||
|
|
||||||
|
Ces classifications n'augmentent pas la force normative d'une règle. En particulier, choisir une solution différente d'un `SHOULD` / `SHOULD NOT` ne crée pas à lui seul un `OVERRIDE` obligatoire ; le projet MAY conserver ce choix comme décision locale et documenter sa raison lorsque cette trace apporte une valeur durable.
|
||||||
|
|
||||||
|
### 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 obligation PGR réellement applicable, ou un contrat localement rendu obligatoire, est volontairement remplacé ou raffiné 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. Un simple écart à une recommandation `SHOULD` / `SHOULD NOT` MUST NOT exiger un override uniquement parce que la recommandation n'est pas suivie.
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
## Autorité locale et réalignement futur
|
||||||
|
|
||||||
|
Après clôture du scope d'adoption, les règles, plans, décisions, validations et historiques locaux gouvernent les travaux suivants. Les sessions et releases ultérieures MUST partir de cette baseline locale et non d'une recherche automatique d'une version PGR plus récente.
|
||||||
|
|
||||||
|
PGR n'est pas un upstream documentaire implicite. Une référence, URL ou archive PGR utilisée pendant l'adoption reste une source de comparaison de cette opération ; elle ne crée pas un abonnement aux évolutions futures du référentiel. Une dépendance documentaire externe MAY exister uniquement si le projet la choisit et la possède explicitement comme contrat local.
|
||||||
|
|
||||||
|
Un réalignement futur avec PGR MAY être engagé lorsqu'il apporte une valeur réelle. Cette opération MUST être explicite et bornée. Elle doit au minimum :
|
||||||
|
|
||||||
|
1. identifier le snapshot PGR choisi, par exemple version, tag, commit ou archive ;
|
||||||
|
2. repartir de la baseline locale autoritaire du projet ;
|
||||||
|
3. comparer les owners applicables et classifier les écarts utiles selon `ADOPT / KEEP-LOCAL / OVERRIDE / DEFER` ;
|
||||||
|
4. définir le scope et les validations de la migration ;
|
||||||
|
5. préserver les histories, tags et décisions historiques au lieu de les réécrire pour simuler une conformité continue.
|
||||||
|
|
||||||
|
Le réalignement ne doit pas être présenté comme une mise à jour automatique. Entre deux opérations explicitement décidées, la gouvernance locale reste autonome et suffisante pour reprendre le projet.
|
||||||
|
|
||||||
|
## 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 dont la baseline locale gouverne les sessions et releases suivantes ;
|
||||||
|
- uniquement les owners PGR réellement applicables ;
|
||||||
|
- les choix locaux légitimes préservés ;
|
||||||
|
- les overrides explicites lorsqu'une obligation applicable est volontairement remplacée ;
|
||||||
|
- 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.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user