v0.2.7-pre.004
This commit is contained in:
240
deltas/0.2.7/pre.004.md
Normal file
240
deltas/0.2.7/pre.004.md
Normal file
@@ -0,0 +1,240 @@
|
||||
<!-- file: deltas/0.2.7/pre.004.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.2.7-pre.004` — runtime WebSocket physique + actor JSON-RPC
|
||||
|
||||
## 1. Base requise
|
||||
|
||||
```text
|
||||
0.2.7-pre.003 appliquée
|
||||
workspace.package.version = 0.2.7-pre.3
|
||||
```
|
||||
|
||||
Le checkpoint opérateur reçu avant cette tranche est vert : `cargo fmt --all`, audit Python, `cargo check --workspace`, `cargo clippy --workspace --all-targets`, tests Transport, tests Config et `cargo test --workspace`.
|
||||
|
||||
## 2. Signal technique
|
||||
|
||||
Cette prerelease non-fix modifie dépendances, runtime Rust et tests. Conformément au workflow KSP :
|
||||
|
||||
```text
|
||||
livraison = 0.2.7-pre.004
|
||||
workspace.package.version = 0.2.7-pre.4
|
||||
commit = v0.2.7-pre.004
|
||||
```
|
||||
|
||||
Aucun tag prerelease.
|
||||
|
||||
## 3. Dépendances WebSocket matérialisées
|
||||
|
||||
Le réaudit du 22 août 2026 confirme les versions retenues depuis `pre.001` :
|
||||
|
||||
```text
|
||||
tokio-tungstenite 0.30.0
|
||||
futures-util 0.3.34
|
||||
```
|
||||
|
||||
Le root déclare sans features consumer :
|
||||
|
||||
```toml
|
||||
tokio-tungstenite = { version = "^0.30", default-features = false }
|
||||
futures-util = { version = "^0.3", default-features = false }
|
||||
```
|
||||
|
||||
Transport active seulement :
|
||||
|
||||
```text
|
||||
tokio-tungstenite : connect + rustls-tls-webpki-roots
|
||||
futures-util : sink + std
|
||||
tokio : macros + rt + sync + time
|
||||
```
|
||||
|
||||
Le fixture serveur local ajoute `tokio/net` côté dev.
|
||||
|
||||
Aucune dépendance Config, Store, Program, Wallet ou `tracing` direct n'est introduite.
|
||||
|
||||
## 4. `WsSession` physique
|
||||
|
||||
Nouvelle surface publique :
|
||||
|
||||
```text
|
||||
WsSession::connect(WsEndpointSettings)
|
||||
WsSession::id()
|
||||
WsSession::state()
|
||||
WsSession::snapshot()
|
||||
```
|
||||
|
||||
Un appel de `connect` crée exactement une connexion physique. Deux appels avec le même endpoint créent deux sockets indépendants ; aucun singleton, pool ou scheduler automatique n'est ajouté.
|
||||
|
||||
Le caller ne reçoit jamais le socket brut.
|
||||
|
||||
## 5. Actor propriétaire du socket
|
||||
|
||||
Une tâche actor unique possède :
|
||||
|
||||
```text
|
||||
WebSocketStream
|
||||
compteur JSON-RPC request id
|
||||
map pending requests
|
||||
bounded command receiver
|
||||
publication WsSessionSnapshot
|
||||
```
|
||||
|
||||
Le handle communique avec l'actor par `tokio::sync::mpsc` borné selon `command_queue_capacity`.
|
||||
|
||||
Les snapshots sont publiés via `tokio::sync::watch` et conservent seulement les metadata sûres prévues en `pre.002`.
|
||||
|
||||
## 6. Handshake et `WebSocketConfig`
|
||||
|
||||
`WsSession::connect` attend le handshake sous `command_timeout` et configure explicitement :
|
||||
|
||||
```text
|
||||
write_buffer_size = 0
|
||||
max_write_buffer_size = WsSessionSettings.max_write_buffer_size_bytes
|
||||
max_message_size = WsSessionSettings.max_message_size_bytes
|
||||
max_frame_size = WsSessionSettings.max_frame_size_bytes
|
||||
```
|
||||
|
||||
Le `write_buffer_size = 0` évite de rendre la validité de la configuration KSP dépendante du buffer par défaut interne de Tungstenite et garantit que le plafond configuré reste strictement supérieur au target buffer.
|
||||
|
||||
Les tests oversized et les recalibrages éventuels restent le gate `pre.005`.
|
||||
|
||||
## 7. Pending JSON-RPC
|
||||
|
||||
La primitive interne actor :
|
||||
|
||||
```text
|
||||
execute_json_rpc(method, params)
|
||||
```
|
||||
|
||||
reste **`pub(crate)`**. Elle n'est volontairement pas exposée comme API raw provider-extension publique.
|
||||
|
||||
Comportement :
|
||||
|
||||
- ID numérique KSP monotone par session ;
|
||||
- sérialisation via `JsonRpcRequest` existant ;
|
||||
- map `BTreeMap` bornée par `max_pending_requests` ;
|
||||
- deadline par request issue de `command_timeout` ;
|
||||
- dispatch des réponses par `id`, y compris si elles arrivent hors ordre ;
|
||||
- erreurs JSON-RPC applicatives renvoyées au caller concerné sans teardown de la connexion ;
|
||||
- ID réponse inconnu/stale ignoré avec diagnostic sûr ;
|
||||
- JSON structurellement invalide classé erreur protocole session.
|
||||
|
||||
Cette primitive sera consommée par le moteur de subscriptions à partir de `pre.006`.
|
||||
|
||||
## 8. Lifecycle limité à la tranche
|
||||
|
||||
`pre.004` matérialise :
|
||||
|
||||
```text
|
||||
Connecting -> Active
|
||||
connection/read/write failure -> Failed
|
||||
last handle dropped -> cleanup best-effort -> Closed
|
||||
```
|
||||
|
||||
Le reconnect/resubscribe reste `pre.007`.
|
||||
|
||||
Le shutdown async public, les budgets de Close et les fixtures peer hostile restent `pre.005`.
|
||||
|
||||
Ping reçu est répondu par Pong afin de conserver l'interopérabilité du socket. Aucun heartbeat applicatif périodique n'est ajouté.
|
||||
|
||||
## 9. Erreurs
|
||||
|
||||
Nouveaux codes publics :
|
||||
|
||||
```text
|
||||
ws_backpressure_overflow
|
||||
ws_connection_failed
|
||||
ws_protocol_error
|
||||
ws_session_closed
|
||||
```
|
||||
|
||||
Les erreurs de connexion WebSocket ne conservent volontairement pas la source Tungstenite brute : celle-ci pourrait contenir une request/URI ou d'autres détails provider. Les erreurs KSP exposent uniquement `session_id`, endpoint logique, provider et cluster.
|
||||
|
||||
## 10. Logging / tracing
|
||||
|
||||
Toutes les émissions passent exclusivement par `ksp-logging-lib` et réutilisent :
|
||||
|
||||
```text
|
||||
crates/ksp-onchain-transport-lib/src/constants.rs
|
||||
TRACING_TARGET = "ksp-onchain-transport-lib"
|
||||
```
|
||||
|
||||
Répartition principale :
|
||||
|
||||
```text
|
||||
trace -> ouverture socket, send/dispatch JSON-RPC, Ping/Pong, notification prématurée ignorée
|
||||
debug -> actor start, handshake actif, réponse stale, timeout pending, remote close
|
||||
warn -> handshake/read/write failure, malformed wire, capacité pending épuisée
|
||||
```
|
||||
|
||||
Ne sont jamais loggés : URL complète, credentials, query token, payload JSON-RPC complet ou notification brute.
|
||||
|
||||
## 11. Serveur local déterministe
|
||||
|
||||
Nouveaux tests runtime sans Internet :
|
||||
|
||||
```text
|
||||
handshake local + round-trip JSON-RPC
|
||||
deux sessions physiques distinctes sur la même URL
|
||||
deux requests concurrentes + réponses inversées
|
||||
application error sans teardown de session
|
||||
connection error sans fuite URL/credential
|
||||
```
|
||||
|
||||
Le serveur utilise `tokio::net::TcpListener` + `tokio_tungstenite::accept_async`.
|
||||
|
||||
## 12. Canaris workspace/public API
|
||||
|
||||
Le canari workspace dependencies est synchronisé avec les nouvelles dépendances/features et continue de vérifier le firewall Transport.
|
||||
|
||||
Le canari public API vérifie la disponibilité de `WsSession` et les quatre nouveaux codes d'erreur.
|
||||
|
||||
## 13. Documentation synchronisée
|
||||
|
||||
Mis à jour :
|
||||
|
||||
```text
|
||||
crates/ksp-onchain-transport-lib/README.md
|
||||
crates/ksp-onchain-transport-lib/USAGE.md
|
||||
docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md
|
||||
docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
|
||||
```
|
||||
|
||||
`ROADMAP.md` et `CHANGELOG.md` restent inchangés conformément à la politique de série prerelease.
|
||||
|
||||
## 14. Validation de préparation
|
||||
|
||||
Exécuté dans le sandbox :
|
||||
|
||||
```text
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
General Rust rule audit: clean
|
||||
Rust export completeness audit: 0 candidate(s)
|
||||
KSP workspace Rust rule audit: clean
|
||||
|
||||
inspection absence tracing direct OK
|
||||
inspection TRACING_TARGET OK
|
||||
inspection dépendances workspace/member OK
|
||||
inspection Markdown tables OK
|
||||
```
|
||||
|
||||
Cargo n'est pas disponible dans le sandbox de génération ; aucun résultat Cargo local n'est revendiqué.
|
||||
|
||||
## 15. Gates opérateur avant commit
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-onchain-transport-lib
|
||||
cargo test --workspace
|
||||
```
|
||||
|
||||
Si le checkpoint est vert :
|
||||
|
||||
```text
|
||||
commit = v0.2.7-pre.004
|
||||
```
|
||||
|
||||
La tranche suivante est `0.2.7-pre.005` : adversarial limits frame/message/request, control frames, cancellation, close/shutdown explicite et peer hostile.
|
||||
Reference in New Issue
Block a user