213 lines
6.8 KiB
Markdown
213 lines
6.8 KiB
Markdown
<!-- file: deltas/0.3.5/alpha.8.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta 0.3.5-alpha.8
|
|
|
|
## Base requise
|
|
|
|
`0.3.5-alpha.7.fix.2`, validée par l'utilisateur le 2026-09-22.
|
|
|
|
La gate finale confirme fmt, audits, `cargo check --workspace`, Clippy strict, build WASM de l'adapter browser, génération `wasm-bindgen`, build TypeScript/Vite et smoke WebTransport navigateur réel terminé par :
|
|
|
|
```text
|
|
game-realtime-webtransport-browser-smoke: PASS
|
|
```
|
|
|
|
La preuve complète est enregistrée dans `history/0.3.5/alpha.7.fix.2.md`.
|
|
|
|
## Objectif
|
|
|
|
Prouver le fallback WebSocket au niveau composition sans modifier le contrat transport-neutral ni masquer les erreurs sensibles :
|
|
|
|
- essayer WebTransport en premier ;
|
|
- conserver WebTransport lorsqu'il est disponible ;
|
|
- basculer vers WebSocket uniquement pour des erreurs explicitement classifiées ;
|
|
- forcer une branche fallback déterministe ;
|
|
- garder une erreur non-fallback visible ;
|
|
- ne créer ni manager générique, ni registry, ni couplage gameplay.
|
|
|
|
## Version
|
|
|
|
La version workspace passe à :
|
|
|
|
```text
|
|
0.3.5-alpha.8
|
|
```
|
|
|
|
## Launcher de composition
|
|
|
|
Nouveau package technique :
|
|
|
|
```text
|
|
crates/apps/game-realtime-transport-fallback-smoke
|
|
```
|
|
|
|
Il dépend directement des deux backends candidats et du contrat commun, mais d'aucun engine ni gameplay.
|
|
|
|
Le sélecteur reste privé au launcher :
|
|
|
|
```text
|
|
WebTransport attempt
|
|
-> success -> WebTransport
|
|
-> classified Timeout/Io -> WebSocket attempt
|
|
-> any other error -> visible error
|
|
```
|
|
|
|
Aucune API n'est ajoutée à `game-realtime-transport-lib`, `game-realtime-websocket-lib` ou `game-realtime-webtransport-lib`.
|
|
|
|
## Classification conservative
|
|
|
|
Le backend WebTransport natif mappe actuellement les erreurs amont d'établissement sous une catégorie `Connect` trop large pour distinguer de manière sûre une indisponibilité réseau d'un problème TLS/pinning.
|
|
|
|
Pour éviter un downgrade silencieux, `alpha.8` autorise le fallback uniquement pour :
|
|
|
|
```text
|
|
Timeout
|
|
Io
|
|
```
|
|
|
|
et refuse explicitement le fallback pour :
|
|
|
|
```text
|
|
InvalidConfiguration
|
|
Connect
|
|
Bind
|
|
Accept
|
|
MessageTooLarge
|
|
Backpressure
|
|
Closed
|
|
Protocol
|
|
Aborted
|
|
```
|
|
|
|
Cette politique est volontairement plus restrictive qu'un fallback générique sur toute erreur de connexion. Une évolution future pourra élargir la matrice uniquement si le backend expose une classification suffisamment précise pour préserver les erreurs de sécurité/protocole.
|
|
|
|
## Smoke runtime
|
|
|
|
Le launcher exécute trois scénarios séquentiels sous une deadline globale de 10 s.
|
|
|
|
### 1. WebTransport disponible
|
|
|
|
- serveur WebTransport loopback réel sur port éphémère ;
|
|
- identité P-256 en mémoire et pin SHA-256 exact ;
|
|
- sélection WebTransport-first ;
|
|
- fallback WebSocket volontairement inutilisable si appelé ;
|
|
- round-trip binaire dans les deux sens ;
|
|
- fermeture propre dans les deux sens.
|
|
|
|
### 2. Fallback WebSocket forcé
|
|
|
|
- erreur WebTransport `Timeout` injectée explicitement au point de composition ;
|
|
- listener WebSocket loopback réel sur port éphémère ;
|
|
- sélection de la branche fallback ;
|
|
- round-trip binaire dans les deux sens ;
|
|
- fermeture propre dans les deux sens.
|
|
|
|
L'injection ne simule pas le backend WebSocket : elle force uniquement la cause WebTransport classifiée afin que la branche de sélection soit déterministe et rapide. La connexion fallback et son échange restent réels.
|
|
|
|
### 3. Erreur non-fallback visible
|
|
|
|
- vraie `WebTransportClientConfig` avec `connect_timeout = 0` ;
|
|
- `game-realtime-webtransport-lib::connect()` retourne `InvalidConfiguration` avant I/O ;
|
|
- la branche WebSocket ne doit pas être utilisée ;
|
|
- l'erreur exacte `connect_timeout must be greater than zero` doit rester visible.
|
|
|
|
Le verdict global attendu est :
|
|
|
|
```text
|
|
game-realtime-transport-fallback-smoke: PASS
|
|
```
|
|
|
|
## Tests unitaires
|
|
|
|
Le binary contient également des tests ciblés qui vérifient :
|
|
|
|
- la matrice `TransportErrorKind` complète ;
|
|
- `Connect` explicitement non éligible ;
|
|
- succès WebTransport prioritaire ;
|
|
- `Timeout` déclenchant la valeur WebSocket ;
|
|
- `InvalidConfiguration` restant inchangée et visible.
|
|
|
|
## Audit de distribution
|
|
|
|
`scripts/audit_distribution_layout.py` ajoute les chemins du launcher et vérifie :
|
|
|
|
- dépendance directe aux deux backends ;
|
|
- aucune dépendance engine/gameplay ;
|
|
- classification limitée à `Timeout`/`Io` ;
|
|
- exclusion explicite de `Connect` ;
|
|
- verdict `PASS` déterministe.
|
|
|
|
## Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
README.md
|
|
docs/plans/005-V0_3_5_WEBTRANSPORT_QUIC_POC_PLAN.md
|
|
scripts/audit_distribution_layout.py
|
|
```
|
|
|
|
Nouveaux fichiers :
|
|
|
|
```text
|
|
crates/apps/game-realtime-transport-fallback-smoke/Cargo.toml
|
|
crates/apps/game-realtime-transport-fallback-smoke/src/main.rs
|
|
crates/apps/game-realtime-transport-fallback-smoke/unit_tests/fallback.rs
|
|
deltas/0.3.5/alpha.8.md
|
|
history/0.3.5/alpha.7.fix.2.md
|
|
```
|
|
|
|
## Validation attendue
|
|
|
|
```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
|
|
|
|
cargo test -p game-realtime-transport-lib --all-targets --all-features
|
|
cargo test -p game-realtime-websocket-lib --all-targets --all-features
|
|
cargo test -p game-realtime-webtransport-lib --all-targets --all-features
|
|
cargo test -p game-realtime-transport-fallback-smoke --all-targets --all-features
|
|
|
|
cargo run -p game-realtime-websocket-smoke
|
|
cargo run -p game-realtime-webtransport-smoke
|
|
cargo run -p game-realtime-transport-fallback-smoke
|
|
|
|
cargo tree -p game-realtime-transport-fallback-smoke --edges normal
|
|
cargo tree -i game-realtime-websocket-lib --workspace --edges normal
|
|
cargo tree -i game-realtime-webtransport-lib --workspace --edges normal
|
|
```
|
|
|
|
Le nouveau smoke doit terminer par :
|
|
|
|
```text
|
|
game-realtime-transport-fallback-smoke: PASS
|
|
```
|
|
|
|
Les graphes inverses peuvent contenir les launchers techniques, mais aucun engine ni crate gameplay ne doit dépendre des backends concrets.
|
|
|
|
## Contrôles statiques avant livraison
|
|
|
|
Le candidat a été vérifié côté générateur sans attribuer de résultat Cargo non exécuté :
|
|
|
|
```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), 286 file(s))
|
|
Distribution layout audit: clean (61 required path(s), 8 forbidden path(s) absent)
|
|
Cargo.toml parse: clean
|
|
```
|
|
|
|
La compilation, Clippy, les tests et les smokes restent à exécuter dans la gate utilisateur ci-dessus.
|
|
|
|
## Après validation
|
|
|
|
Créer `history/0.3.5/alpha.8.md` à partir des sorties réellement fournies, puis ouvrir `0.3.5-alpha.9` pour le POC datagram isolé si cette tranche reste justifiée par l'API/backend réellement disponibles.
|