Files
games/deltas/0.3.5/alpha.8.md
2026-09-22 07:35:17 +02:00

6.8 KiB

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 :

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 à :

0.3.5-alpha.8

Launcher de composition

Nouveau package technique :

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 :

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 :

Timeout
Io

et refuse explicitement le fallback pour :

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 :

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

Cargo.toml
README.md
docs/plans/005-V0_3_5_WEBTRANSPORT_QUIC_POC_PLAN.md
scripts/audit_distribution_layout.py

Nouveaux fichiers :

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

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 :

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é :

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.