Files
games/deltas/0.3.5/alpha.7.md
2026-09-22 06:36:54 +02:00

7.9 KiB

Delta 0.3.5-alpha.7

Base requise

0.3.5-alpha.6, validée par l'utilisateur le 2026-09-22 avec fmt, audits, cargo check, Clippy strict, les sept tests du contrat realtime commun, les vingt tests WebTransport, le smoke natif PASS, puis check/Clippy/build réels de game-realtime-webtransport-lib en wasm32-unknown-unknown.

Le graphe WASM confirmé ne tire ni web-transport-quinn, ni rcgen, ni Tokio. La preuve est enregistrée dans history/0.3.5/alpha.6.md.

Objectif

Fermer l'interop navigateur réelle du POC WebTransport sans introduire encore le fallback WebSocket :

  • appliquer réellement les deadlines WebTransportConfig côté browser/WASM ;
  • charger le client Rust/WASM dans un host Vite technique isolé ;
  • connecter un navigateur récent à un serveur Rust WebTransport local ;
  • transmettre explicitement le hash SHA-256 du certificat court P-256 ;
  • effectuer un round-trip binaire bidirectionnel via le stream primaire ;
  • fermer proprement les deux directions ;
  • produire un verdict PASS reproductible côté navigateur et côté serveur.

Version

La version workspace passe à :

0.3.5-alpha.7

Deadlines navigateur

Le target wasm32 de game-realtime-webtransport-lib ajoute uniquement :

gloo-timers 0.4.0
futures-util 0.3.34 avec feature std

Les dépendances restent target-specific et ne changent pas le backend natif.

Les opérations navigateur suivantes sont maintenant bornées :

connect_timeout
primary_stream_timeout
send_timeout

La politique reste identique au natif :

  • connect expiré -> TransportErrorKind::Timeout ;
  • ouverture du stream primaire expirée -> Timeout ;
  • send expiré -> Timeout puis reset terminal du stream ;
  • receive() idle reste sans timeout implicite ;
  • cancellation de receive() reste reprenable grâce au parseur incrémental.

Le timer browser prend des millisecondes u32. Une deadline qui devient zéro après conversion ou dépasse cette plage est rejetée comme InvalidConfiguration avant établissement.

Smoke navigateur

Nouveau package technique :

crates/apps/game-realtime-webtransport-browser-smoke

Le même package possède :

  • un binary natif qui génère l'identité loopback P-256 en mémoire, bind un serveur WebTransport sur port éphémère, affiche endpoint + SHA-256 et attend exactement le round-trip navigateur ;
  • une lib cdylib/rlib dont l'export run_browser_smoke(...) compile en WASM et consomme réellement game-realtime-webtransport-lib.

Nouveau host direct :

Web/game-realtime-webtransport-browser-smoke

Il utilise Vite + TypeScript, génère les bindings avec wasm-bindgen hors du repository et sert la page sur :

http://127.0.0.1:1435/main.html

Le loopback HTTP est un secure context de navigateur. La page vérifie néanmoins window.isSecureContext et la présence de WebTransport avant d'exécuter le WASM.

Le transport cible toujours :

https://127.0.0.1:<port-ephemere>/browser-smoke

avec serverCertificateHashes SHA-256 ; aucune vérification TLS n'est désactivée.

Round-trip prouvé par le smoke

La séquence attendue est :

browser WASM
    -> connect WebTransport avec pin SHA-256
    -> open primary bidirectional stream
    -> send browser binary payload
native Rust peer
    -> receive exact payload
    -> send server binary payload
browser WASM
    -> receive exact payload
    -> FIN send direction
native Rust peer
    -> observe Closed
    -> FIN send direction
browser WASM
    -> observe Closed

Le navigateur doit afficher :

game-realtime-webtransport-browser-smoke: PASS

et le binary serveur doit ensuite terminer avec la même ligne.

Aucun fallback WebSocket n'existe dans cette preuve ; un échec WebTransport doit rester visible.

Audit de distribution

