Files
games/deltas/0.3.5/alpha.3.md
2026-09-21 22:55:21 +02:00

7.3 KiB

Delta 0.3.5-alpha.3

Base requise

0.3.5-alpha.2.fix.1, validée par l'utilisateur le 2026-09-21 avec fmt, audits, check workspace, Clippy strict et les six tests de game-realtime-webtransport-lib entièrement verts.

La validation réellement fournie est conservée dans history/0.3.5/alpha.2.fix.1.md.

Objectif

Fermer la première adaptation fiable WebTransport vers game-realtime-transport-lib sans introduire encore la robustesse/lifecycle avancés, le navigateur/WASM, les datagrams ou le smoke public.

La version passe à :

0.3.5-alpha.3

Stream primaire

Une WebTransportSession peut désormais être consommée de deux façons :

client -> open_primary_connection()
server -> accept_primary_connection()

Chaque chemin sélectionne exactement un stream bidirectionnel fiable et retourne WebTransportConnection.

Le backend web-transport-quinn écrit lui-même l'en-tête WebTransport nécessaire pendant open_bi(). Le serveur peut donc accepter le stream avant toute frame applicative. Aucun préambule games.sasedev supplémentaire n'est ajouté : après l'en-tête protocolaire géré par la dépendance, le premier octet applicatif appartient directement au framing prévu.

Framing fiable privé

Le framing du stream primaire est :

u32 big-endian payload length
payload bytes

Il reste privé à game-realtime-webtransport-lib et n'est pas un wire codec gameplay.

La borne POC actuelle est de 1 MiB par message. Elle est vérifiée :

  • avant écriture côté sender ;
  • immédiatement après décodage des quatre octets de longueur et avant toute allocation côté receiver.

Une longueur hors limite produit TransportErrorKind::MessageTooLarge.

La limite n'est pas encore exposée comme configuration produit. alpha.4 possède cette décision avec les autres limites et deadlines.

Contrat commun

WebTransportConnection implémente RealtimeConnection et produit :

WebTransportSender
WebTransportReceiver

Les deux moitiés conservent chacune une référence à la session WebTransport. Le split() ne ferme donc pas accidentellement la session au moment où l'objet connexion est consommé.

WebTransportSender::send(...) écrit le header puis le payload sur le stream fiable et respecte la backpressure naturelle de QUIC pendant les écritures asynchrones.

WebTransportReceiver::receive(...) reconstruit exactement un TransportMessage, y compris les payloads vides et binaires non UTF-8.

RealtimeSender::close() termine proprement la direction locale du stream primaire. Lorsque le pair a consommé les messages précédents puis atteint le FIN, RealtimeReceiver::receive() retourne TransportReceive::Closed.

La fermeture complète de session, reset, abort, cancellation, deadlines et mapping fin des erreurs restent hors de cette tranche.

API et documentation

src/lib.rs réexporte les nouveaux types publics conformément aux règles du workspace.

Le README local est réconcilié avec le stream primaire et ses frontières. Un USAGE.md durable est ajouté car l'ordre session -> stream primaire -> RealtimeConnection et la contrainte d'accept serveur nécessitent désormais un guide d'utilisation distinct du delta.

Le plan 005 enregistre les décisions réellement matérialisées sans modifier le forecast de alpha.4+.

ROADMAP.md et CHANGELOG.md restent inchangés : cette alpha ne modifie ni la mission macro de 0.3.5 ni une livraison stable.

Tests

Le test unitaire du backend ajoute la preuve que :

  • la longueur est encodée en u32 big-endian ;
  • la borne de frame refuse une taille supérieure à 1 MiB avec MessageTooLarge.

Le nouveau test d'intégration tests/realtime_connection.rs prouve en loopback :

  • ouverture du stream primaire côté client ;
  • ouverture cliente puis accept du stream primaire côté serveur avant la première frame applicative ;
  • adaptation RealtimeConnection ;
  • payload vide ;
  • payload binaire non UTF-8 ;
  • ordre de plusieurs messages ;
  • echo bidirectionnel ;
  • FIN client observé comme TransportReceive::Closed côté serveur ;
  • FIN serveur observé comme TransportReceive::Closed côté client.

Les sessions restent vivantes pendant toute la preuve afin que le test ne confonde pas FIN du stream logique et drop de session.

Fichiers modifiés

Cargo.toml
README.md
crates/common/game-realtime-webtransport-lib/README.md
crates/common/game-realtime-webtransport-lib/src/lib.rs
crates/common/game-realtime-webtransport-lib/src/webtransport.rs
crates/common/game-realtime-webtransport-lib/unit_tests/webtransport.rs
docs/plans/005-V0_3_5_WEBTRANSPORT_QUIC_POC_PLAN.md

Nouveaux fichiers :

crates/common/game-realtime-webtransport-lib/USAGE.md
crates/common/game-realtime-webtransport-lib/tests/realtime_connection.rs
history/0.3.5/alpha.2.fix.1.md
deltas/0.3.5/alpha.3.md

Aucune dépendance Cargo n'est ajoutée ou modifiée dans cette tranche.

Validation exécutée dans l'environnement de génération

L'environnement de génération ne possède pas de toolchain Rust. Aucun cargo fmt, cargo check, Clippy ou test n'est donc attribué à cette livraison.

Les audits statiques disponibles ont été exécutés sur le candidat final :

General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
games.sasedev workspace audit: clean
Markdown table audit: clean (5 table(s), 273 file(s))
Distribution layout audit: clean (50 required path(s), 8 forbidden path(s) absent)

Le compteur de fichiers Markdown correspond à la reconstruction de travail issue de l'archive taggée et des deltas fournis. Il n'est pas utilisé comme invariant contre le checkout utilisateur, qui contient davantage de fichiers suivis localement.

Validation utilisateur demandée

Cette tranche modifie le backend Rust et ajoute un test d'intégration. La gate ciblée est :

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 tree -i game-realtime-webtransport-lib --workspace --edges normal

Le contrat commun est retesté parce que alpha.3 en devient un nouvel implémenteur, même si sa crate n'est pas modifiée.

Le cargo tree inverse vérifie qu'aucune crate moteur ou gameplay n'a acquis de dépendance vers le backend concret. Les arbres complets web-transport-quinn de alpha.2 ne sont pas répétés puisque le graphe de dépendances n'a pas changé.

Aucun smoke executable n'est encore attendu : le smoke natif public reste alpha.5, après la tranche de robustesse alpha.4.

Suite après validation

Si la gate est propre, ouvrir 0.3.5-alpha.4 pour :

  • limites configurables si justifiées ;
  • deadlines ;
  • backpressure/erreurs observables ;
  • close/reset/abort ;
  • cancellation/drop ;
  • cas négatifs de framing ;
  • mapping d'erreurs détaillé ;
  • tests de robustesse ciblés.

Un défaut fermé de cette tranche produit d'abord 0.3.5-alpha.3.fix.N au lieu d'ouvrir alpha.4.