v0.2.8-pre.004-fix.001
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 221
|
||||
# version: 222
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/ksp-app-config-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-wallet-lib"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.2.8-pre.4"
|
||||
version = "0.2.8-pre.4.fix.1"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -102,6 +102,47 @@
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"profile_id": "devnet_helius",
|
||||
"endpoints": [
|
||||
{
|
||||
"name": "devnet_public",
|
||||
"enabled": true,
|
||||
"provider": "solana-public",
|
||||
"cluster": "devnet",
|
||||
"url": "${KSP_PUBLIC_SOLANA_DEVNET_HTTP_URL:-https://api.devnet.solana.com}",
|
||||
"connect_timeout_ms": 5000,
|
||||
"request_timeout_ms": 15000,
|
||||
"max_idle_connections_per_host": 8,
|
||||
"roles": [
|
||||
{
|
||||
"role": "default",
|
||||
"enabled": true,
|
||||
"request_kinds": [
|
||||
"*"
|
||||
],
|
||||
"priority": 100,
|
||||
"limits": {
|
||||
"requests_per_second": 5,
|
||||
"burst_capacity": 10,
|
||||
"max_concurrent_requests": 8,
|
||||
"pause_after_rate_limit_ms": 1000
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"ws_endpoints": [
|
||||
{
|
||||
"name": "devnet_helius_ws",
|
||||
"enabled": true,
|
||||
"provider": "helius",
|
||||
"cluster": "devnet",
|
||||
"kind": "helius_laserstream",
|
||||
"url": "wss://devnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-replace-me}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-config-lib/USAGE.md -->
|
||||
<!-- version: 9 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Utilisation de ksp-config-lib
|
||||
|
||||
@@ -142,7 +142,7 @@ let _ = (http_settings, ws_settings);
|
||||
|
||||
`std.transport` V2 conserve `retry` et `profiles[].endpoints[]` pour HTTP, ajoute `ws_defaults` et `profiles[].ws_endpoints[]`, puis accepte les protocoles WebSocket `kind = "solana_standard"` et `kind = "helius_laserstream"`. Ce second discriminateur appartient exclusivement au namespace WebSocket et mappe vers `WsProtocolKind::HeliusLaserStream`; il ne préfigure aucun contrat LaserStream gRPC. Un `ws_endpoints[].session` optionnel surcharge seulement les paramètres génériques de `WsSessionSettings`.
|
||||
|
||||
Pour Helius LaserStream WebSocket, l'exemple versionné compose l'URL provider avec `${KSP_SECRET_HELIUS_API_KEY:-replace-me}`. Config reste l'unique propriétaire de cette variable : il résout la clé dans l'URL effective, transmet au Transport un `WsEndpointUrl` utilisable au runtime et redige la valeur dans la projection sûre et les représentations `Debug`. Transport ne lit jamais directement l'environnement.
|
||||
Pour Helius LaserStream WebSocket, l'exemple versionné couvre explicitement les deux réseaux supportés par ce contrat : mainnet via `wss://mainnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-replace-me}` et devnet via `wss://devnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-replace-me}`. Les deux réseaux vivent dans des profils Config distincts afin de ne pas mélanger des clusters dans un même profil logique. Config reste l'unique propriétaire de `KSP_SECRET_HELIUS_API_KEY` : il résout la clé dans l'URL effective et transmet au Transport un `WsEndpointUrl` utilisable au runtime. Dans `safe_value`, Config conserve les segments littéraux non sensibles d'une chaîne composée et remplace uniquement chaque segment secret par `********` ; les projections deviennent donc respectivement `wss://mainnet.helius-rpc.com/?api-key=********` et `wss://devnet.helius-rpc.com/?api-key=********`. Les représentations `Debug` restent sûres et n'exposent jamais la clé réelle. Transport ne lit jamais directement l'environnement.
|
||||
|
||||
Le même schema enregistré conserve la lecture stricte du V1 historique : dans ce cas `http_settings()` reste disponible et `ws_settings()` retourne `None`. Aucun `WsTransportSettings` vide n'est inventé pour simuler l'absence de WebSocket.
|
||||
|
||||
|
||||
@@ -81,6 +81,47 @@
|
||||
"url": "wss://mainnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-fixture-helius-key}"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"profile_id": "helius_devnet",
|
||||
"endpoints": [
|
||||
{
|
||||
"name": "fixture_devnet_http",
|
||||
"enabled": true,
|
||||
"provider": "solana-public",
|
||||
"cluster": "devnet",
|
||||
"url": "https://api.devnet.solana.com",
|
||||
"connect_timeout_ms": 750,
|
||||
"request_timeout_ms": 2500,
|
||||
"max_idle_connections_per_host": 3,
|
||||
"roles": [
|
||||
{
|
||||
"role": "default",
|
||||
"enabled": true,
|
||||
"request_kinds": [
|
||||
"*"
|
||||
],
|
||||
"priority": 7,
|
||||
"limits": {
|
||||
"requests_per_second": 9,
|
||||
"burst_capacity": 12,
|
||||
"max_concurrent_requests": 4,
|
||||
"pause_after_rate_limit_ms": 650
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"ws_endpoints": [
|
||||
{
|
||||
"name": "fixture_helius_devnet_ws",
|
||||
"enabled": true,
|
||||
"provider": "helius",
|
||||
"cluster": "devnet",
|
||||
"kind": "helius_laserstream",
|
||||
"url": "wss://devnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-fixture-helius-key}"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -267,7 +267,7 @@ fn secret_websocket_url_is_runtime_available_but_safe_projection_is_redacted() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn helius_laserstream_secret_api_key_maps_to_provider_protocol_and_safe_redaction() {
|
||||
fn helius_laserstream_mainnet_and_devnet_api_key_map_to_protocol_and_safe_redaction() {
|
||||
let engine = fixture_engine();
|
||||
let engine = match engine {
|
||||
std::result::Result::Ok(value) => value,
|
||||
@@ -277,33 +277,63 @@ fn helius_laserstream_secret_api_key_maps_to_provider_protocol_and_safe_redactio
|
||||
let mut process = std::collections::BTreeMap::<String, String>::new();
|
||||
process.insert("KSP_SECRET_HELIUS_API_KEY".to_owned(), canary.to_owned());
|
||||
let environment = crate::ConfigEnvironment::from_maps(process, std::collections::BTreeMap::new());
|
||||
let resolved = engine.load_resolved_transport_config(std::option::Option::None, &environment);
|
||||
assert!(resolved.is_ok(), "Helius LaserStream WebSocket endpoint should map without exposing its API key: {resolved:?}");
|
||||
let resolved = match resolved {
|
||||
let mainnet = engine.load_resolved_transport_config(std::option::Option::None, &environment);
|
||||
assert!(mainnet.is_ok(), "Helius mainnet WebSocket endpoint should map without exposing its API key: {mainnet:?}");
|
||||
let mainnet = match mainnet {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let ws = resolved.ws_settings();
|
||||
assert!(ws.is_some(), "V2 fixture should expose WebSocket settings");
|
||||
if let std::option::Option::Some(ws) = ws {
|
||||
let mainnet_ws = mainnet.ws_settings();
|
||||
assert!(mainnet_ws.is_some(), "V2 fixture should expose mainnet WebSocket settings");
|
||||
if let std::option::Option::Some(ws) = mainnet_ws {
|
||||
assert_eq!(ws.endpoints().len(), 2);
|
||||
let endpoint = &ws.endpoints()[1];
|
||||
assert_eq!(endpoint.provider().as_str(), "helius");
|
||||
assert_eq!(endpoint.cluster().as_str(), "mainnet-beta");
|
||||
assert_eq!(endpoint.protocol(), ksp_onchain_transport_lib::WsProtocolKind::HeliusLaserStream);
|
||||
assert_eq!(endpoint.url().as_str(), "wss://mainnet.helius-rpc.com/?api-key=helius-api-key-canary");
|
||||
}
|
||||
let safe_url = resolved.effective().safe_value().pointer("/ws_endpoints/1/url").and_then(serde_json::Value::as_str);
|
||||
assert_eq!(safe_url, std::option::Option::Some(crate::REDACTED_CONFIG_VALUE));
|
||||
let provenance = resolved.effective().provenance_at("/ws_endpoints/1/url");
|
||||
assert!(provenance.is_some(), "Helius endpoint URL should retain secret environment provenance");
|
||||
if let std::option::Option::Some(provenance) = provenance {
|
||||
let mainnet_safe_url = mainnet.effective().safe_value().pointer("/ws_endpoints/1/url").and_then(serde_json::Value::as_str);
|
||||
assert_eq!(mainnet_safe_url, std::option::Option::Some("wss://mainnet.helius-rpc.com/?api-key=********"));
|
||||
let mainnet_provenance = mainnet.effective().provenance_at("/ws_endpoints/1/url");
|
||||
assert!(mainnet_provenance.is_some(), "Helius mainnet endpoint URL should retain secret environment provenance");
|
||||
if let std::option::Option::Some(provenance) = mainnet_provenance {
|
||||
assert_eq!(provenance.len(), 1);
|
||||
assert_eq!(provenance[0].environment_source(), std::option::Option::Some(crate::ConfigEnvironmentSource::Process));
|
||||
assert_eq!(provenance[0].variable_name(), std::option::Option::Some("KSP_SECRET_HELIUS_API_KEY"));
|
||||
}
|
||||
let debug = format!("{resolved:?}");
|
||||
assert!(!debug.contains(canary));
|
||||
assert!(debug.contains(crate::REDACTED_CONFIG_VALUE));
|
||||
let devnet = engine.load_resolved_transport_config(std::option::Option::Some("helius_devnet"), &environment);
|
||||
assert!(devnet.is_ok(), "Helius devnet WebSocket endpoint should map without exposing its API key: {devnet:?}");
|
||||
let devnet = match devnet {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(_) => return,
|
||||
};
|
||||
let devnet_ws = devnet.ws_settings();
|
||||
assert!(devnet_ws.is_some(), "V2 fixture should expose devnet WebSocket settings");
|
||||
if let std::option::Option::Some(ws) = devnet_ws {
|
||||
assert_eq!(ws.endpoints().len(), 1);
|
||||
let endpoint = &ws.endpoints()[0];
|
||||
assert_eq!(endpoint.provider().as_str(), "helius");
|
||||
assert_eq!(endpoint.cluster().as_str(), "devnet");
|
||||
assert_eq!(endpoint.protocol(), ksp_onchain_transport_lib::WsProtocolKind::HeliusLaserStream);
|
||||
assert_eq!(endpoint.url().as_str(), "wss://devnet.helius-rpc.com/?api-key=helius-api-key-canary");
|
||||
let _connect_future = ksp_onchain_transport_lib::HeliusLaserStreamWsSession::connect(endpoint.clone());
|
||||
}
|
||||
let devnet_safe_url = devnet.effective().safe_value().pointer("/ws_endpoints/0/url").and_then(serde_json::Value::as_str);
|
||||
assert_eq!(devnet_safe_url, std::option::Option::Some("wss://devnet.helius-rpc.com/?api-key=********"));
|
||||
let devnet_provenance = devnet.effective().provenance_at("/ws_endpoints/0/url");
|
||||
assert!(devnet_provenance.is_some(), "Helius devnet endpoint URL should retain secret environment provenance");
|
||||
if let std::option::Option::Some(provenance) = devnet_provenance {
|
||||
assert_eq!(provenance.len(), 1);
|
||||
assert_eq!(provenance[0].environment_source(), std::option::Option::Some(crate::ConfigEnvironmentSource::Process));
|
||||
assert_eq!(provenance[0].variable_name(), std::option::Option::Some("KSP_SECRET_HELIUS_API_KEY"));
|
||||
}
|
||||
let mainnet_debug = format!("{mainnet:?}");
|
||||
let devnet_debug = format!("{devnet:?}");
|
||||
assert!(!mainnet_debug.contains(canary));
|
||||
assert!(!devnet_debug.contains(canary));
|
||||
assert!(mainnet_debug.contains(crate::REDACTED_CONFIG_VALUE));
|
||||
assert!(devnet_debug.contains(crate::REDACTED_CONFIG_VALUE));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
182
deltas/0.2.8/pre.004-fix.001.md
Normal file
182
deltas/0.2.8/pre.004-fix.001.md
Normal file
@@ -0,0 +1,182 @@
|
||||
<!-- file: deltas/0.2.8/pre.004-fix.001.md -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Delta `0.2.8-pre.004-fix.001` — redaction Helius Config + couverture Devnet
|
||||
|
||||
## 1. Objet
|
||||
|
||||
Ce fix corrige deux défauts circonscrits de `0.2.8-pre.004` :
|
||||
|
||||
```text
|
||||
1. faux négatif du nouveau canari de redaction `safe_value` Helius ;
|
||||
2. représentation déterministe incomplète : mainnet était matérialisé, Devnet ne l'était pas encore.
|
||||
```
|
||||
|
||||
Le résolveur Config, le mapping Config -> Transport et le moteur WebSocket restent inchangés.
|
||||
|
||||
Version workspace :
|
||||
|
||||
```text
|
||||
0.2.8-pre.4.fix.1
|
||||
```
|
||||
|
||||
Livraison / commit attendu :
|
||||
|
||||
```text
|
||||
0.2.8-pre.004-fix.001
|
||||
v0.2.8-pre.004-fix.001
|
||||
```
|
||||
|
||||
Aucun tag prerelease.
|
||||
|
||||
## 2. Preuve opérateur ayant déclenché le fix
|
||||
|
||||
Le checkpoint `pre.004` reçu le 2026-08-23 donne :
|
||||
|
||||
```text
|
||||
cargo fmt --all OK
|
||||
python3 scripts/audit_rust_workspace_rules.py clean
|
||||
cargo check --workspace OK
|
||||
cargo clippy --workspace --all-targets OK
|
||||
cargo test -p ksp-config-lib FAIL 109/110
|
||||
cargo test -p ksp-onchain-transport-lib OK
|
||||
cargo test --workspace FAIL sur le même test Config
|
||||
```
|
||||
|
||||
L'échec exact est :
|
||||
|
||||
```text
|
||||
observé = wss://mainnet.helius-rpc.com/?api-key=********
|
||||
attendu = ********
|
||||
```
|
||||
|
||||
Le test avait déjà prouvé avant cette assertion que le schema accepte `helius_laserstream`, que l'adapter produit `WsProtocolKind::HeliusLaserStream` et que l'URL runtime contient la clé Helius résolue.
|
||||
|
||||
## 3. Redaction Config confirmée
|
||||
|
||||
Le contrat historique Config est segmentaire pour une chaîne composée :
|
||||
|
||||
```text
|
||||
source composée safe_value
|
||||
https://rpc.example/?token=${SECRET} -> https://rpc.example/?token=********
|
||||
token=${SECRET} -> token=********
|
||||
```
|
||||
|
||||
La projection sûre conserve donc les littéraux non sensibles et masque uniquement le segment secret.
|
||||
|
||||
Pour Helius :
|
||||
|
||||
```text
|
||||
mainnet runtime = wss://mainnet.helius-rpc.com/?api-key=<clé réelle>
|
||||
mainnet safe_value = wss://mainnet.helius-rpc.com/?api-key=********
|
||||
|
||||
devnet runtime = wss://devnet.helius-rpc.com/?api-key=<clé réelle>
|
||||
devnet safe_value = wss://devnet.helius-rpc.com/?api-key=********
|
||||
```
|
||||
|
||||
La clé réelle doit rester absente de `safe_value` et de toutes les représentations `Debug`.
|
||||
|
||||
## 4. Couverture Helius Devnet ajoutée
|
||||
|
||||
La documentation Helius WebSocket actuelle expose un endpoint unifié par réseau :
|
||||
|
||||
```text
|
||||
mainnet wss://mainnet.helius-rpc.com/?api-key=<api-key>
|
||||
devnet wss://devnet.helius-rpc.com/?api-key=<api-key>
|
||||
```
|
||||
|
||||
`pre.004` avait documenté les deux réseaux dans le plan mais n'avait matérialisé que mainnet dans l'exemple et la fixture Config. Le fix complète ce manque.
|
||||
|
||||
Décision de structure :
|
||||
|
||||
```text
|
||||
mainnet et devnet vivent dans des profils Config distincts ;
|
||||
un même profil logique ne mélange pas les deux clusters ;
|
||||
la même variable KSP_SECRET_HELIUS_API_KEY peut alimenter les deux URLs ;
|
||||
config/std.transport.json reste standard-only.
|
||||
```
|
||||
|
||||
L'exemple versionné ajoute un profil `devnet_helius`. La fixture Config ajoute un profil `helius_devnet` et le test charge explicitement ce profil en plus du profil mainnet par défaut.
|
||||
|
||||
## 5. Correction du test
|
||||
|
||||
Le canari devient :
|
||||
|
||||
```text
|
||||
helius_laserstream_mainnet_and_devnet_api_key_map_to_protocol_and_safe_redaction
|
||||
```
|
||||
|
||||
Il vérifie pour **mainnet et devnet** :
|
||||
|
||||
```text
|
||||
provider = helius
|
||||
cluster exact
|
||||
protocol = WsProtocolKind::HeliusLaserStream
|
||||
URL runtime exacte avec la clé résolue
|
||||
safe_value exact avec segment ********
|
||||
provenance = KSP_SECRET_HELIUS_API_KEY / Process
|
||||
Debug sans la clé réelle
|
||||
composition avec HeliusLaserStreamWsSession au moins sur le profil Devnet dédié
|
||||
```
|
||||
|
||||
## 6. Invariants non modifiés
|
||||
|
||||
Aucune modification n'est apportée à :
|
||||
|
||||
```text
|
||||
ConfigEnvironment / moteur de résolution
|
||||
sensitivity / provenance semantics
|
||||
JSON Schema Transport V2
|
||||
mapping helius_laserstream -> HeliusLaserStream
|
||||
WsEndpointUrl
|
||||
WsSession / façades / actor
|
||||
config/std.transport.json canonique
|
||||
transactionSubscribe
|
||||
heartbeat
|
||||
new dependency
|
||||
```
|
||||
|
||||
`.env.example` conserve une seule variable `KSP_SECRET_HELIUS_API_KEY`, suffisante pour les deux endpoints Helius.
|
||||
|
||||
## 7. Fichiers de la livraison
|
||||
|
||||
Nouveau :
|
||||
|
||||
```text
|
||||
deltas/0.2.8/pre.004-fix.001.md
|
||||
```
|
||||
|
||||
Modifiés :
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
config/examples/std.transport.example.json
|
||||
crates/ksp-config-lib/unit_tests/fixtures/std.transport.json
|
||||
crates/ksp-config-lib/unit_tests/transport.rs
|
||||
crates/ksp-config-lib/USAGE.md
|
||||
docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md
|
||||
docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md
|
||||
```
|
||||
|
||||
Inchangés volontairement :
|
||||
|
||||
```text
|
||||
config/std.transport.json
|
||||
config/schemas/std.transport.schema.json
|
||||
.env.example
|
||||
Transport WebSocket runtime
|
||||
```
|
||||
|
||||
## 8. Validation à rejouer
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-config-lib
|
||||
cargo test -p ksp-onchain-transport-lib
|
||||
cargo test --workspace
|
||||
```
|
||||
|
||||
`pre.004` + `fix.001` restent non fermés jusqu'à réception de ce checkpoint intégralement vert.
|
||||
@@ -1,9 +1,9 @@
|
||||
<!-- file: docs/plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md -->
|
||||
<!-- version: 9 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Plan `0.2.8` — Helius LaserStream WebSocket
|
||||
|
||||
> **Statut : `0.2.8-pre.003` est validé ; `0.2.8-pre.004` est préparé.** La façade `HeliusLaserStreamWsSession` possède désormais sa surface standard 6/6 validée. `pre.004` étend uniquement Config V2 au discriminateur WebSocket `helius_laserstream`, ajoute la fixture/exemple Helius et verrouille la résolution/redaction de `KSP_SECRET_HELIUS_API_KEY`, sans ouvrir `transactionSubscribe`.
|
||||
> **Statut : `0.2.8-pre.003` est validé ; le checkpoint `0.2.8-pre.004` a révélé un faux négatif de test, puis la revue du fix a identifié l'omission d'une représentation Devnet Helius déterministe. `pre.004-fix.001` corrige les deux points et reste préparé.** Le runtime Config/Transport est inchangé : pour une chaîne composée, `safe_value` conserve les segments littéraux non sensibles et remplace uniquement le segment secret par `********`. Le fix couvre désormais mainnet et devnet sans ouvrir `transactionSubscribe`.
|
||||
|
||||
## 1. Objet, base et état courant
|
||||
|
||||
@@ -27,10 +27,11 @@ pre.001-fix.002 forecast compact + namespace LaserStream WS/gRPC
|
||||
pre.002 socle protocolaire validé
|
||||
pre.002-fix.001 correction Clippy + normalisation structure documentaire validées
|
||||
pre.003 six familles standard Helius validées
|
||||
pre.004 Config V2 Helius + secret/redaction préparés
|
||||
pre.004 Config V2 Helius implémenté ; checkpoint bloqué par un faux négatif de test
|
||||
pre.004-fix.001 correction safe_value + couverture Devnet Helius préparées
|
||||
|
||||
workspace.package.version courant = 0.2.8-pre.4
|
||||
commit attendu = v0.2.8-pre.004
|
||||
workspace.package.version courant = 0.2.8-pre.4.fix.1
|
||||
commit attendu = v0.2.8-pre.004-fix.001
|
||||
aucun tag prerelease
|
||||
```
|
||||
|
||||
@@ -50,8 +51,10 @@ pre.002 DONE — socle protocolaire : WsProtocolKind::HeliusLaserStream + faça
|
||||
fix.001 DONE — correction Clippy `implicit_return` + audit/normalisation structure docs
|
||||
pre.003 DONE — surface Helius standard supportée : account/logs/program/root/signature/slot
|
||||
+ absence typée de block/slotsUpdates/vote sur Helius + non-régression standard 9/9
|
||||
pre.004 PREPARED — Config V2 helius_laserstream + schema/fixtures + mapping Config -> Transport
|
||||
+ stratégie de secret Helius et redaction URL
|
||||
pre.004 CHECKPOINT — Config V2 helius_laserstream + schema/fixtures + mapping Config -> Transport
|
||||
+ stratégie de secret Helius et redaction URL ; runtime/check/clippy/Transport verts
|
||||
fix.001 PREPARED — corrige le faux négatif `safe_value` + complète la représentation Devnet Helius
|
||||
+ mainnet/devnet dans des profils distincts, même secret, sans changement runtime
|
||||
pre.005 transactionSubscribe request typed + filters/options/tokenAccounts + transactionUnsubscribe
|
||||
+ bounds 50k + maxSupportedTransactionVersion conditionnel
|
||||
pre.006 transactionNotification + actor integration + reconnect/resubscribe/unsubscribe races
|
||||
@@ -709,17 +712,18 @@ profiles[].ws_endpoints[].kind:
|
||||
helius_laserstream -> WsProtocolKind::HeliusLaserStream
|
||||
```
|
||||
|
||||
La fixture Config contient un endpoint Helius typé et l'exemple versionné montre la composition de l'URL mainnet. `config/std.transport.json` reste standard-only pour ne pas imposer de provider/credential dans la configuration par défaut. Les paramètres de `transactionSubscribe` restent runtime et n'appartiennent pas au profil endpoint Config.
|
||||
La fixture Config contient un endpoint Helius mainnet typé ainsi qu'un profil Helius devnet distinct. L'exemple versionné matérialise lui aussi un profil mainnet et un profil devnet séparés ; aucun profil logique ne mélange les deux clusters. `config/std.transport.json` reste standard-only pour ne pas imposer de provider/credential dans la configuration par défaut. Les paramètres de `transactionSubscribe` restent runtime et n'appartiennent pas au profil endpoint Config.
|
||||
|
||||
### 7.13 Credentials
|
||||
|
||||
L'api-key reste uniquement dans l'URL résolue :
|
||||
|
||||
```text
|
||||
wss://mainnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-replace-me}
|
||||
mainnet = wss://mainnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-replace-me}
|
||||
devnet = wss://devnet.helius-rpc.com/?api-key=${KSP_SECRET_HELIUS_API_KEY:-replace-me}
|
||||
```
|
||||
|
||||
`KSP_SECRET_HELIUS_API_KEY` est inventorié dans `.env.example` sous forme commentée/placeholder. Config résout la clé au sein de l'URL effective, marque la valeur comme `Secret`, conserve l'URL réelle uniquement pour le runtime légitime et redige la projection sûre ainsi que `Debug`. Transport ne lit jamais `std::env` et reçoit uniquement un `WsEndpointUrl`.
|
||||
`KSP_SECRET_HELIUS_API_KEY` est inventorié dans `.env.example` sous forme commentée/placeholder et est réutilisé pour les deux réseaux Helius. Config résout la clé au sein de chaque URL effective, marque le segment résolu comme `Secret` et conserve l'URL réelle uniquement pour le runtime légitime. Le contrat Config existant de redaction **segmentaire** s'applique aux chaînes composées : les littéraux sûrs sont conservés et le segment secret devient `********`, soit `wss://mainnet.helius-rpc.com/?api-key=********` ou `wss://devnet.helius-rpc.com/?api-key=********`. `Debug` n'expose jamais la clé réelle. Transport ne lit jamais `std::env` et reçoit uniquement un `WsEndpointUrl`.
|
||||
|
||||
## 8. Threat model provider
|
||||
|
||||
@@ -890,7 +894,7 @@ validation finale fermée
|
||||
prompt 0.2.9 prêt
|
||||
```
|
||||
|
||||
## 13. Checkpoint `pre.004`
|
||||
## 13. Checkpoint `pre.004` et `fix.001`
|
||||
|
||||
Le checkpoint `pre.003` est fermé par preuve opérateur :
|
||||
|
||||
@@ -910,8 +914,8 @@ Les preuves spécifiques `pre.003` sont acquises : fixture Helius 6/6, 38 tests
|
||||
```text
|
||||
WsProtocolKind Config mapping helius_laserstream -> HeliusLaserStream
|
||||
JSON Schema V2 kind accepte solana_standard + helius_laserstream
|
||||
fixture Config endpoint Helius avec interpolation d'api-key
|
||||
example Config endpoint Helius mainnet explicite
|
||||
fixture Config Helius mainnet + profil Helius devnet séparé, interpolation d'api-key
|
||||
example Config profils Helius mainnet/devnet explicites et séparés
|
||||
secret KSP_SECRET_HELIUS_API_KEY
|
||||
safe projection / Debug credential Helius redacted
|
||||
Config -> Transport endpoint typé HeliusLaserStream
|
||||
@@ -921,7 +925,21 @@ heartbeat toujours absent
|
||||
new dependency aucune
|
||||
```
|
||||
|
||||
Le checkpoint opérateur requis avant de déclarer `pre.004` `DONE` est :
|
||||
Le premier checkpoint opérateur `pre.004` reçu le 2026-08-23 donne :
|
||||
|
||||
```text
|
||||
cargo fmt --all OK
|
||||
python3 scripts/audit_rust_workspace_rules.py clean
|
||||
cargo check --workspace OK
|
||||
cargo clippy --workspace --all-targets OK
|
||||
cargo test -p ksp-config-lib FAIL 109/110
|
||||
cargo test -p ksp-onchain-transport-lib OK 314 unit + 38 public + 26 completeness + 4 doctests
|
||||
cargo test --workspace FAIL sur le même test Config
|
||||
```
|
||||
|
||||
L'unique échec opérateur compare `safe_value` à `********` alors que le résolveur produit correctement `wss://mainnet.helius-rpc.com/?api-key=********`. Les canaris historiques Config prouvent déjà ce contrat de redaction segmentaire pour les chaînes composées. La revue du fix a aussi identifié que `pre.004` ne matérialisait déterministiquement que mainnet alors que le contrat Helius WebSocket couvre mainnet et devnet. `pre.004-fix.001` corrige donc l'attente du test **et** ajoute un profil/fixture Devnet Helius séparé, sans modifier le résolveur, le schema, le mapping protocol ou le runtime Transport.
|
||||
|
||||
Le checkpoint à rejouer avant de déclarer `pre.004` + `fix.001` `DONE` est :
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<!-- file: docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md -->
|
||||
<!-- version: 9 -->
|
||||
<!-- version: 11 -->
|
||||
|
||||
# Validation `0.2.8` — Helius LaserStream WebSocket
|
||||
|
||||
> **Statut : `pre.003` validé ; `pre.004` préparé.** Les six wrappers standard Helius, leurs exact-wire fixtures, canaries publiques/release-completeness et compile-fail sont verts. La tranche courante ajoute uniquement le mapping Config V2 `helius_laserstream`, une fixture/exemple Helius et les preuves de résolution/redaction du secret provider.
|
||||
> **Statut : `pre.003` validé ; `pre.004` a atteint son checkpoint avec un faux négatif Config et la revue a ensuite relevé l'absence d'un cas Devnet Helius déterministe. `pre.004-fix.001` couvre les deux corrections.** `fmt`, audit, `check`, `clippy` et Transport sont verts. Le fix aligne le test Helius sur la redaction segmentaire existante et exige désormais mainnet + devnet dans des profils distincts.
|
||||
|
||||
## 1. Références
|
||||
|
||||
@@ -17,6 +17,8 @@ fix forecast/nomenclature deltas/0.2.8/pre.001-fix.002.md
|
||||
pre.002 deltas/0.2.8/pre.002.md
|
||||
pre.002 Clippy/docs fix deltas/0.2.8/pre.002-fix.001.md
|
||||
pre.003 deltas/0.2.8/pre.003.md
|
||||
pre.004 deltas/0.2.8/pre.004.md
|
||||
pre.004 redaction test fix deltas/0.2.8/pre.004-fix.001.md
|
||||
validation standard WS docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md
|
||||
HTTP compliance docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
|
||||
KSP-TRANSPORT-007 docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
|
||||
@@ -130,22 +132,22 @@ Verdict : **gate `0.2.8-pre.001` positif ; `pre.002` + `fix.001` et `pre.003` so
|
||||
|
||||
### 4.2 Invariants architecture
|
||||
|
||||
| Critère | Décision | Preuve cible | État |
|
||||
|-------------------------------------|------------------------------------------------------------------|---------------------------------|--------|
|
||||
| Critère | Décision | Preuve cible | État |
|
||||
|-------------------------------------|------------------------------------------------------------------|---------------------------------|--------------------|
|
||||
| actor physique | un seul `WsSession` actor partagé | source/runtime canary | pre.002 implémenté |
|
||||
| façade standard | `SolanaStandardWsSession` | public API canary | pre.002 implémenté |
|
||||
| façade Helius | `HeliusLaserStreamWsSession` | public API canary | pre.002 implémenté |
|
||||
| namespace LaserStream WS | `WsProtocolKind` + `ws_endpoints` possèdent `helius_laserstream` | API/Config/docs canary | pre.004 préparé |
|
||||
| LaserStream gRPC | backend/type/Config distincts, hors `0.2.8` | absence de réutilisation WS | décidé |
|
||||
| namespace LaserStream WS | `WsProtocolKind` + `ws_endpoints` possèdent `helius_laserstream` | API/Config/docs canary | pre.004 préparé |
|
||||
| LaserStream gRPC | backend/type/Config distincts, hors `0.2.8` | absence de réutilisation WS | décidé |
|
||||
| escape hatch Helius | aucun `inner()`/`into_inner()` public | compile-fail/source canary | pre.002 implémenté |
|
||||
| generic Helius `WsSession::connect` | ne doit pas permettre de contourner la façade | invalid protocol pre-I/O canary | pre.002 implémenté |
|
||||
| Helius unsupported | absent de la façade | compile-fail/API absence canary | pre.003 validé |
|
||||
| standard Helius commun | délégation vers le même wire/actor | exact fixture | pre.003 validé |
|
||||
| DTO duplication | seulement si wire/sémantique divergent | public/source audit | décidé |
|
||||
| Config direction | Config -> Transport uniquement | ownership tests | pre.004 préparé |
|
||||
| heartbeat | Helius-only, actor commun | deterministic timers | décidé |
|
||||
| secret | query URL derrière `WsEndpointUrl` | redaction canaries | pre.004 préparé |
|
||||
| new Rust dependency | aucune | manifest/tree audit | décidé |
|
||||
| Helius unsupported | absent de la façade | compile-fail/API absence canary | pre.003 validé |
|
||||
| standard Helius commun | délégation vers le même wire/actor | exact fixture | pre.003 validé |
|
||||
| DTO duplication | seulement si wire/sémantique divergent | public/source audit | décidé |
|
||||
| Config direction | Config -> Transport uniquement | ownership tests | pre.004 préparé |
|
||||
| heartbeat | Helius-only, actor commun | deterministic timers | décidé |
|
||||
| secret | query URL derrière `WsEndpointUrl` | redaction canaries | pre.004 préparé |
|
||||
| new Rust dependency | aucune | manifest/tree audit | décidé |
|
||||
|
||||
## 5. Contrat `transactionSubscribe` à valider
|
||||
|
||||
@@ -232,8 +234,8 @@ aucun payload brut dans logs/snapshots
|
||||
[x] KSP-TRANSPORT-007 inchangé — tests Transport/workspace verts
|
||||
[x] Config V1 HTTP-only backward readable — tests Config workspace verts
|
||||
[x] Config V2 solana_standard backward readable — tests Config workspace verts
|
||||
[ ] Config V2 helius_laserstream mappe vers WsProtocolKind::HeliusLaserStream — pre.004 test ajouté, pending
|
||||
[ ] schema V2 accepte helius_laserstream sans relâcher les autres contraintes — pre.004 fixture pending
|
||||
[x] Config V2 helius_laserstream mappe vers WsProtocolKind::HeliusLaserStream — test pre.004 atteint cette assertion avant l'échec safe_value
|
||||
[x] schema V2 accepte helius_laserstream sans relâcher les autres contraintes — fixture chargée par le test pre.004
|
||||
[x] no Transport -> Config/Wallet/Store/Program/tracing direct — audits/tests ownership verts
|
||||
```
|
||||
|
||||
@@ -241,8 +243,8 @@ aucun payload brut dans logs/snapshots
|
||||
|
||||
```text
|
||||
[x] api-key absente de Debug WsEndpointUrl — canaries héritées + pre.002 vert
|
||||
[ ] KSP_SECRET_HELIUS_API_KEY redacted dans safe_value Config — pre.004 test ajouté, pending
|
||||
[ ] KSP_SECRET_HELIUS_API_KEY absente de ResolvedTransportConfig Debug — pre.004 test ajouté, pending
|
||||
[ ] KSP_SECRET_HELIUS_API_KEY redacted dans safe_value Config — comportement correct observé, attente du test corrigée par fix.001, checkpoint à rejouer
|
||||
[ ] KSP_SECRET_HELIUS_API_KEY absente de ResolvedTransportConfig Debug — assertion située après le faux négatif, checkpoint fix.001 à rejouer
|
||||
[ ] api-key absente de Debug settings/session/subscription
|
||||
[ ] api-key absente des KspError safe contexts
|
||||
[ ] URL complète absente des snapshots
|
||||
@@ -293,16 +295,18 @@ La fixture Transport rapporte 314 tests unitaires verts, 38 tests public API ver
|
||||
Surface `pre.004` préparée :
|
||||
|
||||
```text
|
||||
[ ] schema `ws_endpoints[].kind` accepte `helius_laserstream`
|
||||
[ ] adapter Config mappe `helius_laserstream` vers `WsProtocolKind::HeliusLaserStream`
|
||||
[ ] fixture Config matérialise un endpoint Helius typé
|
||||
[ ] exemple Transport matérialise Helius mainnet sans credential réel
|
||||
[ ] `.env.example` inventorie `KSP_SECRET_HELIUS_API_KEY`
|
||||
[ ] interpolation du secret produit l'URL runtime Helius attendue
|
||||
[ ] safe_value redige l'URL contenant l'api-key
|
||||
[ ] Debug de `ResolvedTransportConfig` n'expose pas la clé
|
||||
[ ] Config produit un endpoint composable avec `HeliusLaserStreamWsSession`
|
||||
[ ] `config/std.transport.json` canonique reste standard-only
|
||||
[x] schema `ws_endpoints[].kind` accepte `helius_laserstream`
|
||||
[x] adapter Config mappe `helius_laserstream` vers `WsProtocolKind::HeliusLaserStream`
|
||||
[x] fixture Config matérialise un endpoint Helius mainnet typé
|
||||
[ ] fixture Config matérialise un profil Helius devnet distinct — ajouté par fix.001, checkpoint à rejouer
|
||||
[x] exemple Transport matérialise Helius mainnet sans credential réel
|
||||
[ ] exemple Transport matérialise Helius devnet dans un profil distinct — ajouté par fix.001, checkpoint à rejouer
|
||||
[x] `.env.example` inventorie `KSP_SECRET_HELIUS_API_KEY`
|
||||
[x] interpolation du secret produit l'URL runtime Helius attendue
|
||||
[ ] safe_value conserve les littéraux Helius mainnet/devnet et redige uniquement l'api-key (`...api-key=********`) — fix.001 à rejouer
|
||||
[ ] Debug de `ResolvedTransportConfig` n'expose pas la clé — assertion à rejouer après fix.001
|
||||
[x] Config produit un endpoint composable avec `HeliusLaserStreamWsSession`
|
||||
[x] `config/std.transport.json` canonique reste standard-only
|
||||
```
|
||||
|
||||
Aucun `transactionSubscribe`, heartbeat, changement du moteur WebSocket ou nouvelle dépendance n'est introduit dans cette tranche.
|
||||
@@ -333,7 +337,31 @@ Constats `pre.002-fix.001` :
|
||||
|
||||
Aucun split en fichiers supplémentaires n'est retenu : les plans historiques `0.2.5`–`0.2.7` sont de taille comparable ou supérieure, et le contenu du plan `015` reste entièrement centré sur une seule release. Le problème identifié était **l'ordre interne et la duplication de responsabilités**, pas la nécessité d'un nouveau type de document.
|
||||
|
||||
## 12. Gate opérateur `pre.004`
|
||||
|
||||
## 12. Gate opérateur `pre.004` / `fix.001`
|
||||
|
||||
Premier passage `pre.004` reçu le 2026-08-23 :
|
||||
|
||||
```text
|
||||
[x] cargo fmt --all
|
||||
[x] python3 scripts/audit_rust_workspace_rules.py = clean
|
||||
[x] cargo check --workspace
|
||||
[x] cargo clippy --workspace --all-targets
|
||||
[ ] cargo test -p ksp-config-lib — 109/110 ; faux négatif safe_value Helius
|
||||
[x] cargo test -p ksp-onchain-transport-lib — vert
|
||||
[ ] cargo test --workspace — échoue uniquement sur le même test Config
|
||||
```
|
||||
|
||||
Observation exacte :
|
||||
|
||||
```text
|
||||
observé = wss://mainnet.helius-rpc.com/?api-key=********
|
||||
attendu = ********
|
||||
```
|
||||
|
||||
L'observé est conforme au contrat historique du résolveur Config : dans une chaîne composée, les littéraux non sensibles restent visibles dans la projection sûre tandis que chaque placeholder secret est remplacé par `********`. Le fix ne modifie donc pas le runtime ; il corrige le canari pour attendre l'URL sûre segmentaire exacte. La revue du même checkpoint complète également la couverture Config avec un profil Helius Devnet distinct utilisant `wss://devnet.helius-rpc.com/?api-key=...`, afin que mainnet et devnet soient tous deux prouvés sans mélange de clusters.
|
||||
|
||||
À rejouer après `pre.004-fix.001` :
|
||||
|
||||
```text
|
||||
[ ] cargo fmt --all
|
||||
@@ -345,4 +373,4 @@ Aucun split en fichiers supplémentaires n'est retenu : les plans historiques `0
|
||||
[ ] cargo test --workspace
|
||||
```
|
||||
|
||||
Verdict courant : **`pre.003` DONE ; `pre.004` préparé, non déclaré `DONE` avant ce checkpoint.**
|
||||
Verdict courant : **`pre.003` DONE ; `pre.004` fonctionnellement implémenté mais non fermé ; `pre.004-fix.001` PREPARED.**
|
||||
|
||||
Reference in New Issue
Block a user