scripts/audit_distribution_layout.py possède désormais le host technique et son adapter Rust. Il vérifie notamment :

  • génération WASM hors repository ;
  • host Vite strictement loopback sur le port 1435 ;
  • contrôle secure-context/WebTransport côté page ;
  • appel réel à run_browser_smoke(...) ;
  • dépendance de l'adapter vers game-realtime-webtransport-lib ;
  • verdict PASS déterministe du peer natif.

Fichiers modifiés

Cargo.toml
README.md
crates/common/game-realtime-webtransport-lib/Cargo.toml
crates/common/game-realtime-webtransport-lib/README.md
crates/common/game-realtime-webtransport-lib/USAGE.md
crates/common/game-realtime-webtransport-lib/src/webtransport_wasm.rs
docs/plans/005-V0_3_5_WEBTRANSPORT_QUIC_POC_PLAN.md
scripts/audit_distribution_layout.py

Nouveaux fichiers :

crates/apps/game-realtime-webtransport-browser-smoke/Cargo.toml
crates/apps/game-realtime-webtransport-browser-smoke/src/browser.rs
crates/apps/game-realtime-webtransport-browser-smoke/src/lib.rs
crates/apps/game-realtime-webtransport-browser-smoke/src/main.rs
crates/apps/game-realtime-webtransport-browser-smoke/src/shared.rs
Web/game-realtime-webtransport-browser-smoke/package.json
Web/game-realtime-webtransport-browser-smoke/tsconfig.json
Web/game-realtime-webtransport-browser-smoke/vite.config.ts
Web/game-realtime-webtransport-browser-smoke/frontend/main.html
Web/game-realtime-webtransport-browser-smoke/frontend/ts/main.ts
deltas/0.3.5/alpha.7.md
history/0.3.5/alpha.6.md

Validation attendue

Gate Rust native de non-régression :

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-webtransport-lib --all-targets --all-features
cargo run -p game-realtime-webtransport-smoke

Gate WASM :

cargo check -p game-realtime-webtransport-lib --target wasm32-unknown-unknown
cargo clippy -p game-realtime-webtransport-lib --target wasm32-unknown-unknown --lib -- -D warnings
cargo build -p game-realtime-webtransport-lib --target wasm32-unknown-unknown

cargo check -p game-realtime-webtransport-browser-smoke
cargo clippy -p game-realtime-webtransport-browser-smoke --all-targets --all-features -- -D warnings
cargo build -p game-realtime-webtransport-browser-smoke --lib --target wasm32-unknown-unknown

Build du host Vite direct :

(cd Web/game-realtime-webtransport-browser-smoke && npm install && npm run build)

Smoke runtime réel, avec deux terminaux :

Terminal A :

cargo run -p game-realtime-webtransport-browser-smoke

Le launcher affiche une ligne OPEN=... contenant l'endpoint éphémère et le hash SHA-256.

Terminal B :

(cd Web/game-realtime-webtransport-browser-smoke && npm run dev)

Ouvrir dans un navigateur récent l'URL OPEN=... imprimée par le Terminal A. Si le navigateur demande l'autorisation d'accès loopback/local, l'accorder pour cette preuve locale.

Résultat attendu dans la page puis dans le Terminal A :

game-realtime-webtransport-browser-smoke: PASS

Vérifier enfin le graphe cible :

cargo tree -p game-realtime-webtransport-browser-smoke --target wasm32-unknown-unknown --edges normal
cargo tree -i game-realtime-webtransport-lib --workspace --edges normal
cargo tree -i gloo-timers --workspace --target wasm32-unknown-unknown --edges normal

Le backend navigateur doit rester indépendant de Quinn/rcgen/Tokio ; gloo-timers ne doit apparaître que sur la cible WASM.

Après validation

Créer history/0.3.5/alpha.7.md à partir des sorties réellement fournies, puis ouvrir 0.3.5-alpha.8 pour le fallback WebSocket au niveau composition avec branches WebTransport, fallback classifié et erreur non-fallback visible.