From 27978c37826a9707a0d18ece34e1392c96c0d1ee Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Mon, 21 Sep 2026 17:14:34 +0200 Subject: [PATCH] 0.3.4-alpha.1 --- Cargo.toml | 4 +- README.md | 6 +- RULES.md | 4 +- deltas/0.3.4/alpha.1.md | 246 +++++++++ docs/000-README.md | 5 +- docs/plans/000-README.md | 5 +- ...0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md | 481 ++++++++++++++++++ docs/rules/PROMPT_STRUCTURE.md | 6 +- docs/rules/RULES_DOCUMENTATION.md | 6 +- docs/rules/RULES_SESSION_PLANNING.md | 18 +- docs/rules/RULES_VALIDATION_MATRIX.md | 38 +- docs/rules/VERSION_WORKFLOW.md | 67 +-- history/000-README.md | 15 +- scripts/audit_project_workspace_rules.py | 20 +- 14 files changed, 831 insertions(+), 90 deletions(-) create mode 100644 deltas/0.3.4/alpha.1.md create mode 100644 docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md diff --git a/Cargo.toml b/Cargo.toml index 9aa91e0..73cbc53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ # file: Cargo.toml -# version: 85 +# version: 86 [workspace] resolver = "3" @@ -21,7 +21,7 @@ members = [ ] [workspace.package] -version = "0.3.3" +version = "0.3.4-alpha.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/games" diff --git a/README.md b/README.md index e4e7539..c1442fe 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ - + # games.sasedev @@ -27,9 +27,9 @@ Workspace expérimental puis productif pour des jeux multiplateformes principale Version stable de référence : `0.3.3`. -Prochaine version planifiée : `0.3.4-alpha.1`. `0.3.2` reste différée. +Version candidate active : `0.3.4-alpha.1`. `0.3.2` reste différée. -La stable `0.3.3` livre la voie Android SDL3 native multi-ABI : build Gradle/Cargo sans orchestrateur Python, APK Debug universal et AAB Release pour `arm64-v8a`, `armeabi-v7a`, `x86_64` et `x86`, `minSdk 21` réellement fumé et compatibilité pages mémoire 16 KB validée sur les ABI 64 bits. `0.3.4-alpha.1` ouvrira la prochaine session avec la migration de nomenclature puis le cadrage de l'API de transport realtime/WebSocket. +La stable `0.3.3` livre la voie Android SDL3 native multi-ABI : build Gradle/Cargo sans orchestrateur Python, APK Debug universal et AAB Release pour `arm64-v8a`, `armeabi-v7a`, `x86_64` et `x86`, `minSdk 21` réellement fumé et compatibilité pages mémoire 16 KB validée sur les ABI 64 bits. `0.3.4-alpha.1` migre la nomenclature de prerelease et cadre l'API de transport realtime/WebSocket avant toute implémentation réseau lourde. Les deux premiers jeux sont des POC structurels : `game-reflex-poc` et `game-snake-poc`. Ils existent d'abord pour valider les frontières du workspace, le moteur, les assets et le packaging multiplateforme. diff --git a/RULES.md b/RULES.md index 67b10ab..83e6f89 100644 --- a/RULES.md +++ b/RULES.md @@ -1,5 +1,5 @@ - + # Index normatif games.sasedev @@ -17,7 +17,7 @@ Les règles détaillées sont maintenues sous `docs/rules/` et sont cumulatives 6. [`docs/rules/VERSION_WORKFLOW.md`](docs/rules/VERSION_WORKFLOW.md) — SemVer, niveaux de maturité, fixes, deltas et livraisons ; 7. [`docs/rules/RULES_COMMANDS.md`](docs/rules/RULES_COMMANDS.md) — politique d’exécution des commandes Cargo, audits, runners, Android, Web et Git ; 8. [`docs/rules/RULES_VALIDATION_MATRIX.md`](docs/rules/RULES_VALIDATION_MATRIX.md) — matrice évolutive des commandes, dépendances de validation et politiques de nettoyage ; -9. [`docs/rules/RULES_SESSION_PLANNING.md`](docs/rules/RULES_SESSION_PLANNING.md) — cadrage `pre.1`, dimensionnement des sessions et cycle de transmission ; +9. [`docs/rules/RULES_SESSION_PLANNING.md`](docs/rules/RULES_SESSION_PLANNING.md) — cadrage `alpha.1`, dimensionnement des sessions et cycle de transmission ; 10. [`docs/rules/PROMPT_STRUCTURE.md`](docs/rules/PROMPT_STRUCTURE.md) — structure minimale des prompts de reprise et rappels de workflow obligatoires ; 11. [`docs/rules/RULES_SERVER_HOSTING.md`](docs/rules/RULES_SERVER_HOSTING.md) — contraintes durables de portabilité et préférence d'auto-hébergement. diff --git a/deltas/0.3.4/alpha.1.md b/deltas/0.3.4/alpha.1.md new file mode 100644 index 0000000..38469a4 --- /dev/null +++ b/deltas/0.3.4/alpha.1.md @@ -0,0 +1,246 @@ + + + +# Delta 0.3.4-alpha.1 + +## Base + +Base autoritaire : archive fournie `games-v0.3.3.zip`, téléchargée depuis le lien ZIP du tag Gitea `v0.3.3`. + +La version workspace de la base est `0.3.3`. L'archive taggée est utilisée telle quelle conformément à `CMD-GIT-003` et `CMD-GIT-004`; aucun fichier local absent du ZIP n'est inventé ou réinjecté. + +`0.3.2` reste différée conformément à la roadmap. + +## Objet + +Ouvrir `0.3.4` par le nouveau gate obligatoire `alpha.1` : migrer la nomenclature prospective de version, auditer complètement la stable et les règles, réévaluer les études réseau, vérifier les dépendances amont envisagées, décider l'ownership physique du transport realtime, fermer le contrat minimal WebSocket et créer le plan vivant jusqu'à stable. + +Cette tranche n'ajoute volontairement aucune crate réseau, aucune dépendance Tokio/WebSocket et aucun comportement runtime. L'implémentation commence seulement après validation de ce cadrage. + +## Migration de nomenclature + +À partir de `0.3.4`, les nouvelles prereleases suivent exclusivement : + +```text +X.Y.Z-alpha.N +X.Y.Z-alpha.N.fix.M +X.Y.Z-beta.N +X.Y.Z-beta.N.fix.M +X.Y.Z-rc.N +X.Y.Z-rc.N.fix.M +X.Y.Z +``` + +`alpha.1` remplace le rôle historique de `0-pre.1`. + +La migration réconcilie les règles prospectives et les README/index actifs concernés. Les anciens deltas, historiques, prompts et entrées de changelog restent inchangés avec leurs identifiants `0-pre`, `1-alpha`, `2-beta` et `3-rc`. + +L'audit workspace sépare désormais explicitement : + +- la convention courante, exigée pour le workspace et les versions explicites des crates ; +- la convention historique, acceptée uniquement pour les répertoires de versions déjà livrés avant `0.3.4`. + +Ainsi un nouveau jalon `0.3.4-0-pre.*` est refusé sans casser la lecture de l'historique existant. + +## Version + +La version workspace passe de : + +```text +0.3.3 +``` + +à : + +```text +0.3.4-alpha.1 +``` + +Aucune version npm/Tauri/Android n'est synchronisée : cette tranche ne change aucun produit packagé. + +## Audit de l'archive + +Avant modification, l'environnement de génération a obtenu : + +```text +unzip -t : no errors +General Rust rule audit: clean +Rust export completeness audit: 0 candidate(s) +games.sasedev workspace audit: clean +Markdown table audit: clean (5 table(s), 242 file(s)) +Distribution layout audit: clean (49 required path(s), 8 forbidden path(s) absent) +``` + +L'inventaire indépendant du ZIP confirme : + +```text +400 fichiers +246 fichiers Markdown +55 fichiers Rust +15 Cargo.toml, dont le manifest racine +14 membres workspace +workspace.package.version = 0.3.3 +0 symlink +0 erreur de chemin/archive détectée +``` + +Aucune arborescence générée `target/`, `node_modules/`, `gen/android/` ou `build/` n'est livrée dans l'archive. + +Le log utilisateur fourni à l'ouverture de session confirme également sur son checkout `0.3.3` : format Cargo propre, audits propres, `cargo check --workspace` et Clippy workspace strict réussis. Son audit Markdown annonce `258` fichiers, soit davantage que le ZIP taggé fourni. Cette différence n'est pas masquée : le delta est construit exclusivement depuis l'archive autoritaire reçue. + +## Audit des règles + +La lecture intégrale demandée par `prompts/005-V0_3_4_START_PROMPT.md` confirme notamment : + +- `alpha.1` porte le cadrage, le sizing, les risques, les validations et le plan avant développement lourd ; +- les archives taggées peuvent être utilisées sans `.git` et constituent la baseline de travail déclarée ; +- les historiques validés sont immuables ; +- le transport doit rester séparé du wire codec, de la session, de la synchronisation et de la simulation authoritative ; +- aucune dépendance réseau concrète ne doit remonter dans le gameplay ; +- les builds, tests et smokes finaux sont attestés côté utilisateur ; +- une modification Cargo impose format/check/Clippy workspace côté utilisateur ; +- `CHANGELOG.md` reste silencieux avant RC et `ROADMAP.md` reste macroscopique. + +La recherche prospective a trouvé des références à l'ancienne nomenclature au-delà des six fichiers minimum du prompt. `RULES_VALIDATION_MATRIX.md`, `docs/plans/000-README.md`, `history/000-README.md` et le `README.md` racine sont donc également réconciliés lorsqu'ils décrivent le workflow courant. Les références historiques restent intactes. + +Aucune contradiction bloquante n'est trouvée entre le prompt, les règles, la roadmap, les études réseau et la baseline `v0.3.3`. + +## Vérification des dépendances envisagées + +État amont vérifié le 2026-09-21 pour préparer les tranches d'implémentation : + +```text +Tokio 1.53.1 +futures-util 0.3.34 +tokio-tungstenite 0.30.0 +tungstenite 0.30.0 +``` + +Constats retenus : + +- Tokio `1.53.1` annonce un MSRV `1.71` ; +- `tokio-tungstenite 0.30.0` et `tungstenite 0.30.0` annoncent un MSRV `1.85` ; +- `tokio-tungstenite` fournit `connect`/`handshake` par défaut mais pas de backend TLS obligatoire ; +- les features `native-tls` et `rustls-*` restent optionnelles ; +- Tungstenite expose déjà des limites configurables de message, frame et write buffer. + +Aucune de ces dépendances n'est ajoutée dans `alpha.1`. Le plan les introduira uniquement dans la crate backend qui les consomme. + +## Ownership et contrat retenus + +Le plan `docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md` retient deux frontières physiques : + +```text +crates/common/game-realtime-transport-lib +crates/common/game-realtime-websocket-lib +``` + +`game-realtime-transport-lib` portera uniquement le contrat transport-neutral : payload binaire opaque, send/receive/close, fermeture distante, erreurs transport-neutral et split concurrent. Elle ne dépendra ni de Tokio ni de Tungstenite. + +`game-realtime-websocket-lib` portera l'établissement client/server, Tokio, `tokio-tungstenite`, le mapping des frames, les limites, timeouts, close handshake, tracing et tests loopback localhost. + +Décisions structurantes : + +- runtime Tokio possédé par l'application/service/test consommateur, jamais créé globalement par le backend ; +- aucune tâche backend détachée nécessaire au chemin de base ; +- aucun codec métier dans `0.3.4` : le transport véhicule des octets opaques ; +- aucune abstraction générique `Connector`/`Provider`/runtime avant besoin démontré ; +- baseline locale en `ws://`, sans choix TLS prématuré ; +- aucune file interne non bornée ; +- tests loopback sur `127.0.0.1:0`, sans Internet ni port fixe ; +- aucune dépendance `tokio-tungstenite` dans `crates/games/` ou `crates/engines/`. + +Les limites et timeouts candidats, le modèle d'erreur, le lifecycle, le tracing et la matrice de tests sont détaillés dans le plan actif. Les signatures Rust exactes restent volontairement à fermer dans `alpha.2`, après validation de ce cadrage. + +## Forecast révisé + +Le plan actif retient : + +```text +0.3.4-alpha.1 gouvernance + audit + ownership + contrat +0.3.4-alpha.2 API game-realtime-transport-lib +0.3.4-alpha.3 backend game-realtime-websocket-lib + loopback +0.3.4-alpha.4 robustesse + limites + lifecycle + consolidation +0.3.4-alpha.5 uniquement si un demo/consolidation autonome est réellement utile +0.3.4-beta.1 validation large +0.3.4-rc.1 candidate gelée + publication documentaire +0.3.4 promotion mécanique stable +``` + +Le scope reste compatible avec une seule version/session tant qu'il ne dérive pas vers le wire codec, la session multijoueur, TLS/PKI produit ou WebTransport/QUIC. + +## Fichiers + +Ajoutés : + +```text +deltas/0.3.4/alpha.1.md +docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md +``` + +Modifiés : + +```text +Cargo.toml +README.md +RULES.md +docs/000-README.md +docs/plans/000-README.md +docs/rules/PROMPT_STRUCTURE.md +docs/rules/RULES_DOCUMENTATION.md +docs/rules/RULES_SESSION_PLANNING.md +docs/rules/RULES_VALIDATION_MATRIX.md +docs/rules/VERSION_WORKFLOW.md +history/000-README.md +scripts/audit_project_workspace_rules.py +``` + +`ROADMAP.md`, `CHANGELOG.md`, les anciens prompts, anciens deltas et anciens historiques restent inchangés. + +## Validations exécutées dans l'environnement de génération + +Après constitution de l'état livré, le générateur a exécuté uniquement les audits statiques autorisés : + +```text +General Rust rule audit: clean +Rust export completeness audit: 0 candidate(s) +games.sasedev workspace audit: clean +Markdown table audit: clean (5 table(s), 244 file(s)) +Distribution layout audit: clean (49 required path(s), 8 forbidden path(s) absent) +``` + +Le contrôle ciblé de politique de version a également obtenu : + +```text +history/0.3.4/0-pre.1.md -> DOC-010, rejet attendu +history/0.3.4/alpha.1.md -> accepté +targeted version-policy probe: clean +``` + +L'historique antérieur à `0.3.4` reste accepté par l'audit workspace normal. + +Aucun `cargo check`, Clippy, test ou smoke post-delta n'est attribué au générateur. + +## Validation utilisateur demandée + +Le manifest Cargo et l'audit Python changent. Depuis la racine : + +```bash +cargo fmt --all +cargo fmt --all -- --check + +python3 scripts/audit_rust_workspace_rules.py +python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Android Web deltas history +python3 scripts/audit_distribution_layout.py + +cargo check --workspace +cargo clippy --workspace --all-targets --all-features -- -D warnings +``` + +Aucun test workspace complet n'est demandé dans `alpha.1` : aucun code Rust, aucune dépendance réseau et aucun comportement runtime ne changent. + +## Suite après validation + +Si cette gate est propre, `alpha.2` crée `history/0.3.4/alpha.1.md` avec les sorties réellement obtenues, puis introduit `game-realtime-transport-lib` sans Tokio/Tungstenite. + +Une erreur de migration, d'audit, de plan ou de versionnement produit d'abord `0.3.4-alpha.1.fix.N`. diff --git a/docs/000-README.md b/docs/000-README.md index 7cc9944..49a719c 100644 --- a/docs/000-README.md +++ b/docs/000-README.md @@ -1,5 +1,5 @@ - + # Documentation games.sasedev @@ -17,7 +17,8 @@ - [`plans/000-README.md`](plans/000-README.md) — plans vivants des versions ; le plan actif porte notamment le découpage prévisionnel souple des prereleases. - [`plans/001-V0_3_0_WEB_SNAKE_POC_PLAN.md`](plans/001-V0_3_0_WEB_SNAKE_POC_PLAN.md) — plan clôturé de `0.3.0`, premier POC Snake Web direct. - [`plans/002-V0_3_1_TAURI_ANDROID_SNAKE_PLAN.md`](plans/002-V0_3_1_TAURI_ANDROID_SNAKE_PLAN.md) — plan clôturé de `0.3.1`, second host Snake Tauri Android. -- [`plans/003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md`](plans/003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md) — plan actif de `0.3.3`, pipeline Android SDL3 natif Gradle/Cargo multi-ABI. +- [`plans/003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md`](plans/003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md) — plan clôturé de `0.3.3`, pipeline Android SDL3 natif Gradle/Cargo multi-ABI. +- [`plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md`](plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md) — plan actif de `0.3.4`, API de transport realtime et baseline WebSocket Tokio/tokio-tungstenite. ## Architecture diff --git a/docs/plans/000-README.md b/docs/plans/000-README.md index 2f5c57a..54bfa0d 100644 --- a/docs/plans/000-README.md +++ b/docs/plans/000-README.md @@ -1,11 +1,11 @@ - + # Plans de versions games.sasedev Ce répertoire contient les plans vivants des versions concrètes. -Un plan est créé ou révisé pendant `0-pre.1`. Il conserve le scope, les décisions utiles, les validations et surtout le découpage prévisionnel souple des tranches jusqu'à la release. Il peut évoluer lorsque les audits ou validations imposent de scinder, fusionner, reporter ou corriger une tranche. +Un plan est créé ou révisé pendant `alpha.1`. Il conserve le scope, les décisions utiles, les validations et surtout le découpage prévisionnel souple des tranches jusqu'à la release. Il peut évoluer lorsque les audits ou validations imposent de scinder, fusionner, reporter ou corriger une tranche. Le `ROADMAP.md` reste la trajectoire macroscopique du projet ; les deltas décrivent ce qui a réellement été livré. Le plan se situe entre les deux et sert au suivi de la version en cours. @@ -14,3 +14,4 @@ Le `ROADMAP.md` reste la trajectoire macroscopique du projet ; les deltas décri - [`001-V0_3_0_WEB_SNAKE_POC_PLAN.md`](001-V0_3_0_WEB_SNAKE_POC_PLAN.md) — plan clôturé de `0.3.0`, baseline Snake et premier POC Web direct. - [`002-V0_3_1_TAURI_ANDROID_SNAKE_PLAN.md`](002-V0_3_1_TAURI_ANDROID_SNAKE_PLAN.md) — plan clôturé de `0.3.1`, second host Snake Tauri Android. - [`003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md`](003-V0_3_3_ANDROID_NATIVE_MULTI_ABI_PLAN.md) — plan clôturé de `0.3.3`, pipeline Android SDL3 natif Gradle/Cargo multi-ABI. +- [`004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md`](004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md) — plan actif de `0.3.4`, API de transport realtime et baseline WebSocket Tokio/tokio-tungstenite. diff --git a/docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md b/docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md new file mode 100644 index 0000000..6a3f041 --- /dev/null +++ b/docs/plans/004-V0_3_4_REALTIME_TRANSPORT_WEBSOCKET_PLAN.md @@ -0,0 +1,481 @@ + + + +# Plan 0.3.4 — transport realtime et baseline WebSocket + +## Statut + +Plan actif créé pendant `0.3.4-alpha.1` à partir de l'archive taggée `v0.3.3`. + +La tranche `alpha.1` migre d'abord la gouvernance de version vers `alpha.N / beta.N / rc.N`, audite la baseline et ferme les décisions d'ownership avant toute implémentation réseau lourde. + +## Mission + +`0.3.4` doit introduire une frontière de transport realtime async et une première implémentation WebSocket fondée sur Tokio + `tokio-tungstenite`, sans implémenter le protocole de session, la synchronisation gameplay ni la simulation authoritative. + +La frontière reste : + +```text +transport + ↓ +wire codec + ↓ +session protocol + ↓ +synchronization + ↓ +authoritative simulation +``` + +Le transport de `0.3.4` transporte des octets opaques. Il ne connaît ni joueur, ni room, ni tick, ni snapshot, ni delta métier. + +## Baseline auditée + +L'archive fournie comme téléchargement du tag `v0.3.3` est traitée comme autoritaire conformément à `CMD-GIT-003` et `CMD-GIT-004`. + +L'audit local de l'archive confirme : + +- archive ZIP intègre, sans chemin traversant ni symlink ; +- `400` fichiers, `14` membres Cargo et `55` fichiers Rust ; +- `workspace.package.version = 0.3.3` avant migration ; +- audits Rust/workspace, Markdown et distribution propres sur l'archive ; +- aucune arborescence générée `target/`, `node_modules/`, `gen/android` ou `build/` livrée ; +- gameplay et moteurs sans dépendance réseau realtime ; +- baseline Android `0.3.3` conservée et hors scope de cette version. + +Le log utilisateur fourni à l'ouverture de session confirme également `cargo fmt`, `cargo check --workspace` et Clippy workspace strict sur son checkout `0.3.3`. Son audit Markdown annonce davantage de fichiers que l'archive taggée fournie ; la présente version reste néanmoins construite exclusivement depuis l'archive autoritaire reçue et n'invente aucun fichier absent de celle-ci. + +## Migration de gouvernance + +À partir de `0.3.4`, les seules formes de prerelease nouvelles sont : + +```text +X.Y.Z-alpha.N +X.Y.Z-alpha.N.fix.M +X.Y.Z-beta.N +X.Y.Z-beta.N.fix.M +X.Y.Z-rc.N +X.Y.Z-rc.N.fix.M +``` + +`alpha.1` remplace l'ancien rôle de cadrage `0-pre.1`. + +Les anciens labels `0-pre`, `1-alpha`, `2-beta` et `3-rc` restent valides uniquement comme preuves historiques déjà livrées. Les audits distinguent donc la convention courante de la compatibilité historique et n'autorisent plus l'ancien schéma pour un nouveau workspace ou un nouvel historique `0.3.4+`. + +## Dépendances vérifiées au 2026-09-21 + +Versions amont observées pour la future implémentation : + +```text +Tokio 1.53.1 +futures-util 0.3.34 +tokio-tungstenite 0.30.0 +tungstenite 0.30.0, via réexport tokio-tungstenite +``` + +Contraintes utiles : + +- Tokio `1.53.1` annonce un MSRV `1.71` ; +- `tokio-tungstenite 0.30.0` et `tungstenite 0.30.0` annoncent un MSRV `1.85` ; +- `tokio-tungstenite` dépend déjà de Tokio `1.x` et de Tungstenite `0.30.0` ; +- ses features par défaut couvrent `connect` et `handshake`, sans TLS ; +- `native-tls` et les variantes `rustls-*` sont optionnelles ; +- Tungstenite expose déjà des limites de message/frame et de write buffer configurables. + +La compatibilité effective de la toolchain utilisateur avec ces MSRV sera attestée par les gates Cargo de la tranche qui introduira réellement les dépendances. Elles ne sont pas ajoutées pendant `alpha.1` : elles seront introduites uniquement avec les crates qui les consomment réellement. + +## Ownership physique retenu + +### `game-realtime-transport-lib` + +Créer sous : + +```text +crates/common/game-realtime-transport-lib +``` + +Responsabilités : + +- contrat transport-neutral ; +- payload binaire opaque ; +- distinction send/receive/close ; +- fermeture distante explicite ; +- catégories d'erreur transport-neutral ; +- contrat de split permettant lecture et écriture concurrentes ; +- aucune dépendance à Tokio, Tungstenite, HTTP, TLS, SDL, Tauri, WASM, moteur ou gameplay. + +Cette crate est une capability technique commune indépendante d'une génération de moteur. Elle n'est pas placée dans `engine-v1-*`. + +### `game-realtime-websocket-lib` + +Créer sous : + +```text +crates/common/game-realtime-websocket-lib +``` + +Responsabilités : + +- implémentation WebSocket du contrat transport ; +- `tokio-tungstenite` et Tokio réseau/temps ; +- connexion client WebSocket ; +- bind/accept serveur local ; +- mapping des frames WebSocket vers le contrat binaire ; +- close handshake, erreurs, timeouts, limites et tracing spécifiques au backend ; +- tests loopback localhost. + +Le backend dépend de `game-realtime-transport-lib`. L'inverse est interdit. + +### Dépendances interdites + +Aucune crate sous : + +```text +crates/games/ +crates/engines/ +``` + +doit dépendre de `tokio-tungstenite` ou du backend WebSocket pendant `0.3.4`. + +Aucun contrat gameplay n'est déplacé vers les crates transport pour fabriquer artificiellement un consommateur. + +## Contrat transport minimal + +Le contrat public doit rester suffisamment petit pour être implémentable par WebSocket puis confronté au POC WebTransport de `0.3.5`. + +### Payload + +Le message transport est un buffer binaire possédé, conceptuellement `Vec`. + +Décisions : + +- aucune variante texte dans l'API transport-neutral ; +- aucun JSON, Serde, Protobuf ou codec gameplay dans `0.3.4` ; +- Ping/Pong WebSocket reste un détail du backend ; +- une frame Text reçue par le backend n'est pas promue en message métier et doit produire un comportement explicite, testé et tracé ; +- le futur wire codec consommera/produira ces octets au-dessus du transport. + +### Connexion et split + +Le contrat doit permettre conceptuellement : + +```text +connection.split() -> sender + receiver +sender.send(bytes) -> async Result +sender.close() -> async Result +receiver.receive() -> async Result +``` + +L'implémentation Rust exacte est décidée dans `alpha.2`, avec priorité à une API statiquement dispatchée et sans allocation de futures imposée uniquement pour obtenir un trait object. + +Le contrat doit supporter lecture et écriture concurrentes après split. Il n'expose pas de runtime Tokio et ne crée aucun executor. + +### Fermeture + +La fermeture distante n'est pas une erreur I/O générique. `receive()` doit pouvoir distinguer au minimum : + +- message binaire reçu ; +- fermeture distante propre ; +- erreur de transport. + +La fermeture locale est explicite via `close()`. + +Une cancellation de task/future n'est pas assimilée à une fermeture WebSocket propre. Abandonner le propriétaire de la connexion doit néanmoins libérer les ressources sans tâche backend détachée. + +### Erreurs + +Le contrat transport-neutral doit représenter au minimum les catégories suivantes sans exposer les types d'erreur de Tungstenite : + +```text +invalid endpoint/configuration +connect/bind/accept failure +timeout +message too large +backpressure/write buffer full +connection closed +I/O failure +protocol/backend failure +cancelled/operation aborted lorsque cette distinction est réellement observable +``` + +Les détails backend peuvent être conservés pour `Display`/source/tracing sans faire remonter `tungstenite::Error` dans l'API commune. + +## Ownership Tokio/runtime + +Le runtime est possédé par l'application, le service ou le test consommateur. + +`game-realtime-websocket-lib` : + +- utilise les primitives Tokio nécessaires ; +- ne crée pas de runtime global ; +- ne lance pas de thread runtime privé ; +- évite les tâches détachées pour la connexion de base ; +- ne propage aucune dépendance Tokio dans le gameplay. + +Les tests peuvent utiliser `#[tokio::test]` comme harness de validation, sans transformer la macro en contrat public. + +## Client et serveur + +La séparation retenue est asymétrique et minimale : + +- le contrat commun modélise une connexion déjà établie et ses deux moitiés ; +- le backend WebSocket possède les constructeurs concrets client/server ; +- aucun trait générique `Connector`, `Listener`, `Server`, `Provider` ou `Runtime` n'est créé dans `alpha.2` sans besoin démontré ; +- le client peut exposer une connexion à partir d'un endpoint WebSocket ; +- le serveur peut binder une adresse socket puis accepter une connexion ; +- le futur backend WebTransport pourra proposer ses propres étapes d'établissement tout en produisant une connexion compatible lorsque cela reste pertinent. + +Cette décision évite de forcer aujourd'hui WebSocket et QUIC à partager artificiellement des opérations d'établissement différentes. + +## TLS + +La baseline `0.3.4` est d'abord un POC transport local reproductible en `ws://`. + +Aucune feature TLS de `tokio-tungstenite` n'est activée par défaut dans la première implémentation. `wss://` pourra être ajouté si un consommateur direct ou la stratégie de terminaison TLS le justifie réellement. + +Cette décision : + +- réduit les dépendances initiales ; +- évite de choisir prématurément `native-tls` contre `rustls` ; +- n'interdit pas une terminaison TLS future en reverse proxy ; +- ne présente pas le WebSocket local de test comme configuration de production Internet. + +## Timeouts et backpressure + +### Principes + +- aucune file interne non bornée ; +- `send()` attend la capacité du sink au lieu d'accumuler des messages arbitrairement ; +- les limites Tungstenite sont configurées explicitement et ne restent pas implicitement aux maxima amont ; +- l'absence de message reçu n'est pas un timeout de transport automatique : heartbeat/idle/session timeout appartient à la couche supérieure ; +- connect, send et fermeture propre disposent de bornes configurables afin qu'une opération locale ne reste pas bloquée indéfiniment. + +### Valeurs de baseline proposées + +Valeurs initiales, configurables et non assimilées à un protocole gameplay final : + +```text +max message size 1 MiB +max frame size 1 MiB +write buffer target 64 KiB +max write buffer 2 MiB +connect timeout 10 s +send timeout 5 s +close timeout 2 s +receive idle timeout aucun au niveau transport +``` + +Le choix `2 MiB` pour le write buffer maximum laisse au moins la place au buffer cible plus un message maximal. Les tests négatifs doivent vérifier le comportement limite plutôt que supposer que ces constantes resteront éternellement inchangées. + +## Tracing + +Domaines proposés : + +```text +games::realtime::transport +games::realtime::websocket +``` + +Le tracing doit couvrir au minimum connexion, accept, fermeture, timeout, rejet de message hors limite et erreurs backend. + +Ne pas logguer par défaut le contenu brut des payloads de transport. + +Les futurs domaines session/sync/simulation utilisent des targets distinctes. + +## Tests retenus + +### Contrat commun + +Tests unitaires ciblés : + +- types d'erreur et affichage ; +- invariants de configuration réellement portés par la crate commune ; +- aucune dépendance au backend concret. + +### Backend WebSocket + +Tests d'intégration localhost déterministes avec `127.0.0.1:0` : + +1. bind serveur sur port éphémère ; +2. connexion client ; +3. client → serveur : payload binaire ; +4. serveur → client : réponse binaire ; +5. fermeture propre initiée d'un côté et observée de l'autre ; +6. dépassement de taille rejeté ; +7. comportement explicite sur frame Text ; +8. connexion interrompue/peer drop ; +9. timeout d'opération retenu ; +10. backpressure/write-buffer error provoquée par un test borné si elle est reproductible sans test flaky. + +Les tests ne dépendent ni d'Internet, ni d'un serveur externe, ni d'un port fixe. + +Un petit demo/CLI n'est pas prévu par défaut : il sera créé uniquement si les tests publics ne prouvent pas suffisamment le chemin client/server. + +## Gates par jalon + +### `alpha.1` + +Changements : gouvernance, audit Python, version workspace, plan et delta. + +Gate utilisateur : + +```bash +cargo fmt --all +cargo fmt --all -- --check + +python3 scripts/audit_rust_workspace_rules.py +python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Android Web deltas history +python3 scripts/audit_distribution_layout.py + +cargo check --workspace +cargo clippy --workspace --all-targets --all-features -- -D warnings +``` + +Aucun test runtime réseau n'est requis avant l'existence du code réseau. + +### `alpha.2` + +Ajouter `game-realtime-transport-lib`, ses tests ciblés et sa documentation publique. + +Gate minimale supplémentaire : + +```bash +cargo test -p game-realtime-transport-lib --all-targets --all-features +``` + +### `alpha.3` + +Ajouter `game-realtime-websocket-lib`, les dépendances backend et le loopback principal. + +Gates ciblées : + +```bash +cargo test -p game-realtime-transport-lib --all-targets --all-features +cargo test -p game-realtime-websocket-lib --all-targets --all-features +cargo tree -p game-realtime-websocket-lib --edges normal +``` + +### `alpha.4` + +Fermer robustesse, limites, timeouts, close/cancellation et cas négatifs. Réexécuter les tests des deux crates. Un demo n'est ajouté que si une preuve manque réellement. + +### Beta + +La beta est le jalon large retenu pour : + +```bash +cargo test --workspace --all-targets --all-features +``` + +Elle revalide également audits, format/check, Clippy, tests loopback et graphe de dépendances. + +### RC + +La RC gèle le comportement et rejoue les gates de publication utiles. Le test workspace complet n'est répété que si un fix depuis la beta a modifié du Rust, des dépendances ou une frontière transverse qui le justifie. + +## Forecast révisé + +### `0.3.4-alpha.1` — gouvernance, audit et contrat + +- migrer les règles prospectives ; +- adapter l'audit de version sans casser l'historique ; +- synchroniser la version workspace ; +- vérifier dépendances et contraintes amont ; +- décider ownership, contrat, erreurs, lifecycle, limites et tests ; +- créer le présent plan. + +Aucune dépendance réseau n'est ajoutée. + +### `0.3.4-alpha.2` — API transport-neutral + +- créer `game-realtime-transport-lib` ; +- implémenter message, receive/close, erreurs et split ; +- conserver l'API sans Tokio/Tungstenite ; +- tests unitaires ciblés ; +- README/USAGE uniquement si une valeur durable est démontrée par `DOC-CRATE-*`. + +### `0.3.4-alpha.3` — backend WebSocket et loopback + +- créer `game-realtime-websocket-lib` ; +- ajouter Tokio, `tokio-tungstenite` et `futures-util` avec features minimales ; +- client connect + serveur bind/accept ; +- mapping binaire, tracing, close ; +- round-trip localhost déterministe. + +### `0.3.4-alpha.4` — robustesse et consolidation technique + +- limites explicites ; +- timeouts ; +- fermeture distante/abrupt drop ; +- cas Text non supporté ; +- backpressure bornée ; +- cancellation/lifecycle sans tâche orpheline ; +- documentation API/backend et audit du graphe. + +Cette tranche peut absorber la consolidation avant beta si elle reste dans le budget. Si elle devient trop lourde, une `alpha.5` de consolidation est créée ; elle ne doit pas être ajoutée uniquement pour suivre un numéro prévu. + +### `0.3.4-beta.1` — validation large + +- aucun nouveau scope ; +- test workspace complet planifié ; +- tests loopback/negatifs ; +- dépendances et frontières vérifiées ; +- confirmation qu'aucun gameplay/engine ne dépend du backend WebSocket. + +Un défaut fermé produit `beta.1.fix.N`. Une capacité manquante réouvre une alpha. + +### `0.3.4-rc.1` — candidate gelée + +- scope gelé ; +- `CHANGELOG.md` ; +- `ROADMAP.md` si statut macro à réconcilier ; +- historique beta ; +- documentation finale ; +- prompt `0.3.5` préparant WebTransport/QUIC sur la même frontière ; +- aucune abstraction nouvelle sans défaut de release. + +### `0.3.4` — stable + +Promotion mécanique : version stable, historique RC, changelog stable, clôture du plan, delta final et ajustement mécanique du prompt suivant. + +## Sizing + +Le scope reste compatible avec une seule version/session : deux petites crates techniques, un seul backend concret et des tests locaux. Le POC WebTransport/QUIC, la session multijoueur et la simulation authoritative sont explicitement exclus. + +Un split vers une autre version est requis si l'une des conditions suivantes apparaît : + +- besoin d'un vrai wire codec partagé pour prouver le transport ; +- nécessité de concevoir le protocole session/joueur/room ; +- TLS direct nécessitant une politique de certificats/PKI produit ; +- abstraction commune WebSocket/QUIC exigeant déjà des concepts spécifiques à QUIC ; +- demo/app devenant un produit autonome plutôt qu'un harness de preuve. + +## Hors scope confirmé + +- Uroburas Mode 3 ; +- matchmaking ; +- auth complète ; +- snapshots/deltas métier ; +- prediction/reconciliation ; +- rollback ; +- persistence gameplay ; +- Redis/NATS/Kafka ; +- scaling/sharding/regions ; +- WebTransport/QUIC productif ; +- Actix Web dans le data plane realtime ; +- modification du pipeline Android `0.3.3` sans régression causée par `0.3.4`. + +## Critères d'entrée en beta + +`0.3.4` peut entrer en beta lorsque : + +- l'API commune ne dépend ni de Tokio ni de WebSocket ; +- le backend WebSocket implémente le contrat public sans fuite de types Tungstenite ; +- client et serveur round-tripent des payloads binaires sur localhost ; +- close local/distant est observable ; +- limites et timeouts retenus sont testés ; +- aucun queueing non borné ni runtime privé n'est introduit ; +- les targets tracing transport/WebSocket sont distinctes des futurs domaines session/sync/simulation ; +- aucune crate gameplay ou engine ne dépend de `tokio-tungstenite` ; +- les audits et tests ciblés sont propres ; +- la documentation décrit ce qui est réellement implémenté et ce qui reste reporté. diff --git a/docs/rules/PROMPT_STRUCTURE.md b/docs/rules/PROMPT_STRUCTURE.md index 520b792..f530169 100644 --- a/docs/rules/PROMPT_STRUCTURE.md +++ b/docs/rules/PROMPT_STRUCTURE.md @@ -1,5 +1,5 @@ - + # Structure des prompts de reprise @@ -15,7 +15,7 @@ Le prompt rappelle les invariants qui évitent les erreurs de workflow et renvoi - **PROMPT-STR-002** — Le prompt fournit un ordre de lecture court des sources de vérité : `RULES.md`, `ROADMAP.md`, `CHANGELOG.md`, `docs/000-README.md`, règles directement pertinentes, plan/historique de la version précédente et documents d'architecture concernés. - **PROMPT-STR-003** — Le prompt distingue explicitement l'état déjà validé hérité de la baseline des validations qui devront être exécutées dans la nouvelle version. - **PROMPT-STR-004** — Le prompt décrit la mission, le résultat attendu, le scope inclus, le hors-périmètre et les invariants architecturaux gelés. -- **PROMPT-STR-005** — Le prompt rappelle que `0-pre.1` est le gate de cadrage : audit, requirements, sizing, risques, validations prévues et création/révision du plan sous `docs/plans/` avant développement lourd. +- **PROMPT-STR-005** — Le prompt rappelle que `alpha.1` est le gate de cadrage : audit, requirements, sizing, risques, validations prévues et création/révision du plan sous `docs/plans/` avant développement lourd. - **PROMPT-STR-006** — Le prompt contient un forecast souple jusqu'à la stable. Il réserve les responsabilités de développement, validation large, consolidation documentaire, préparation de publication/RC et release mécanique sans rendre les numéros immuables. - **PROMPT-STR-007** — Le prompt rappelle où se trouve la définition des commandes : `docs/rules/RULES_COMMANDS.md` pour la politique d'exécution et `docs/rules/RULES_VALIDATION_MATRIX.md` pour les IDs, dépendances et déclencheurs. Il ne recopie que les commandes indispensables à la reprise ou au premier gate. - **PROMPT-STR-008** — Le prompt rappelle la séparation utilisateur/générateur : les audits statiques peuvent être exécutés par le générateur, mais les builds, tests et smokes finaux restent côté utilisateur conformément à `CMD-BUILD-005` et ne sont jamais déclarés réussis sans sortie réelle. @@ -30,7 +30,7 @@ Le prompt rappelle les invariants qui évitent les erreurs de workflow et renvoi - **PROMPT-STR-010** — Le prompt rappelle que `deltas/` décrit la livraison candidate et ses validations attendues, alors que `history/` enregistre uniquement le résultat d'un jalon effectivement accepté. - **PROMPT-STR-011** — Le prompt rappelle qu'une entrée `history//.md` est créée par le delta suivant ou le fix suivant après validation, jamais avant la validation qu'elle décrit. -- **PROMPT-STR-012** — Le prompt rappelle que `CHANGELOG.md` n'est normalement mis à jour qu'à partir de la RC puis à la stable ; les détails `pre`/`beta` restent dans `deltas/` et `history/`. +- **PROMPT-STR-012** — Le prompt rappelle que `CHANGELOG.md` n'est normalement mis à jour qu'à partir de la RC puis à la stable ; les détails `alpha`/`beta` restent dans `deltas/` et `history/`. - **PROMPT-STR-013** — Le prompt rappelle que `ROADMAP.md` reste macroscopique et n'est modifié que lorsque le scope, son ordre ou son statut évolue réellement ; le plan de version porte le découpage fin. - **PROMPT-STR-014** — Le prompt rappelle que la documentation propre à une fonctionnalité évolue avec la tranche qui l'introduit ; la consolidation finale réconcilie l'ensemble mais ne sert pas à repousser toute documentation à la fin. - **PROMPT-STR-015** — Le prompt mentionne explicitement la politique `README.md`/`USAGE.md` lorsque la version crée ou finalise une crate, une application ou un package : appliquer `DOC-CRATE-*` et décider dans le plan quels fichiers ont une valeur durable réelle. diff --git a/docs/rules/RULES_DOCUMENTATION.md b/docs/rules/RULES_DOCUMENTATION.md index d01734c..000d45c 100644 --- a/docs/rules/RULES_DOCUMENTATION.md +++ b/docs/rules/RULES_DOCUMENTATION.md @@ -1,5 +1,5 @@ - + # Règles de documentation @@ -74,7 +74,7 @@ ## CHANGELOG - **DOC-CHG-001** — `CHANGELOG.md` est une synthèse de publication, pas un journal de développement. -- **DOC-CHG-002** — Les `pre.*`, `alpha.*`, `beta.*` et leurs `.fix.*` ne créent normalement aucune entrée de changelog. +- **DOC-CHG-002** — Les `alpha.*`, `beta.*` et leurs `.fix.*` ne créent normalement aucune entrée de changelog. - **DOC-CHG-003** — Le changelog est mis à jour à partir des jalons `rc.*` et pour chaque release stable. - **DOC-CHG-004** — Une entrée RC résume l'état candidat à publication ; l'entrée stable résume le résultat effectivement publié. - **DOC-CHG-005** — Les détails intermédiaires de construction, corrections et validations restent dans `deltas/` et `history/`. @@ -92,7 +92,7 @@ - **DOC-VAL-001** — Une gate Markdown ou un audit syntaxique valide la forme des documents, jamais leur exactitude fonctionnelle, leur exhaustivité ni leur acceptation. - **DOC-VAL-002** — Une prerelease principalement documentaire reste candidate tant que son contenu n'a pas été relu et accepté humainement. -- **DOC-VAL-003** — Une version de conception peut utiliser plusieurs `pre.N` successives uniquement pour permettre revue, correction, complément et maturation documentaire. +- **DOC-VAL-003** — Une version de conception peut utiliser plusieurs `alpha.N` successives uniquement pour permettre revue, correction, complément et maturation documentaire. - **DOC-VAL-004** — Cargo, Gradle, packaging et smoke tests ne sont requis pour une prerelease documentaire que si le delta modifie du code, une configuration de build/runtime ou un contrat susceptible de les affecter. - **DOC-VAL-005** — Le document de delta énumère les validations applicables ; l'absence volontaire d'une gate technique doit découler du scope réel, pas d'un raccourci. - **DOC-VAL-006** — Une version documentaire n'est promue en `rc` ou stable qu'après validation explicite de son contenu, même si tous les audits automatisés sont propres. diff --git a/docs/rules/RULES_SESSION_PLANNING.md b/docs/rules/RULES_SESSION_PLANNING.md index 21c3fa9..c41f67c 100644 --- a/docs/rules/RULES_SESSION_PLANNING.md +++ b/docs/rules/RULES_SESSION_PLANNING.md @@ -1,5 +1,5 @@ - + # Règles de cadrage des versions, sessions et prompts @@ -7,26 +7,26 @@ Ces règles imposent un découpage suffisamment petit pour qu'une version puisse être développée complètement dans une seule session et reprise sans ambiguïté. -## `pre.1` — cadrage obligatoire +## `alpha.1` — cadrage obligatoire -- **SESSION-001** — Toute nouvelle version commence par une `0-pre.1` de cadrage. +- **SESSION-001** — Toute nouvelle version commence par une `alpha.1` de cadrage. - **SESSION-002** — Cette tranche couvre au minimum l'audit de la base, le brainstorming/recherche de requirements, le sizing, les dépendances, les validations prévues et le découpage prévisionnel. -- **SESSION-003** — Une première implémentation peut être incluse dans `0-pre.1` uniquement si elle est petite, cohérente et n'empêche pas le cadrage d'être terminé. +- **SESSION-003** — Une première implémentation peut être incluse dans `alpha.1` uniquement si elle est petite, cohérente et n'empêche pas le cadrage d'être terminé. - **SESSION-004** — Si le sizing montre que l'objectif global ne peut raisonnablement pas être terminé dans la session, il est scindé en plusieurs versions avant le développement lourd. -- **SESSION-005** — `0-pre.1` crée ou révise obligatoirement le plan de la version sous `docs/plans/`. Ce plan est un livrable du cadrage, pas une note optionnelle. +- **SESSION-005** — `alpha.1` crée ou révise obligatoirement le plan de la version sous `docs/plans/`. Ce plan est un livrable du cadrage, pas une note optionnelle. - **SESSION-006** — Le plan de version contient au minimum l'objectif et le scope, les décisions acquises, les dépendances/risques utiles, les validations attendues, les hors-périmètre et une prévision souple des tranches jusqu'à la release stable. - **SESSION-007** — La prévision du plan n'est pas un calendrier figé : une tranche peut être scindée, fusionnée, déplacée ou complétée par un fix lorsque les résultats réels le justifient. Le plan actif est alors réconcilié et le delta explique le changement. - **SESSION-008** — `ROADMAP.md` reste macroscopique, le plan porte le découpage prévisionnel fin de la version et les deltas enregistrent ce qui a réellement été livré. -- **SESSION-009** — Le forecast créé en `0-pre.1` rend explicitement visible une tranche de consolidation avant la candidate finale ; cette tranche couvre au minimum la réconciliation de la documentation durable, `CHANGELOG.md`, `ROADMAP.md`, l'historique applicable et le prompt de la version/session suivante, même si son numéro exact reste prévisionnel. +- **SESSION-009** — Le forecast créé en `alpha.1` rend explicitement visible une tranche de consolidation avant la candidate finale ; cette tranche couvre au minimum la réconciliation de la documentation durable, `CHANGELOG.md`, `ROADMAP.md`, l'historique applicable et le prompt de la version/session suivante, même si son numéro exact reste prévisionnel. ## Taille des tranches -- **SESSION-010** — Une tranche `pre.N`, `alpha.N`, `beta.N`, `rc.N` ou `fix.N` vise normalement un delta correspondant à environ 15 à 30 minutes de travail effectif. +- **SESSION-010** — Une tranche `alpha.N`, `beta.N`, `rc.N` ou `fix.N` vise normalement un delta correspondant à environ 15 à 30 minutes de travail effectif. - **SESSION-011** — Une tranche clairement plus lourde est scindée avant exécution. - **SESSION-012** — Plusieurs micro-tranches sans valeur de validation indépendante peuvent être regroupées. - **SESSION-013** — Le découpage suit des unités fonctionnelles complètes et validables ; une fonctionnalité ne doit pas être volontairement coupée au milieu uniquement pour respecter un numéro de prerelease. - **SESSION-014** — Chaque tranche livre son delta et ses validations proportionnelles avant la tranche suivante. -- **SESSION-015** — Le plan créé en `0-pre.1` identifie explicitement le ou les rares jalons où `cargo test --workspace --all-targets --all-features` apporte une valeur globale (initial si nécessaire, préfinal/final ou changement transverse). Les autres tranches privilégient les tests `cargo test -p ...` ciblés. +- **SESSION-015** — Le plan créé en `alpha.1` identifie explicitement le ou les rares jalons où `cargo test --workspace --all-targets --all-features` apporte une valeur globale (initial si nécessaire, préfinal/final ou changement transverse). Les autres tranches privilégient les tests `cargo test -p ...` ciblés. ## Une version par session @@ -49,7 +49,7 @@ Ces règles imposent un découpage suffisamment petit pour qu'une version puisse - **PROMPT-005** — Le prompt rappelle les invariants essentiels mais renvoie aux RULES pour les détails normatifs au lieu de les recopier intégralement. - **PROMPT-006** — Le prompt contient suffisamment de contexte pour reprendre la version sans dépendre de la mémoire conversationnelle ni relire toute l'histoire du dépôt. - **PROMPT-007** — Le prompt précise la condition de fin de session et les livrables attendus. -- **PROMPT-008** — Si `pre.1` invalide le sizing prévu par le prompt, le nouveau découpage est documenté immédiatement avant le développement lourd. +- **PROMPT-008** — Si `alpha.1` invalide le sizing prévu par le prompt, le nouveau découpage est documenté immédiatement avant le développement lourd. - **PROMPT-009** — Tout nouveau prompt de version applique `docs/rules/PROMPT_STRUCTURE.md`; le présent document fixe le cycle de session tandis que `PROMPT_STRUCTURE.md` fixe le contenu opératoire à rappeler. ## Relation avec VERSION_WORKFLOW diff --git a/docs/rules/RULES_VALIDATION_MATRIX.md b/docs/rules/RULES_VALIDATION_MATRIX.md index 7ac81fd..6a9a946 100644 --- a/docs/rules/RULES_VALIDATION_MATRIX.md +++ b/docs/rules/RULES_VALIDATION_MATRIX.md @@ -1,5 +1,5 @@ - + # Matrice normative des commandes et validations @@ -15,30 +15,30 @@ Les commandes ciblées restent la norme pendant l'implémentation ; les gates wo | ID | Commande / action | Dépend de | Déclencheur principal | Phase minimale typique | |-----------|------------------------------------------------------------------------------------|---------------------------------|----------------------------------------------------|------------------------| -| `CMD-001` | `cargo fmt --all` | — | Rust ou dépendance Cargo modifiée | `pre` | -| `CMD-002` | `cargo fmt --all -- --check` | `CMD-001` | Rust ou dépendance Cargo modifiée | `pre` | -| `CMD-010` | `python3 scripts/audit_rust_workspace_rules.py` | — | Rust/Cargo/workspace/règles Rust concernés | `pre` | -| `CMD-011` | `python3 scripts/audit_markdown_tables.py ...` | — | Markdown concerné | `pre` | -| `CMD-012` | `python3 scripts/audit_distribution_layout.py` | — | layout/build/distribution concerné | `pre` | -| `CMD-020` | `cargo check -p ` | audits applicables | diagnostic ciblé facultatif | `pre` | -| `CMD-021` | `cargo test -p --all-targets --all-features` | `CMD-023`, `CMD-024` | comportement/API crate | `pre` | -| `CMD-022` | tests ciblés des crates consommatrices impactées | `CMD-021` | API publique/contrat partagé modifié | `pre` | -| `CMD-023` | `cargo check --workspace` | `CMD-002`, audits applicables | Rust ou dépendance Cargo modifiée | `pre` | -| `CMD-024` | `cargo clippy --workspace --all-targets --all-features -- -D warnings` | `CMD-023` | Rust ou dépendance Cargo modifiée | `pre` | +| `CMD-001` | `cargo fmt --all` | — | Rust ou dépendance Cargo modifiée | `alpha` | +| `CMD-002` | `cargo fmt --all -- --check` | `CMD-001` | Rust ou dépendance Cargo modifiée | `alpha` | +| `CMD-010` | `python3 scripts/audit_rust_workspace_rules.py` | — | Rust/Cargo/workspace/règles Rust concernés | `alpha` | +| `CMD-011` | `python3 scripts/audit_markdown_tables.py ...` | — | Markdown concerné | `alpha` | +| `CMD-012` | `python3 scripts/audit_distribution_layout.py` | — | layout/build/distribution concerné | `alpha` | +| `CMD-020` | `cargo check -p ` | audits applicables | diagnostic ciblé facultatif | `alpha` | +| `CMD-021` | `cargo test -p --all-targets --all-features` | `CMD-023`, `CMD-024` | comportement/API crate | `alpha` | +| `CMD-022` | tests ciblés des crates consommatrices impactées | `CMD-021` | API publique/contrat partagé modifié | `alpha` | +| `CMD-023` | `cargo check --workspace` | `CMD-002`, audits applicables | Rust ou dépendance Cargo modifiée | `alpha` | +| `CMD-024` | `cargo clippy --workspace --all-targets --all-features -- -D warnings` | `CMD-023` | Rust ou dépendance Cargo modifiée | `alpha` | | `CMD-025` | `cargo test --workspace --all-targets --all-features` | `CMD-024` | gate rare planifiée / portée transverse incertaine | selon plan | | `CMD-026` | `cargo tree -p --edges normal` ou variante ciblée | — | dépendances/features modifiées ou diagnostic | selon portée | | `CMD-030` | build Desktop `--release` ciblé | gates Rust applicables | runner/distribution Desktop touché | beta | | `CMD-031` | smoke Desktop release | `CMD-030` | runtime Desktop touché | beta | -| `CMD-040` | `(cd && cargo tauri dev)` | gates Rust/frontend applicables | smoke interactif Tauri Desktop | `pre`/beta | +| `CMD-040` | `(cd && cargo tauri dev)` | gates Rust/frontend applicables | smoke interactif Tauri Desktop | alpha/beta | | `CMD-041` | `(cd && cargo tauri build)` | gates Rust/frontend applicables | packaging Tauri Desktop final/prefinal | beta/RC | -| `CMD-042` | build Rust `wasm32-unknown-unknown` + `wasm-bindgen --target web` | gates Rust de l'adapter | adapter WASM/Web direct touché | `pre` | -| `CMD-043` | `(cd Web/ && npm install && npm run build)` | `CMD-042` si frontend avec WASM | frontend Web direct touché | `pre` | -| `CMD-044` | smoke navigateur du host Web direct | `CMD-043` | Canvas/input/responsive Web touchés | `pre`/beta | -| `CMD-045` | `(cd && cargo tauri android init)` | environnement Android/Tauri | initialisation unique de la cible Tauri Android | `pre` | -| `CMD-046` | `(cd && cargo tauri android dev)` | gates Rust/frontend applicables | smoke interactif Tauri Android | `pre`/beta | +| `CMD-042` | build Rust `wasm32-unknown-unknown` + `wasm-bindgen --target web` | gates Rust de l'adapter | adapter WASM/Web direct touché | `alpha` | +| `CMD-043` | `(cd Web/ && npm install && npm run build)` | `CMD-042` si frontend avec WASM | frontend Web direct touché | `alpha` | +| `CMD-044` | smoke navigateur du host Web direct | `CMD-043` | Canvas/input/responsive Web touchés | alpha/beta | +| `CMD-045` | `(cd && cargo tauri android init)` | environnement Android/Tauri | initialisation unique de la cible Tauri Android | `alpha` | +| `CMD-046` | `(cd && cargo tauri android dev)` | gates Rust/frontend applicables | smoke interactif Tauri Android | alpha/beta | | `CMD-047` | `(cd && cargo tauri android build)` | gates Rust/frontend applicables | packaging Tauri Android final/prefinal | beta/RC | -| `CMD-050` | build Rust Android ABI ciblé | gates Rust applicables | Android/JNI/backend natif touché | pre/beta | -| `CMD-051` | `(cd Android && gradle ::assembleDebug)` | `CMD-050` si Rust natif change | Android/app/manifest/Java touché | pre/beta | +| `CMD-050` | build Rust Android ABI ciblé | gates Rust applicables | Android/JNI/backend natif touché | alpha/beta | +| `CMD-051` | `(cd Android && gradle ::assembleDebug)` | `CMD-050` si Rust natif change | Android/app/manifest/Java touché | alpha/beta | | `CMD-052` | install + smoke AVD | `CMD-051` | Android concerné | beta | | `CMD-053` | install + smoke appareil réel | `CMD-051` | Android concerné | beta/RC | | `CMD-060` | `cargo clean --dry-run --verbose` | — | contrôle disque / préparation nettoyage | maintenance | diff --git a/docs/rules/VERSION_WORKFLOW.md b/docs/rules/VERSION_WORKFLOW.md index 4938803..ba60e9f 100644 --- a/docs/rules/VERSION_WORKFLOW.md +++ b/docs/rules/VERSION_WORKFLOW.md @@ -1,32 +1,31 @@ - + # Versionnement, maturité et livraisons ## SemVer canonique -Le projet utilise SemVer et les labels de maturité normalisés suivants : +À partir de `0.3.4`, le projet utilise SemVer et les labels de maturité normalisés suivants : ```text -X.Y.Z-0-pre.N -X.Y.Z-0-pre.N.fix.M -X.Y.Z-1-alpha.N -X.Y.Z-1-alpha.N.fix.M -X.Y.Z-2-beta.N -X.Y.Z-2-beta.N.fix.M -X.Y.Z-3-rc.N -X.Y.Z-3-rc.N.fix.M +X.Y.Z-alpha.N +X.Y.Z-alpha.N.fix.M +X.Y.Z-beta.N +X.Y.Z-beta.N.fix.M +X.Y.Z-rc.N +X.Y.Z-rc.N.fix.M X.Y.Z ``` `N` et `M` sont des entiers positifs sans zéro initial. +Les anciens labels `0-pre.N`, `1-alpha.N`, `2-beta.N` et `3-rc.N` appartiennent uniquement aux jalons livrés avant cette migration. Les fichiers historiques concernés restent immuables et leurs identifiants ne sont jamais normalisés rétroactivement. + ## Sens des niveaux -- `0-pre.N` : construction initiale, architecture et fonctionnalités encore très mouvantes ; -- `1-alpha.N` : périmètre fonctionnel principal établi mais encore incomplet ou instable ; -- `2-beta.N` : fonctionnalités attendues largement présentes, priorité à la stabilisation et aux tests ; -- `3-rc.N` : candidat de publication, aucune évolution non indispensable ; +- `alpha.N` : construction, architecture et fonctionnalités encore susceptibles d'évoluer ; `alpha.1` porte obligatoirement le cadrage de la version ; +- `beta.N` : fonctionnalités attendues largement présentes, priorité à la stabilisation et aux tests ; +- `rc.N` : candidat de publication, aucune évolution non indispensable ; - `X.Y.Z` : version stable. ## Correctifs @@ -34,13 +33,13 @@ X.Y.Z Un suffixe `.fix.M` corrige la prerelease immédiatement précédente sans changer son objectif fonctionnel. Exemple : ```text -0.1.0-0-pre.4 -0.1.0-0-pre.4.fix.1 -0.1.0-0-pre.4.fix.2 -0.1.0-0-pre.5 +0.3.4-alpha.2 +0.3.4-alpha.2.fix.1 +0.3.4-alpha.2.fix.2 +0.3.4-alpha.3 ``` -Après une version stable, un correctif produit normalement un nouveau patch SemVer, par exemple `0.1.1`, et non `0.1.0.fix.1`. +Après une version stable, un correctif produit normalement un nouveau patch SemVer, par exemple `0.3.5`, et non `0.3.4.fix.1`. ## Version workspace et versions autonomes @@ -64,19 +63,21 @@ Les documents sont rangés sous : deltas/X.Y.Z/.md ``` -Exemples : +Exemples canoniques pour les nouvelles versions : ```text -deltas/0.1.0/0-pre.1.md -deltas/0.1.0/0-pre.1.fix.1.md -deltas/0.1.0/1-alpha.1.md -deltas/0.1.0/3-rc.2.md -deltas/0.1.0/rel.md +deltas/0.3.4/alpha.1.md +deltas/0.3.4/alpha.1.fix.1.md +deltas/0.3.4/beta.1.md +deltas/0.3.4/rc.1.md +deltas/0.3.4/rel.001.md ``` +Les anciens chemins déjà livrés, par exemple `deltas/0.3.3/0-pre.1.md` ou `deltas/0.3.3/3-rc.1.md`, restent des preuves historiques valides et immuables. + ## Versions principalement documentaires -Une version de conception suit le même SemVer que les autres versions et peut utiliser plusieurs `0-pre.N` pour permettre une revue humaine progressive. +Une version de conception suit le même SemVer que les autres versions et peut utiliser plusieurs `alpha.N` pour permettre une revue humaine progressive. Les audits Markdown et de règles valident la cohérence mécanique mais ne valent jamais acceptation du fond documentaire. Une prerelease documentaire reste candidate jusqu'à revue explicite de son contenu. @@ -93,7 +94,7 @@ La promotion `rc` puis stable d'une version de conception exige une validation h - **VER-RC-001** — Une RC est fonctionnellement gelée. Les nouvelles fonctionnalités, nouvelles capabilities, refactors architecturaux non indispensables et changements volontaires de comportement sont interdits. - **VER-RC-002** — Les modifications de code restent autorisées en RC lorsqu'elles corrigent un bug, un test erroné, un défaut de packaging, un problème de sécurité, une incompatibilité de release ou un défaut strictement nécessaire à la publication. -- **VER-RC-003** — Un correctif conforme à `VER-RC-002` produit `3-rc.N.fix.M` et n'impose pas un retour automatique en beta. +- **VER-RC-003** — Un correctif conforme à `VER-RC-002` produit `rc.N.fix.M` et n'impose pas un retour automatique en beta. - **VER-RC-004** — Si le périmètre fonctionnel est rouvert pendant une RC, la candidate est abandonnée et le développement revient à une phase adaptée, normalement beta, avant une nouvelle RC. ## Prompt de la version suivante @@ -106,7 +107,7 @@ La promotion `rc` puis stable d'une version de conception exige une validation h ## Correctifs strictement documentaires - **VER-DOCFIX-001** — Un `.fix.N` limité à la documentation, aux prompts, aux deltas, à `history/` ou aux règles non consommées par le build/runtime ne modifie aucune version technique : ni `workspace.package.version`/`Cargo.toml`, ni `package.json`, ni Gradle/Android, ni `tauri.conf.json`, ni autre métadonnée de version consommée par un build ou une distribution. L'identité du correctif est portée uniquement par le delta et son archive. -- **VER-DOCFIX-002** — Une prerelease non-fix (`pre.N`, `alpha.N`, `beta.N`, `rc.N`) synchronise sa version technique selon le workflow de phase même lorsque son contenu est principalement documentaire. +- **VER-DOCFIX-002** — Une prerelease non-fix (`alpha.N`, `beta.N`, `rc.N`) synchronise sa version technique selon le workflow de phase même lorsque son contenu est principalement documentaire. - **VER-DOCFIX-003** — Dès qu'un correctif touche du code, une configuration exécutable, un manifeste consommé par le build/runtime ou un artefact distribué, la version technique suit l'identifiant `.fix.N`. ## Phases de développement @@ -118,11 +119,11 @@ PLAN → IMPLEMENT → INTEGRATE → VALIDATE → CANDIDATE → RELEASE ``` - **VER-PHASE-001** — Ces phases structurent le travail mais n'imposent pas une prerelease distincte pour chacune. -- **VER-PHASE-002** — `0-pre.1` est obligatoirement la tranche de cadrage de la version : audit de la base, brainstorming/recherche de requirements, sizing, planification, dépendances, validations attendues et création/révision du plan actif sous `docs/plans/` avec son découpage prévisionnel souple. -- **VER-PHASE-003** — `0-pre.1` peut aussi contenir une première implémentation strictement bornée si le cadrage montre qu'elle tient naturellement dans la même tranche, mais le cadrage ne doit jamais être sauté. +- **VER-PHASE-002** — `alpha.1` est obligatoirement la tranche de cadrage de la version : audit de la base, brainstorming/recherche de requirements, sizing, planification, dépendances, validations attendues et création/révision du plan actif sous `docs/plans/` avec son découpage prévisionnel souple. +- **VER-PHASE-003** — `alpha.1` peut aussi contenir une première implémentation strictement bornée si le cadrage montre qu'elle tient naturellement dans la même tranche, mais le cadrage ne doit jamais être sauté. - **VER-PHASE-004** — Une version doit être dimensionnée pour que l'ensemble de son développement puisse être terminé dans une seule session de travail. Si ce n'est pas réaliste, son objectif est découpé en plusieurs versions/sessions avant le développement lourd. -- **VER-PHASE-005** — Le plan établi en `0-pre.1` est vivant : il peut regrouper, scinder, reporter ou reclasser des tranches lorsque l'information réelle le justifie, sans réécrire les deltas déjà livrés. Il reste la référence de suivi prévisionnel de la version jusqu'à sa clôture. -- **VER-PHASE-006** — Une tranche `pre.N`, `alpha.N`, `beta.N`, `rc.N` ou leur fix vise normalement un delta réalisable en environ 15 à 30 minutes. Une tranche sensiblement plus lourde est découpée avant exécution ; une tranche trop petite peut être regroupée avec une tranche adjacente cohérente. +- **VER-PHASE-005** — Le plan établi en `alpha.1` est vivant : il peut regrouper, scinder, reporter ou reclasser des tranches lorsque l'information réelle le justifie, sans réécrire les deltas déjà livrés. Il reste la référence de suivi prévisionnel de la version jusqu'à sa clôture. +- **VER-PHASE-006** — Une tranche `alpha.N`, `beta.N`, `rc.N` ou leur fix vise normalement un delta réalisable en environ 15 à 30 minutes. Une tranche sensiblement plus lourde est découpée avant exécution ; une tranche trop petite peut être regroupée avec une tranche adjacente cohérente. - **VER-PHASE-007** — Le découpage privilégie des unités fonctionnelles complètes et validables, pas des coupures arbitraires au milieu d'une fonctionnalité. - **VER-PHASE-008** — Chaque tranche ferme son propre scope, produit son delta et ses validations proportionnelles avant l'ouverture de la tranche suivante. - **VER-PHASE-009** — Alpha, beta et RC sont utilisées proportionnellement au risque et à la maturité ; elles ne sont pas créées uniquement pour satisfaire une séquence cérémonielle. @@ -133,7 +134,7 @@ PLAN → IMPLEMENT → INTEGRATE → VALIDATE → CANDIDATE → RELEASE - **VER-TAURI-001** — Pour une app Tauri Rust du workspace, la version produit canonique est la version Cargo. - **VER-TAURI-002** — `tauri.conf.json` omet `version` lorsque Tauri peut hériter de la version `Cargo.toml`. -- **VER-TAURI-003** — La `version` de `package.json` décrit le package frontend local et n'est pas synchronisée à chaque `pre.N` ou `.fix.N`. +- **VER-TAURI-003** — La `version` de `package.json` décrit le package frontend local et n'est pas synchronisée à chaque prerelease ou `.fix.N`. - **VER-TAURI-004** — Tant que le frontend n'est pas publié comme package npm, sa version est mise à jour uniquement aux jalons significatifs retenus par le projet, au minimum lorsque cela est nécessaire pour alpha, beta, RC ou stable. ## Corrections des deltas déjà livrés diff --git a/history/000-README.md b/history/000-README.md index 27fc6d1..5b360ae 100644 --- a/history/000-README.md +++ b/history/000-README.md @@ -1,5 +1,5 @@ - + # Historique transitoire validé @@ -10,13 +10,14 @@ Cette arborescence conserve l'historique durable des jalons transitoires effecti ```text history/ └── X.Y.Z/ - ├── 0-pre.N.md - ├── 0-pre.N.fix.M.md - ├── 1-alpha.N.md - ├── 2-beta.N.md - └── 3-rc.N.md + ├── alpha.N.md + ├── alpha.N.fix.M.md + ├── beta.N.md + ├── beta.N.fix.M.md + ├── rc.N.md + └── rc.N.fix.M.md ``` -Un fichier n'est créé qu'après validation du jalon qu'il décrit et devient ensuite immuable. +Un fichier n'est créé qu'après validation du jalon qu'il décrit et devient ensuite immuable. Les répertoires historiques antérieurs à `0.3.4` conservent volontairement leurs anciens labels `0-pre.N`, `1-alpha.N`, `2-beta.N` et `3-rc.N` ; ils ne sont ni renommés ni réécrits. Le fichier delta correspondant décrit la livraison candidate et les commandes attendues ; le fichier `history/` décrit le résultat validé. diff --git a/scripts/audit_project_workspace_rules.py b/scripts/audit_project_workspace_rules.py index e31e758..ff5bf22 100755 --- a/scripts/audit_project_workspace_rules.py +++ b/scripts/audit_project_workspace_rules.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # file: scripts/audit_project_workspace_rules.py -# version: 7 +# version: 8 """Audit mechanically verifiable games.sasedev workspace boundaries.""" @@ -12,7 +12,15 @@ import re import sys import tomllib -SEMVER = re.compile(r"^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-(?:0-pre|1-alpha|2-beta|3-rc)\.[1-9][0-9]*(?:\.fix\.[1-9][0-9]*)?)?$", re.ASCII) +CURRENT_SEMVER = re.compile( + r"^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)(?:-(?:alpha|beta|rc)\.[1-9][0-9]*(?:\.fix\.[1-9][0-9]*)?)?$", + re.ASCII, +) +LEGACY_MILESTONE_SEMVER = re.compile( + r"^(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)-(?:0-pre|1-alpha|2-beta|3-rc)\.[1-9][0-9]*(?:\.fix\.[1-9][0-9]*)?$", + re.ASCII, +) +LEGACY_HISTORY_BASE_VERSIONS = frozenset({"0.1.0", "0.2.0", "0.3.0", "0.3.1", "0.3.3"}) def is_generated_path(path: pathlib.Path, root: pathlib.Path) -> bool: @@ -32,7 +40,7 @@ def main() -> int: errors: list[str] = [] manifest = tomllib.loads((root / "Cargo.toml").read_text(encoding="utf-8")) workspace_version = manifest.get("workspace", {}).get("package", {}).get("version") - if not isinstance(workspace_version, str) or SEMVER.fullmatch(workspace_version) is None: + if not isinstance(workspace_version, str) or CURRENT_SEMVER.fullmatch(workspace_version) is None: errors.append("VERSION-001: workspace.package.version does not follow the canonical games.sasedev SemVer scheme") members = manifest.get("workspace", {}).get("members", []) for member in members: @@ -47,7 +55,7 @@ def main() -> int: if version.get("workspace") is not True: errors.append(f"GAME-WS-004: {relative}: table version must use workspace = true") elif isinstance(version, str): - if SEMVER.fullmatch(version) is None: + if CURRENT_SEMVER.fullmatch(version) is None: errors.append(f"GAME-WS-005: {relative}: explicit crate version does not follow the canonical games.sasedev SemVer scheme") else: errors.append(f"GAME-WS-004: {relative}: crate must inherit or explicitly own a version") @@ -84,7 +92,9 @@ def main() -> int: errors.append(f"DOC-010: invalid history base version directory: {history_path.relative_to(root).as_posix()}") label = filename[:-3] candidate = f"{base_version}-{label}" - if SEMVER.fullmatch(candidate) is None: + is_current = CURRENT_SEMVER.fullmatch(candidate) is not None + is_legacy = base_version in LEGACY_HISTORY_BASE_VERSIONS and LEGACY_MILESTONE_SEMVER.fullmatch(candidate) is not None + if not is_current and not is_legacy: errors.append(f"DOC-010: invalid history milestone filename: {history_path.relative_to(root).as_posix()}") docs_root = root / "docs"