v0.2.9-pre.012

This commit is contained in:
2026-08-24 20:48:30 +02:00
parent 21ed5f88da
commit 813a45385a
20 changed files with 2095 additions and 365 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V1.md -->
<!-- version: 14 -->
<!-- version: 15 -->
# `.kspwallet` V1 — spécification du format natif Wallet KSP
@@ -399,29 +399,29 @@ Les champs binaires sont les **octets décodés** du Base64url, jamais le texte
| Tag hex | Champ |
|--------:|----------------------------------------------------|
| `0001` | magic |
| `0002` | format_version |
| `0003` | owner_auth_public_key |
| `0010` | view enabled |
| `0011` | rôle VIEW littéral `view` |
| `0012` | view slot_id ; longueur zéro lorsque VIEW disabled |
| `0100` | slot_id |
| `0101` | slot role |
| `0102` | KDF algorithm |
| `0103` | KDF version |
| `0104` | KDF memory_kib |
| `0105` | KDF iterations |
| `0106` | KDF parallelism |
| `0107` | KDF salt |
| `0108` | wrap algorithm |
| `0109` | wrap nonce |
| `010A` | wrap ciphertext |
| `0200` | compartment kind |
| `0201` | compartment payload version |
| `0202` | compartment algorithm |
| `0203` | compartment nonce |
| `0204` | compartment ciphertext |
| `0500` | state-signature algorithm |
| `0001` | magic |
| `0002` | format_version |
| `0003` | owner_auth_public_key |
| `0010` | view enabled |
| `0011` | rôle VIEW littéral `view` |
| `0012` | view slot_id ; longueur zéro lorsque VIEW disabled |
| `0100` | slot_id |
| `0101` | slot role |
| `0102` | KDF algorithm |
| `0103` | KDF version |
| `0104` | KDF memory_kib |
| `0105` | KDF iterations |
| `0106` | KDF parallelism |
| `0107` | KDF salt |
| `0108` | wrap algorithm |
| `0109` | wrap nonce |
| `010A` | wrap ciphertext |
| `0200` | compartment kind |
| `0201` | compartment payload version |
| `0202` | compartment algorithm |
| `0203` | compartment nonce |
| `0204` | compartment ciphertext |
| `0500` | state-signature algorithm |
Les tags ne remplacent pas l'ordre normatif ; **l'ordre ci-dessous est obligatoire**.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/formats/KSPWALLET_V2.md -->
<!-- version: 3 -->
<!-- version: 4 -->
# `.kspwallet` V2 — spécification du wire binaire natif KSP
@@ -104,14 +104,14 @@ Une implémentation conforme doit vérifier les bornes **avant** toute allocatio
Le début de fichier est strictement :
| Ordre | Champ | Taille | Valeur / règle |
| Ordre | Champ | Taille | Valeur / règle |
|------:|---------------------------|-----------------:|------------------------------------------------|
| 1 | `magic` | 9 | ASCII exact `KSPWALLET` |
| 2 | `format_version` | 2 | `0x0002` |
| 3 | `document_length` | 4 | longueur totale exacte du fichier |
| 4 | `flags` | 2 | bit 0 = VIEW activé ; tous les autres bits = 0 |
| 5 | `owner_auth_public_key` | 32 | clé publique Ed25519 OWNER |
| 6 | `view_descriptor.slot_id` | 16 conditionnels | présent uniquement si `flags & 0x0001 != 0` |
| 1 | `magic` | 9 | ASCII exact `KSPWALLET` |
| 2 | `format_version` | 2 | `0x0002` |
| 3 | `document_length` | 4 | longueur totale exacte du fichier |
| 4 | `flags` | 2 | bit 0 = VIEW activé ; tous les autres bits = 0 |
| 5 | `owner_auth_public_key` | 32 | clé publique Ed25519 OWNER |
| 6 | `view_descriptor.slot_id` | 16 conditionnels | présent uniquement si `flags & 0x0001 != 0` |
Offsets fixes avant le descripteur conditionnel :
@@ -154,20 +154,20 @@ Aucun compteur de slots ou de compartiments n'est nécessaire : leur cardinalit
Chaque key slot est encodé ainsi :
| Champ | Taille | Valeur / règle |
| Champ | Taille | Valeur / règle |
|--------------------------|---------:|-----------------------------------------|
| `role` | 1 | `0x01` OWNER, `0x02` VIEW |
| `slot_id` | 16 | identifiant binaire exact |
| `kdf_algorithm` | 1 | `0x01` Argon2id |
| `kdf_version` | 4 | `19` |
| `memory_kib` | 4 | `1..1 048 576`, et `>= parallelism * 8` |
| `iterations` | 4 | `1..64` |
| `parallelism` | 4 | `1..64` |
| `salt_length` | 1 | `16..64` |
| `role` | 1 | `0x01` OWNER, `0x02` VIEW |
| `slot_id` | 16 | identifiant binaire exact |
| `kdf_algorithm` | 1 | `0x01` Argon2id |
| `kdf_version` | 4 | `19` |
| `memory_kib` | 4 | `1..1 048 576`, et `>= parallelism * 8` |
| `iterations` | 4 | `1..64` |
| `parallelism` | 4 | `1..64` |
| `salt_length` | 1 | `16..64` |
| `salt` | variable | exactement `salt_length` octets |
| `wrap_algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `wrap_nonce` | 24 | nonce exact |
| `wrap_ciphertext_length` | 2 | `16..4096` |
| `wrap_algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `wrap_nonce` | 24 | nonce exact |
| `wrap_ciphertext_length` | 2 | `16..4096` |
| `wrap_ciphertext` | variable | exactement la longueur déclarée |
Ordre obligatoire :
@@ -189,13 +189,13 @@ Toute divergence est invalide avant KDF/déchiffrement.
Chaque compartiment est encodé :
| Champ | Taille | Valeur / règle |
| Champ | Taille | Valeur / règle |
|---------------------|---------:|------------------------------------------------------|
| `kind` | 1 | `0x01` OWNER-CONTROL, `0x02` METADATA, `0x03` SECRET |
| `payload_version` | 4 | `1` pour le profil initial V2 |
| `algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `nonce` | 24 | nonce exact |
| `ciphertext_length` | 4 | longueur exacte |
| `kind` | 1 | `0x01` OWNER-CONTROL, `0x02` METADATA, `0x03` SECRET |
| `payload_version` | 4 | `1` pour le profil initial V2 |
| `algorithm` | 1 | `0x01` XChaCha20-Poly1305 |
| `nonce` | 24 | nonce exact |
| `ciphertext_length` | 4 | longueur exacte |
| `ciphertext` | variable | ciphertext + tag Poly1305 |
Bornes initiales :
@@ -216,8 +216,8 @@ La fin du document est :
| Champ | Taille | Valeur / règle |
|-----------------------------|-------:|---------------------------|
| `state_signature.algorithm` | 1 | `0x01` Ed25519 |
| `state_signature.signature` | 64 | signature detached exacte |
| `state_signature.algorithm` | 1 | `0x01` Ed25519 |
| `state_signature.signature` | 64 | signature detached exacte |
Aucun octet ne peut suivre ces 65 octets.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md -->
<!-- version: 19 -->
<!-- version: 20 -->
# Plan `0.1.3` — Configuration foundation
@@ -605,23 +605,23 @@ Décisions :
### 8.1 Écart `ksp-logging-lib 0.1.2` à fermer
| Capacité | `0.1.2` | Requise par `std.logging.json` |
| Capacité | `0.1.2` | Requise par `std.logging.json` |
|-----------------------------------|----------------:|-------------------------------------:|
| filtre global | oui | oui |
| overrides par target | oui | oui |
| lifecycle spans | oui | oui |
| console stdout/stderr | oui | oui |
| console enabled | via `Option` | oui explicite |
| console ANSI configurable | non | oui |
| format console configurable | non | oui |
| plusieurs fichiers | non | oui |
| rotation par fichier | un seul fichier | oui par sink |
| format par fichier | non | oui |
| filtre par sink/target | non | oui |
| filtre par sink/domain | non | oui |
| filtre par sink/niveau | non indépendant | oui |
| hot reload transactionnel | oui | à conserver |
| non-blocking/guards/drop counters | oui | à conserver et généraliser par sinks |
| filtre global | oui | oui |
| overrides par target | oui | oui |
| lifecycle spans | oui | oui |
| console stdout/stderr | oui | oui |
| console enabled | via `Option` | oui explicite |
| console ANSI configurable | non | oui |
| format console configurable | non | oui |
| plusieurs fichiers | non | oui |
| rotation par fichier | un seul fichier | oui par sink |
| format par fichier | non | oui |
| filtre par sink/target | non | oui |
| filtre par sink/domain | non | oui |
| filtre par sink/niveau | non indépendant | oui |
| hot reload transactionnel | oui | à conserver |
| non-blocking/guards/drop counters | oui | à conserver et généraliser par sinks |
Ce tableau est un **gap identifié**, pas une invitation à déplacer Logging dans Config. La tranche qui le ferme modifie `ksp-logging-lib` uniquement dans son domaine propriétaire.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md -->
<!-- version: 28 -->
<!-- version: 29 -->
# Plan `0.1.4` — `ksp-app-config-desk`
@@ -239,7 +239,7 @@ Chaque application Tauri desk KSP reçoit un couple de ports Vite/HMR propre. La
| Application | Port Vite HTTP | Port HMR |
|-----------------------|---------------:|---------:|
| `ksp-app-config-desk` | `1430` | `1431` |
| `ksp-app-config-desk` | `1430` | `1431` |
Les applications suivantes incrémentent le couple de deux ports (`1432/1433`, puis `1434/1435`, etc.). Vite doit utiliser un port strict afin qu'une collision soit signalée au lieu de provoquer un basculement silencieux vers un autre port. Cette allocation permet de faire fonctionner simultanément plusieurs applications desk en mode développement.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# `0.2.1-pre.001` — plan `ksp-onchain-transport-lib` HTTP Solana foundation
@@ -230,30 +230,30 @@ Colonnes : nom, catégorie, paramètres/config à préserver, forme de résultat
| Méthode | Catégorie | Params / config | Résultat | Statut | Runtime | Bot3 | Release | Tests minimaux | Source |
|-------------------------------------|--------------|----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|---------------------------------|----------|---------------|---------|--------------------------------------------------------------|------------------------------------------------------------------------------|
| `getAccountInfo` | Accounts | pubkey ; config? {commitment, encoding, dataSlice, minContextSlot} | RpcResponse<Account\|null> | Stable | Supporté | typed_adapter | `0.2.2` | params/encoding/dataSlice ; account/null ; RPC error | [Solana](https://solana.com/docs/rpc/http/getaccountinfo) |
| `getAccountInfo` | Accounts | pubkey ; config? {commitment, encoding, dataSlice, minContextSlot} | RpcResponse<Account / null> | Stable | Supporté | typed_adapter | `0.2.2` | params/encoding/dataSlice ; account/null ; RPC error | [Solana](https://solana.com/docs/rpc/http/getaccountinfo) |
| `getBalance` | Accounts | pubkey ; config? {commitment, minContextSlot} | RpcResponse<u64> | Stable | Supporté | typed_adapter | `0.2.1` | params/config ; value u64 ; context/error | [Solana](https://solana.com/docs/rpc/http/getbalance) |
| `getLargestAccounts` | Accounts | config? {commitment, filter, sortResults} | RpcResponse<[LargestAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | config/filter/sort ; array | [Solana](https://solana.com/docs/rpc/http/getlargestaccounts) |
| `getMinimumBalanceForRentExemption` | Accounts | data_len ; config? {commitment} | u64 | Stable | Supporté | typed_adapter | `0.2.2` | data length/config ; u64 | [Solana](https://solana.com/docs/rpc/http/getminimumbalanceforrentexemption) |
| `getMultipleAccounts` | Accounts | pubkeys <= 100 ; config? {commitment, minContextSlot, dataSlice, encoding} | RpcResponse<[Account\|null]> | Stable | Supporté | typed_adapter | `0.2.2` | max/params ; mixed account/null ; encoding | [Solana](https://solana.com/docs/rpc/http/getmultipleaccounts) |
| `getMultipleAccounts` | Accounts | pubkeys <= 100 ; config? {commitment, minContextSlot, dataSlice, encoding} | RpcResponse<[Account / null]> | Stable | Supporté | typed_adapter | `0.2.2` | max/params ; mixed account/null ; encoding | [Solana](https://solana.com/docs/rpc/http/getmultipleaccounts) |
| `getProgramAccounts` | Accounts | program pubkey ; config? {commitment, minContextSlot, withContext, encoding, dataSlice, filters, sortResults} | [KeyedAccount] ou RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | filters/dataSlice ; withContext false/true ; errors | [Solana](https://solana.com/docs/rpc/http/getprogramaccounts) |
| `getTokenAccountBalance` | Tokens | token account ; config? {commitment} | RpcResponse<TokenAmount> | Stable | Supporté | typed_adapter | `0.2.2` | config ; token amount | [Solana](https://solana.com/docs/rpc/http/gettokenaccountbalance) |
| `getTokenAccountsByDelegate` | Tokens | delegate ; filter {mint\|programId} ; config? {commitment,minContextSlot,dataSlice,encoding} | RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | mint/programId exclusifs ; config ; array | [Solana](https://solana.com/docs/rpc/http/gettokenaccountsbydelegate) |
| `getTokenAccountsByOwner` | Tokens | owner ; filter {mint\|programId} ; config? {commitment,minContextSlot,dataSlice,encoding} | RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | mint/programId exclusifs ; config ; array | [Solana](https://solana.com/docs/rpc/http/gettokenaccountsbyowner) |
| `getTokenAccountsByDelegate` | Tokens | delegate ; filter {mint / programId} ; config? {commitment,minContextSlot,dataSlice,encoding} | RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | mint/programId exclusifs ; config ; array | [Solana](https://solana.com/docs/rpc/http/gettokenaccountsbydelegate) |
| `getTokenAccountsByOwner` | Tokens | owner ; filter {mint / programId} ; config? {commitment,minContextSlot,dataSlice,encoding} | RpcResponse<[KeyedAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | mint/programId exclusifs ; config ; array | [Solana](https://solana.com/docs/rpc/http/gettokenaccountsbyowner) |
| `getTokenLargestAccounts` | Tokens | mint ; config? {commitment} | RpcResponse<[TokenLargestAccount]> | Stable | Supporté | typed_adapter | `0.2.2` | config ; array | [Solana](https://solana.com/docs/rpc/http/gettokenlargestaccounts) |
| `getTokenSupply` | Tokens | mint ; config? {commitment} | RpcResponse<TokenAmount> | Stable | Supporté | typed_adapter | `0.2.2` | config ; TokenAmount | [Solana](https://solana.com/docs/rpc/http/gettokensupply) |
| `getFeeForMessage` | Transactions | message base64 ; config? {commitment,minContextSlot} | RpcResponse<u64\|null> | Stable | Supporté | typed_adapter | `0.2.3` | message/config ; fee/null ; error | [Solana](https://solana.com/docs/rpc/http/getfeeformessage) |
| `getFeeForMessage` | Transactions | message base64 ; config? {commitment,minContextSlot} | RpcResponse<u64 / null> | Stable | Supporté | typed_adapter | `0.2.3` | message/config ; fee/null ; error | [Solana](https://solana.com/docs/rpc/http/getfeeformessage) |
| `getLatestBlockhash` | Transactions | config? {commitment,minContextSlot} | RpcResponse<{blockhash,lastValidBlockHeight}> | Stable | Supporté | typed_adapter | `0.2.3` | config ; object | [Solana](https://solana.com/docs/rpc/http/getlatestblockhash) |
| `getRecentPrioritizationFees` | Transactions | pubkeys? <= 128 | [{slot,prioritizationFee}] | Stable | Supporté | typed_adapter | `0.2.3` | no params / addresses ; max ; array | [Solana](https://solana.com/docs/rpc/http/getrecentprioritizationfees) |
| `getSignaturesForAddress` | Transactions | address ; config? {commitment,minContextSlot,limit,before,until} | [SignatureInfo] | Stable | Supporté | typed_adapter | `0.2.3` | pagination/config ; nullable memo/blockTime/status | [Solana](https://solana.com/docs/rpc/http/getsignaturesforaddress) |
| `getSignatureStatuses` | Transactions | signatures <= 256 ; config? {searchTransactionHistory} | RpcResponse<[SignatureStatus\|null]> | Stable | Supporté | typed_adapter | `0.2.3` | max ; cache/history ; object/null | [Solana](https://solana.com/docs/rpc/http/getsignaturestatuses) |
| `getTransaction` | Transactions | signature ; config? {commitment,maxSupportedTransactionVersion,encoding} ; legacy bare encoding deprecated | TransactionResponse\|null | Stable; forme legacy deprecated | Supporté | typed_adapter | `0.2.3` | config + legacy warning ; all encodings ; null ; error | [Solana](https://solana.com/docs/rpc/http/gettransaction) |
| `getSignatureStatuses` | Transactions | signatures <= 256 ; config? {searchTransactionHistory} | RpcResponse<[SignatureStatus / null]> | Stable | Supporté | typed_adapter | `0.2.3` | max ; cache/history ; object/null | [Solana](https://solana.com/docs/rpc/http/getsignaturestatuses) |
| `getTransaction` | Transactions | signature ; config? {commitment,maxSupportedTransactionVersion,encoding} ; legacy bare encoding deprecated | TransactionResponse / null | Stable; forme legacy deprecated | Supporté | typed_adapter | `0.2.3` | config + legacy warning ; all encodings ; null ; error | [Solana](https://solana.com/docs/rpc/http/gettransaction) |
| `getTransactionCount` | Transactions | config? {commitment,minContextSlot} | u64 | Stable | Supporté | typed_adapter | `0.2.3` | config ; u64 | [Solana](https://solana.com/docs/rpc/http/gettransactioncount) |
| `isBlockhashValid` | Transactions | blockhash ; config? {commitment,minContextSlot} | RpcResponse<bool> | Stable | Supporté | typed_adapter | `0.2.3` | hash/config ; bool | [Solana](https://solana.com/docs/rpc/http/isblockhashvalid) |
| `requestAirdrop` | Transactions | pubkey ; lamports ; config? {commitment,recentBlockhash} | signature | Stable | Supporté | typed_adapter | `0.2.3` | serialization ; signature/error ; no-resend policy | [Solana](https://solana.com/docs/rpc/http/requestairdrop) |
| `sendTransaction` | Transactions | signed transaction ; config? {encoding,skipPreflight,preflightCommitment,maxRetries,minContextSlot} | signature | Stable | Supporté | typed_adapter | `0.2.3` | all configs ; RPC error ; timeout/no-resend | [Solana](https://solana.com/docs/rpc/http/sendtransaction) |
| `simulateTransaction` | Transactions | transaction ; config? {commitment,encoding,replaceRecentBlockhash,sigVerify,minContextSlot,innerInstructions,accounts} | RpcResponse<SimulationResult> | Stable | Supporté | typed_adapter | `0.2.3` | configs compatibles/incompatibles ; logs/accounts/null/error | [Solana](https://solana.com/docs/rpc/http/simulatetransaction) |
| `getBlock` | Blocks | slot ; config? {commitment,encoding,transactionDetails,maxSupportedTransactionVersion,rewards} ; legacy bare encoding deprecated | BlockResponse\|null | Stable; forme legacy deprecated | Supporté | typed_adapter | `0.2.4` | config + legacy warning ; transactionDetails variants ; null | [Solana](https://solana.com/docs/rpc/http/getblock) |
| `getBlockCommitment` | Blocks | slot | {commitment:[u64]\|null,totalStake:u64} | Stable | Supporté | typed_adapter | `0.2.4` | slot ; commitment null/array | [Solana](https://solana.com/docs/rpc/http/getblockcommitment) |
| `getBlock` | Blocks | slot ; config? {commitment,encoding,transactionDetails,maxSupportedTransactionVersion,rewards} ; legacy bare encoding deprecated | BlockResponse / null | Stable; forme legacy deprecated | Supporté | typed_adapter | `0.2.4` | config + legacy warning ; transactionDetails variants ; null | [Solana](https://solana.com/docs/rpc/http/getblock) |
| `getBlockCommitment` | Blocks | slot | {commitment:[u64] / null,totalStake:u64} | Stable | Supporté | typed_adapter | `0.2.4` | slot ; commitment null/array | [Solana](https://solana.com/docs/rpc/http/getblockcommitment) |
| `getBlockHeight` | Blocks | config? {commitment,minContextSlot} | u64 | Stable | Supporté | typed_adapter | `0.2.4` | config ; u64 | [Solana](https://solana.com/docs/rpc/http/getblockheight) |
| `getBlockProduction` | Blocks | config? {commitment,identity,range} | RpcResponse<BlockProduction> | Stable | Supporté | typed_adapter | `0.2.4` | identity/range/config ; map | [Solana](https://solana.com/docs/rpc/http/getblockproduction) |
| `getBlocks` | Blocks | startSlot ; endSlot? ou config? ; config? {commitment,minContextSlot} | [u64] | Stable | Supporté | typed_adapter | `0.2.4` | overload 1/2/3 params ; max range 500k ; empty | [Solana](https://solana.com/docs/rpc/http/getblocks) |
@@ -267,19 +267,19 @@ Colonnes : nom, catégorie, paramètres/config à préserver, forme de résultat
| `getEpochSchedule` | Cluster | aucun | EpochSchedule | Stable | Supporté | typed_adapter | `0.2.2` | empty params ; object | [Solana](https://solana.com/docs/rpc/http/getepochschedule) |
| `getGenesisHash` | Cluster | aucun | string base58 | Stable | Supporté | typed_adapter | `0.2.1` | empty params ; hash string ; error | [Solana](https://solana.com/docs/rpc/http/getgenesishash) |
| `getHealth` | Cluster | aucun | "ok" ou RPC unhealthy error | Stable | Supporté | typed_adapter | `0.2.1` | healthy ; unhealthy RPC error | [Solana](https://solana.com/docs/rpc/http/gethealth) |
| `getHighestSnapshotSlot` | Cluster | aucun | {full:u64,incremental:u64\|null} | Stable | Supporté | typed_adapter | `0.2.2` | incremental null ; no snapshot/error | [Solana](https://solana.com/docs/rpc/http/gethighestsnapshotslot) |
| `getHighestSnapshotSlot` | Cluster | aucun | {full:u64,incremental:u64 / null} | Stable | Supporté | typed_adapter | `0.2.2` | incremental null ; no snapshot/error | [Solana](https://solana.com/docs/rpc/http/gethighestsnapshotslot) |
| `getIdentity` | Cluster | aucun | {identity:string} | Stable | Supporté | typed_adapter | `0.2.2` | empty params ; identity | [Solana](https://solana.com/docs/rpc/http/getidentity) |
| `getLeaderSchedule` | Cluster | slot? \| config? \| null ; config? {commitment,identity} | map identity->[slot_index] \| null | Stable | Supporté | typed_adapter | `0.2.2` | all overloads ; filter ; null | [Solana](https://solana.com/docs/rpc/http/getleaderschedule) |
| `getLeaderSchedule` | Cluster | slot? / config? / null ; config? {commitment,identity} | map identity->[slot_index] / null | Stable | Supporté | typed_adapter | `0.2.2` | all overloads ; filter ; null | [Solana](https://solana.com/docs/rpc/http/getleaderschedule) |
| `getMaxRetransmitSlot` | Cluster | aucun | u64 | Stable | Supporté | typed_adapter | `0.2.2` | empty params ; u64 | [Solana](https://solana.com/docs/rpc/http/getmaxretransmitslot) |
| `getMaxShredInsertSlot` | Cluster | aucun | u64 | Stable | Supporté | typed_adapter | `0.2.2` | empty params ; u64 | [Solana](https://solana.com/docs/rpc/http/getmaxshredinsertslot) |
| `getSlot` | Cluster | config? {commitment,minContextSlot} | u64 | Stable | Supporté | typed_adapter | `0.2.2` | config ; u64 | [Solana](https://solana.com/docs/rpc/http/getslot) |
| `getSlotLeader` | Cluster | config? {commitment,minContextSlot} | string pubkey | Stable | Supporté | typed_adapter | `0.2.2` | config ; pubkey | [Solana](https://solana.com/docs/rpc/http/getslotleader) |
| `getSlotLeaders` | Cluster | startSlot ; limit 1..5000 | [string pubkey] | Stable | Supporté | typed_adapter | `0.2.2` | limit boundaries ; array | [Solana](https://solana.com/docs/rpc/http/getslotleaders) |
| `getVersion` | Cluster | aucun | {solana-core:string,feature-set:u32\|null} | Stable | Supporté | typed_adapter | `0.2.1` | empty params ; feature-set present/null | [Solana](https://solana.com/docs/rpc/http/getversion) |
| `getVersion` | Cluster | aucun | {solana-core:string,feature-set:u32 / null} | Stable | Supporté | typed_adapter | `0.2.1` | empty params ; feature-set present/null | [Solana](https://solana.com/docs/rpc/http/getversion) |
| `getVoteAccounts` | Cluster | config? {commitment,votePubkey,keepUnstakedDelinquents,delinquentSlotDistance} | {current:[VoteAccount],delinquent:[VoteAccount]} | Stable | Supporté | typed_adapter | `0.2.2` | filters/config ; both sets | [Solana](https://solana.com/docs/rpc/http/getvoteaccounts) |
| `getInflationGovernor` | Economics | config? {commitment} | InflationGovernor | Stable | Supporté | typed_adapter | `0.2.4` | config ; f64 fields | [Solana](https://solana.com/docs/rpc/http/getinflationgovernor) |
| `getInflationRate` | Economics | aucun | {total,validator,foundation:f64,epoch:u64} | Stable | Supporté | typed_adapter | `0.2.4` | empty params ; object | [Solana](https://solana.com/docs/rpc/http/getinflationrate) |
| `getInflationReward` | Economics | addresses ; config? {commitment,epoch,minContextSlot} | [InflationReward\|null] | Stable | Supporté | typed_adapter | `0.2.4` | addresses/config ; reward/null ; commission null | [Solana](https://solana.com/docs/rpc/http/getinflationreward) |
| `getInflationReward` | Economics | addresses ; config? {commitment,epoch,minContextSlot} | [InflationReward / null] | Stable | Supporté | typed_adapter | `0.2.4` | addresses/config ; reward/null ; commission null | [Solana](https://solana.com/docs/rpc/http/getinflationreward) |
| `getStakeMinimumDelegation` | Economics | config? {commitment,minContextSlot} | RpcResponse<u64> | Stable | Supporté | typed_adapter | `0.2.4` | config ; value | [Solana](https://solana.com/docs/rpc/http/getstakeminimumdelegation) |
| `getSupply` | Economics | config? {commitment,excludeNonCirculatingAccountsList} | RpcResponse<Supply> | Stable | Supporté | typed_adapter | `0.2.4` | config true/false ; list semantics | [Solana](https://solana.com/docs/rpc/http/getsupply) |

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md -->
<!-- version: 15 -->
<!-- version: 16 -->
# Plan `0.2.5` — Wallet foundation
@@ -205,23 +205,23 @@ Les permissions/ACL et le contrôle de qui peut écrire le chemin relèvent du s
### 5.7 Matrice des garanties
| Garantie | Cryptographie du format | Types/capabilities KSP |
| Garantie | Cryptographie du format | Types/capabilities KSP |
|------------------------------------------------------------------------|-------------------------------------------------------:|-------------------------:|
| confidentialité metadata verrouillées | oui | oui |
| confidentialité secret Solana face à VIEW | oui | oui |
| indépendance VIEW/OWNER | oui | oui |
| VIEW ne signe pas | séparation de clés | oui |
| VIEW ne modifie pas Pubkey/alias/notes via API | authentification OWNER des metadata | oui |
| VIEW change son propre password | slot VIEW rewrappable sous la même capability metadata | oui, opération dédiée |
| VIEW ne change pas password OWNER / activation VIEW / autres key slots | authentification OWNER de l'état de contrôle | oui |
| metadata modifiées par VIEW détectées sous la même autorité OWNER | oui, `state_signature` | oui |
| détection corruption/tampering partiel | oui | parsing strict |
| signature Solana sans OWNER | impossible sous les primitives retenues | API absente hors OWNER |
| export secret sans OWNER | secret non déverrouillable | API absente hors OWNER |
| mutation Pubkey/alias/notes/OWNER-state sans OWNER | état non authentifiable | API absente hors OWNER |
| no-clobber / atomic replace | non | propriété de persistence |
| détection remplacement total par un autre wallet valide | hors garantie V1 | hors garantie V1 |
| détection rollback total vers une copie valide | hors garantie V1 | hors garantie V1 |
| confidentialité metadata verrouillées | oui | oui |
| confidentialité secret Solana face à VIEW | oui | oui |
| indépendance VIEW/OWNER | oui | oui |
| VIEW ne signe pas | séparation de clés | oui |
| VIEW ne modifie pas Pubkey/alias/notes via API | authentification OWNER des metadata | oui |
| VIEW change son propre password | slot VIEW rewrappable sous la même capability metadata | oui, opération dédiée |
| VIEW ne change pas password OWNER / activation VIEW / autres key slots | authentification OWNER de l'état de contrôle | oui |
| metadata modifiées par VIEW détectées sous la même autorité OWNER | oui, `state_signature` | oui |
| détection corruption/tampering partiel | oui | parsing strict |
| signature Solana sans OWNER | impossible sous les primitives retenues | API absente hors OWNER |
| export secret sans OWNER | secret non déverrouillable | API absente hors OWNER |
| mutation Pubkey/alias/notes/OWNER-state sans OWNER | état non authentifiable | API absente hors OWNER |
| no-clobber / atomic replace | non | propriété de persistence |
| détection remplacement total par un autre wallet valide | hors garantie V1 | hors garantie V1 |
| détection rollback total vers une copie valide | hors garantie V1 | hors garantie V1 |
Les ACL/permissions OS ne figurent volontairement pas dans cette matrice : elles ne participent pas au modèle de sécurité de `.kspwallet` V1.
@@ -388,9 +388,9 @@ Audit source notable : `solana-keypair 3.1.2` contient un bloc `unsafe` interne
| Primitive | Version publiée auditée | Décision V1 |
|-----------|------------------------:|--------------------------------------------|
| Argon2 | `0.5.3` | **retenu : Argon2id v19** |
| scrypt | `0.12.0` | alternative maintenue, non ajoutée |
| PBKDF2 | `0.13.0` | compatibilité/legacy seulement, non ajouté |
| Argon2 | `0.5.3` | **retenu : Argon2id v19** |
| scrypt | `0.12.0` | alternative maintenue, non ajoutée |
| PBKDF2 | `0.13.0` | compatibilité/legacy seulement, non ajouté |
Les paramètres Argon2 de création ont été mesurés avec le benchmark opérateur de `pre.004` : `64 MiB / 3 / 1 = 1742 ms`, `128 MiB / 3 / 1 = 3459 ms`, `256 MiB / 3 / 1 = 6925 ms` sur la machine/profil testés le 2026-08-19. `pre.005` retient donc **64 MiB / 3 passes / 1 lane** comme profil initial de création KSP, avec un salt CSPRNG indépendant de 32 octets par slot. Ce choix n'est copié ni de bot3, ni d'un RFC, ni d'un default de crate. Le fichier sérialise tous les paramètres nécessaires afin qu'un ancien wallet conserve son profil historique même lorsque les defaults KSP seront durcis.
@@ -398,10 +398,10 @@ Le parseur impose des **bornes maximales** avant de lancer le KDF, afin qu'un fi
### 8.3 AEAD
| Primitive | Version publiée auditée | Décision V1 |
| Primitive | Version publiée auditée | Décision V1 |
|--------------------|--------------------------:|------------------|
| XChaCha20-Poly1305 | `chacha20poly1305 0.11.0` | **retenu** |
| AES-256-GCM-SIV | `aes-gcm-siv 0.12.0` | non retenu en V1 |
| AES-256-GCM-SIV | `aes-gcm-siv 0.12.0` | non retenu en V1 |
XChaCha20-Poly1305 fournit une clé 256 bits et un nonce étendu 192 bits. Un nonce neuf est généré pour chaque wrapping/chiffrement. La crate RustCrypto documente un audit NCC Group sans constat significatif.
@@ -1107,20 +1107,20 @@ liens Markdown locaux audités
| Domaine | Taille | Risque principal |
|-------------------------------|-------:|----------------------------------------------|
| crate/API foundation | M | capability surface durable |
| threat model | M | faux niveau de garantie |
| format wire | L | strict parsing/versioning |
| interop/test vectors | L | transcript exact multi-langages |
| KDF/AEAD/key wrapping | L | paramètres + nonce/AAD |
| VIEW/OWNER key slots | XL | indépendance et rotations |
| auth crypto metadata niveau B | L/XL | clé admin + transcript + substitution limits |
| persistence | L | no-clobber + crash semantics multi-OS |
| signing | M | aucun secret getter |
| password/key-slot rotation | L | rotation vs vraie révocation |
| alias/notes | M | bornes + persistence |
| import/export | M/L | extension sans secret API générale |
| security/adversarial tests | XL | tamper/fault/diagnostics |
| spec/README/USAGE | L | contrat externe autonome |
| crate/API foundation | M | capability surface durable |
| threat model | M | faux niveau de garantie |
| format wire | L | strict parsing/versioning |
| interop/test vectors | L | transcript exact multi-langages |
| KDF/AEAD/key wrapping | L | paramètres + nonce/AAD |
| VIEW/OWNER key slots | XL | indépendance et rotations |
| auth crypto metadata niveau B | L/XL | clé admin + transcript + substitution limits |
| persistence | L | no-clobber + crash semantics multi-OS |
| signing | M | aucun secret getter |
| password/key-slot rotation | L | rotation vs vraie révocation |
| alias/notes | M | bornes + persistence |
| import/export | M/L | extension sans secret API générale |
| security/adversarial tests | XL | tamper/fault/diagnostics |
| spec/README/USAGE | L | contrat externe autonome |
Conclusion : **pas de rescoping fonctionnel**, mais split supplémentaire avant crypto lourde.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md -->
<!-- version: 17 -->
<!-- version: 18 -->
# Plan `0.2.7` — WebSocket Solana standard
@@ -361,10 +361,10 @@ Audit au 2026-08-22 :
| Candidate | Version auditée | Verdict | Motif |
|---------------------|----------------:|---------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------|
| `tokio-tungstenite` | `0.30.0` | **retenue** | mature, Tokio-native, TLS rustls, continuité avec bot3 mais réauditée, contrôle de `WebSocketConfig`, client + serveur local de test |
| `futures-util` | `0.3.34` | **retenue comme utilitaire** | `StreamExt`/`SinkExt`; features minimales `std,sink` |
| `tokio-websockets` | `0.13.3` | alternative viable, non retenue | strict/minimal et performant, mais exige davantage d'assemblage/features et n'apporte pas de besoin fonctionnel supérieur démontré pour cette foundation |
| `fastwebsockets` | `0.10.0` | non retenue | plus bas niveau ; peut déléguer davantage de compliance au caller, inutile pour la première foundation KSP |
| `tokio-tungstenite` | `0.30.0` | **retenue** | mature, Tokio-native, TLS rustls, continuité avec bot3 mais réauditée, contrôle de `WebSocketConfig`, client + serveur local de test |
| `futures-util` | `0.3.34` | **retenue comme utilitaire** | `StreamExt`/`SinkExt`; features minimales `std,sink` |
| `tokio-websockets` | `0.13.3` | alternative viable, non retenue | strict/minimal et performant, mais exige davantage d'assemblage/features et n'apporte pas de besoin fonctionnel supérieur démontré pour cette foundation |
| `fastwebsockets` | `0.10.0` | non retenue | plus bas niveau ; peut déléguer davantage de compliance au caller, inutile pour la première foundation KSP |
Landing matérialisé par **`pre.004`** :

View File

@@ -1,9 +1,9 @@
<!-- file: docs/plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md -->
<!-- version: 22 -->
<!-- version: 23 -->
# Plan `0.2.9` — moteur Yellowstone gRPC + standard Solana + PublicNode
> **Statut courant : `0.2.9-pre.010-fix.001` est fermée par gate opérateur sans warning. `0.2.9-pre.011` est la tranche active : Config Transport V3, séparation explicite protocol/provider, mapping Config -> Yellowstone gRPC et premier profil PublicNode Mainnet. Le présent document a été réorganisé pendant `pre.011` : les décisions actives restent ici ; les journaux historiques détaillés restent dans `deltas/0.2.9/`.**
**Statut courant : `0.2.9-pre.011` est fermée par gate opérateur complet sans warning. `0.2.9-pre.012` est la tranche active de fermeture technique : réaudit upstream final, smoke PublicNode Mainnet opt-in, compliance finale, graphes Cargo, README/USAGE, règles de tableaux Markdown et prompt autonome `0.2.10 — OrbitFlare Yellowstone gRPC`. Les journaux détaillés restent dans `deltas/0.2.9/`; ce plan conserve létat courant et les décisions.**
## 1. Objet et autorité de la release
@@ -88,18 +88,24 @@ Les intégrations provider futures ne dupliquent jamais le moteur N1. Une façad
## 4. Audit upstream et dépendances retenues
### 4.1 Snapshot normatif du gate
### 4.1 Snapshot normatif et réaudit final
Le gate d'ouverture a réaudité Yellowstone courant et a constaté des versions indépendantes entre plugin, client et proto :
Le gate d'ouverture puis le réaudit final du 2026-08-24 confirment que les numéros du plugin, du client, du proto et des releases GitHub évoluent indépendamment. Il ne faut donc pas transformer un numéro de `master` en numéro de release publié.
État observé au réaudit final :
```text
release GitHub observée v15.1.2+solana.4.2.0 — 2026-08-18
yellowstone-grpc-client 13.3.0
yellowstone-grpc-proto 12.6.0
prost/prost-types 0.14.x
tonic 0.14.x
latest release GitHub indexée v14.2.2+solana.4.1.0 — 2026-07-27
master yellowstone-grpc-geyser 15.1.2
master yellowstone-grpc-client 13.3.0
master yellowstone-grpc-proto 12.6.0
master Agave Geyser / storage 4.2.0
master prost / prost-types / tonic 0.14.x
KSP yellowstone-grpc-proto direct ^12.6
```
Le service `Geyser`, la shape de `SubscribeRequest` et les neuf variantes `SubscribeUpdate` retenues par KSP n'ont pas changé matériellement par rapport au gate `pre.001`. `SubscribeDeshred` reste explicitement hors scope `0.2.9`.
Les sources primaires restent :
```text
@@ -530,18 +536,20 @@ La partie HTTP/WS de ce profil reste standard Solana ; seul l'endpoint gRPC est
### 9.2 Testnet
PublicNode affiche toujours une offre Solana Testnet gRPC, mais le hostname exact n'est pas exposé de façon suffisamment autoritative dans la surface publique inspectable pendant `pre.011`.
Le réaudit final du 2026-08-24 confirme que PublicNode annonce bien une capacité Solana Testnet gRPC. La surface officielle consultable ne fournit cependant toujours pas un hostname Testnet exact suffisamment autoritatif pour être versionné.
Décision :
Décision finale `0.2.9` :
```text
existence Testnet gRPC confirmée
hostname Testnet exact non inventé
profil Testnet committé non en pre.011
réaudit endpoint/live pre.012
hostname Testnet exact non obtenu depuis une source autoritative
hostname déduit ou tiers interdit
profil Testnet committé non
smoke Testnet non
statut EXTERNAL BLOCK documentaire / NOT GUESSED
```
Un échec à confirmer le hostname Testnet ne bloque pas la fondation Mainnet ; il doit être documenté explicitement au gate final.
Ce bloc externe ne remet pas en cause la fondation Mainnet. Une release provider ultérieure peut matérialiser Testnet dès qu'une source PublicNode autoritative expose l'endpoint exact.
## 10. Threat model et bornes
@@ -608,13 +616,16 @@ Les preuves détaillées restent dans les fichiers `deltas/0.2.9/*.md`. Le plan
| `pre.008` + fix | Blocks + block_meta + entry | **CLOSED** |
| `pre.009` + fix | bidi, Ping/Pong, backpressure, half-close, shutdown | **CLOSED** |
| `pre.010` + fix | reconnect, from_slot, ReplayInfo, gaps/duplicates | **CLOSED** |
| `pre.011` | Config V3 + protocol/provider + PublicNode Mainnet | **ACTIVE CANDIDATE** |
| `pre.012` | live/compliance/docs/graph/prompt suivant | **PLANNED** |
| `pre.011` | Config V3 + protocol/provider + PublicNode Mainnet | **CLOSED** |
| `pre.012` | live/compliance/docs/graph/prompt suivant | **ACTIVE CANDIDATE** |
Gate opérateur de fermeture `pre.010-fix.001` :
Gate opérateur de fermeture `pre.011` :
```text
fmt/audit/check/clippy PASS sans warning
Config unit 113/113
Config public API 15/15
Config ownership 5/5
Transport unit 383/383
Transport public API 49/49
Transport completeness 43/43
@@ -625,51 +636,31 @@ cargo test --workspace PASS
## 13. Forecast restant
### `pre.011` — Config V3 + PublicNode Mainnet
Cible :
```text
workspace.package.version = 0.2.9-pre.11
schema std.transport V3 strict + branches V1/V2
Config adapter gRPC
metadata publique/secrète + provenance
protocol/provider distincts
profil publicnode_mainnet
compatibilité API V2 conservée
plan 016 + validation 012 réorganisés
```
Preuves :
```text
schema Draft 2020-12 valide
fixtures V1/V2/V3
Config unit/public API/ownership
Transport non-régressé
workspace complet
```
### `pre.012` — fermeture technique et live
Cible :
Cible active :
```text
workspace.package.version = 0.2.9-pre.12
réaudit upstream final
réaudit PublicNode Testnet hostname
smoke PublicNode Mainnet opt-in
Testnet opt-in seulement si endpoint exact confirmé
réaudit PublicNode Testnet sans endpoint inventé
smoke PublicNode Mainnet opt-in, programmatique et sans credential
compliance HTTP 52 current + 14 historical
compliance Standard WS 18/18
Helius WebSocket non régressé
cargo tree direct + duplicates final
README/USAGE Transport synchronisés
matrice validation fermée
prompt 0.2.10 préparé selon la séquence active
règles Markdown sur les tableaux reformulées et auditées mécaniquement
validation 012 fermée si les gates opérateur sont verts
prompt 0.2.10 OrbitFlare autonome
workspace final vert
```
Si `pre.012` devient trop large, une `pre.013+` est créée ; le numéro n'est pas une deadline.
La candidate ajoute un smoke live **ignoré par défaut** ; elle ne modifie pas le runtime Yellowstone déjà fermé. Le smoke Mainnet utilise uniquement la façade provider-neutral KSP, `GetVersion` et `GetSlot`, avec TLS et sans metadata d'authentification.
Le Testnet reste `EXTERNAL BLOCK / NOT GUESSED` tant que PublicNode n'expose pas l'endpoint exact dans une source autoritative.
Si le gate opérateur révèle une anomalie réelle, un `pre.012-fix.001` est créé. Si la fermeture nécessite une nouvelle frontière fonctionnelle plutôt qu'un fix, une `pre.013+` est ouverte ; le numéro n'est pas une deadline.
## 14. Critères de split
@@ -689,27 +680,21 @@ moteur Yellowstone + façade Solana standard + Config provider-neutral + premiè
## 15. Gates opérateur
Après changement Rust :
Gate `pre.012` :
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.9
cargo check --workspace
cargo clippy --workspace --all-targets
```
Pour `pre.011` :
```bash
cargo test -p ksp-config-lib
cargo test -p ksp-config-lib --test public_api
cargo test -p ksp-config-lib --test ownership
cargo test -p ksp-onchain-transport-lib
cargo test -p ksp-core-lib --test workspace_dependencies
cargo test --workspace
```
Le graphe de dépendances gRPC n'est pas modifié par `pre.011`; son gate final complet reste en `pre.012` :
Graphes finaux :
```bash
cargo tree -p ksp-onchain-transport-lib
@@ -717,6 +702,14 @@ cargo tree -p ksp-onchain-transport-lib --duplicates
cargo tree --duplicates
```
Smoke live opt-in Mainnet :
```bash
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
```
Le smoke n'est jamais déclaré réussi avant exécution. Un incident externe PublicNode/TLS/réseau est consigné comme tel et ne doit pas être maquillé en PASS local. Le Testnet n'est pas exécuté tant que son endpoint exact n'est pas confirmé par une source PublicNode autoritative.
## 16. Conditions de clôture `0.2.9`
```text

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_DOCUMENTATION.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Règles de documentation
@@ -32,6 +32,15 @@ Les règles `DOC-*` s'appliquent aux documents Markdown internes et à leur orga
- **DOC-IDEAS-003** — Lorsqu'une idée devient un engagement, elle est transférée vers le roadmap ou un plan ; lorsqu'elle devient une décision durable, elle est reportée dans le document normatif ou architectural approprié. `IDEAS.md` conserve une trace concise de son issue.
- **DOC-IDEAS-004** — `IDEAS.md` ne doit pas devenir un second roadmap ni une liste de tâches de développement promises.
## Format des tableaux Markdown
- **DOC-TABLE-001** — Un tableau Markdown KSP utilise `|` uniquement comme séparateur structurel de colonnes. Un caractère `|` littéral, y compris sous forme échappée `\|`, est interdit dans le contenu dune cellule ; reformuler le contenu, utiliser `/`, `et`, une liste ou un bloc de code hors tableau.
- **DOC-TABLE-002** — Toutes les lignes dun même tableau ont leurs séparateurs verticaux aux mêmes positions. La largeur de chaque colonne est déterminée par le contenu le plus large de cette colonne, en comptant len-tête et les lignes de données.
- **DOC-TABLE-003** — Chaque cellule de contenu commence par exactement un espace après le séparateur `|` gauche. Dans la cellule qui porte le contenu le plus large dune colonne, il existe aussi exactement un espace entre le contenu et le séparateur `|` droit. Les cellules plus courtes conservent lunique espace gauche et reçoivent uniquement le padding droit nécessaire pour aligner les séparateurs verticaux.
- **DOC-TABLE-004** — La ligne séparatrice en tirets occupe exactement la même largeur que chaque colonne ; les marqueurs `:` de lalignement Markdown restent autorisés lorsquils sont intentionnels. Le résultat attendu est équivalent au reformatage de tableau produit par RustRover, mais la règle structurelle KSP prime sur léditeur utilisé.
- **DOC-TABLE-005** — Lorsquune modification touche une ligne dun tableau, le tableau entier est réaligné avant livraison. `python3 scripts/audit_markdown_tables.py <fichiers-markdown-modifiés>` est le canari mécanique recommandé pour les fichiers concernés ; les blocs de code fenced ne sont pas interprétés comme des tableaux.
- **DOC-TABLE-006** — Limmuabilité des deltas déjà publiés prime sur un reformatage rétrospectif : un ancien fichier `deltas/` nest jamais réécrit uniquement pour satisfaire une règle de présentation introduite ultérieurement. Tout nouveau delta et tout autre tableau modifiable créé ou touché doivent en revanche respecter immédiatement `DOC-TABLE-001` à `DOC-TABLE-005`.
## Contenu et exactitude
- **DOC-CONTENT-001** — Une documentation décrit l'état réellement décidé ou validé et distingue explicitement les hypothèses, propositions, TODO et questions ouvertes.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md -->
<!-- version: 17 -->
<!-- version: 18 -->
# Validation `0.2.7` — WebSocket Solana standard
@@ -33,26 +33,26 @@ Pour une paire unstable, l'unsubscribe associé est classé `Unstable pair` dans
## 2. Matrice exhaustive des 18 opérations
| # | Méthode | Type | Statut `pre.001` | Paramètres / résultat essentiels | Notification / paire | Stratégie de test | Source officielle | Compliance |
|---:|---------------------------|-------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|---------------------------------------------------------------|-----------------------------------------------------------------|-------------------|
| 1 | `accountSubscribe` | subscribe | Stable/documented | pubkey ; config `commitment`, `encoding`, `dataSlice` ; result numeric id ; `minContextSlot` upstream actuellement ignoré, donc non promis | `accountNotification` | fixture encodings/config + subscribe/notify | `https://solana.com/docs/rpc/websocket/accountsubscribe` | Done `pre.009` |
| 2 | `accountUnsubscribe` | unsubscribe | Stable/documented | remote id ; `true` or RPC error unknown id | account pair | handle local -> remote id fixture | `https://solana.com/docs/rpc/websocket/accountunsubscribe` | Done `pre.009` |
| 3 | `blockSubscribe` | subscribe | **Unstable** | `all`/mentions filter ; confirmed/finalized ; encoding ; tx details ; max tx version ; showRewards | `blockNotification` | all options + null block/error + validator capability fixture | `https://solana.com/docs/rpc/websocket/blocksubscribe` | Done `pre.011` |
| 4 | `blockUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | block pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/blockunsubscribe` | Done `pre.011` |
| 5 | `logsSubscribe` | subscribe | Stable/documented | `all`, `allWithVotes`, exactly one `mentions`; commitment | `logsNotification` | 3 filters + invalid multi-mention + notification | `https://solana.com/docs/rpc/websocket/logssubscribe` | Done `pre.009` |
| 6 | `logsUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | logs pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/logsunsubscribe` | Done `pre.009` |
| 7 | `programSubscribe` | subscribe | Stable/documented | program pubkey ; commitment ; filters ; encoding ; dataSlice ; `withContext` | `programNotification` | contexted/non-contexted fixtures + filters | `https://solana.com/docs/rpc/websocket/programsubscribe` | Done `pre.009` |
| 8 | `programUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | program pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/programunsubscribe` | Done `pre.009` |
| 9 | `rootSubscribe` | subscribe | Stable/documented | no params ; numeric id | `rootNotification` => `u64` | exact root fixture | `https://solana.com/docs/rpc/websocket/rootsubscribe` | Done `pre.010` |
| 10 | `rootUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | root pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/rootunsubscribe` | Done `pre.010` |
| 11 | `signatureSubscribe` | subscribe | Stable/documented | first transaction signature ; commitment ; `enableReceivedNotification` | `signatureNotification` early string or terminal error object | early + terminal + auto-close/no-resubscribe | `https://solana.com/docs/rpc/websocket/signaturesubscribe` | Done `pre.010` |
| 12 | `signatureUnsubscribe` | unsubscribe | Stable/documented | remote id before terminal fire ; boolean/error | signature pair | cancel before terminal + stale after terminal | `https://solana.com/docs/rpc/websocket/signatureunsubscribe` | Done `pre.010` |
| 13 | `slotSubscribe` | subscribe | Stable/documented | no params ; numeric id | `slotNotification` `{slot,parent,root}` | exact fixture + live smoke Devnet passé | `https://solana.com/docs/rpc/websocket/slotsubscribe` | Done `pre.010` |
| 14 | `slotUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | slot pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotunsubscribe` | Done `pre.010` |
| 15 | `slotsUpdatesSubscribe` | subscribe | **Unstable** | no params ; numeric id | tagged `slotsUpdatesNotification` | each known variant + unknown fallback | `https://solana.com/docs/rpc/websocket/slotsupdatessubscribe` | Done `pre.011` |
| 16 | `slotsUpdatesUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | slotsUpdates pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotsupdatesunsubscribe` | Done `pre.011` |
| 17 | `voteSubscribe` | subscribe | **Unstable** | no params ; validator flag required | `voteNotification` | fields + timestamp omitted/null/value + warning | `https://solana.com/docs/rpc/websocket/votesubscribe` | Done `pre.011` |
| 18 | `voteUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | vote pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/voteunsubscribe` | Done `pre.011` |
| # | Méthode | Type | Statut `pre.001` | Paramètres / résultat essentiels | Notification / paire | Stratégie de test | Source officielle | Compliance |
|---:|---------------------------|-------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|---------------------------------------------------------------|-----------------------------------------------------------------|----------------|
| 1 | `accountSubscribe` | subscribe | Stable/documented | pubkey ; config `commitment`, `encoding`, `dataSlice` ; result numeric id ; `minContextSlot` upstream actuellement ignoré, donc non promis | `accountNotification` | fixture encodings/config + subscribe/notify | `https://solana.com/docs/rpc/websocket/accountsubscribe` | Done `pre.009` |
| 2 | `accountUnsubscribe` | unsubscribe | Stable/documented | remote id ; `true` or RPC error unknown id | account pair | handle local -> remote id fixture | `https://solana.com/docs/rpc/websocket/accountunsubscribe` | Done `pre.009` |
| 3 | `blockSubscribe` | subscribe | **Unstable** | `all`/mentions filter ; confirmed/finalized ; encoding ; tx details ; max tx version ; showRewards | `blockNotification` | all options + null block/error + validator capability fixture | `https://solana.com/docs/rpc/websocket/blocksubscribe` | Done `pre.011` |
| 4 | `blockUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | block pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/blockunsubscribe` | Done `pre.011` |
| 5 | `logsSubscribe` | subscribe | Stable/documented | `all`, `allWithVotes`, exactly one `mentions`; commitment | `logsNotification` | 3 filters + invalid multi-mention + notification | `https://solana.com/docs/rpc/websocket/logssubscribe` | Done `pre.009` |
| 6 | `logsUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | logs pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/logsunsubscribe` | Done `pre.009` |
| 7 | `programSubscribe` | subscribe | Stable/documented | program pubkey ; commitment ; filters ; encoding ; dataSlice ; `withContext` | `programNotification` | contexted/non-contexted fixtures + filters | `https://solana.com/docs/rpc/websocket/programsubscribe` | Done `pre.009` |
| 8 | `programUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | program pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/programunsubscribe` | Done `pre.009` |
| 9 | `rootSubscribe` | subscribe | Stable/documented | no params ; numeric id | `rootNotification` => `u64` | exact root fixture | `https://solana.com/docs/rpc/websocket/rootsubscribe` | Done `pre.010` |
| 10 | `rootUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | root pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/rootunsubscribe` | Done `pre.010` |
| 11 | `signatureSubscribe` | subscribe | Stable/documented | first transaction signature ; commitment ; `enableReceivedNotification` | `signatureNotification` early string or terminal error object | early + terminal + auto-close/no-resubscribe | `https://solana.com/docs/rpc/websocket/signaturesubscribe` | Done `pre.010` |
| 12 | `signatureUnsubscribe` | unsubscribe | Stable/documented | remote id before terminal fire ; boolean/error | signature pair | cancel before terminal + stale after terminal | `https://solana.com/docs/rpc/websocket/signatureunsubscribe` | Done `pre.010` |
| 13 | `slotSubscribe` | subscribe | Stable/documented | no params ; numeric id | `slotNotification` `{slot,parent,root}` | exact fixture + live smoke Devnet passé | `https://solana.com/docs/rpc/websocket/slotsubscribe` | Done `pre.010` |
| 14 | `slotUnsubscribe` | unsubscribe | Stable/documented | remote id ; boolean/error | slot pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotunsubscribe` | Done `pre.010` |
| 15 | `slotsUpdatesSubscribe` | subscribe | **Unstable** | no params ; numeric id | tagged `slotsUpdatesNotification` | each known variant + unknown fallback | `https://solana.com/docs/rpc/websocket/slotsupdatessubscribe` | Done `pre.011` |
| 16 | `slotsUpdatesUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | slotsUpdates pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/slotsupdatesunsubscribe` | Done `pre.011` |
| 17 | `voteSubscribe` | subscribe | **Unstable** | no params ; validator flag required | `voteNotification` | fields + timestamp omitted/null/value + warning | `https://solana.com/docs/rpc/websocket/votesubscribe` | Done `pre.011` |
| 18 | `voteUnsubscribe` | unsubscribe | **Unstable pair** | remote id ; boolean/error | vote pair | generic registry unsubscribe | `https://solana.com/docs/rpc/websocket/voteunsubscribe` | Done `pre.011` |
## 3. Notification matrix
@@ -206,22 +206,22 @@ Les votes observés sont gossip/pre-consensus ; aucune garantie d'entrée dans l
## 7. Threat/security compliance initiale
| Invariant | Preuve attendue | Statut |
|---------------------------------------------------|----------------------------------------------|--------------------------------------------------------|
| URL/credentials absents de `Debug` | unit tests URL wrapper | **Done `pre.002`** |
| URL/credentials absents des erreurs | validation URL + connection errors safe | **Done through `pre.004`** |
| URL/credentials absents des logs | actor logs only safe endpoint metadata | **Done through `pre.011`, source audit `pre.013`** |
| snapshots sans URL/raw payload | unit shape + public contract | **Done `pre.002`** |
| frame/message finis | settings bornés + `WebSocketConfig` raccordé | **Done `pre.005`** |
| JSON borné indirectement par message | oversized + malformed fixture | **Done `pre.005`** |
| queues notifications bornées | queue typed bornée + overflow isolé | **Done `pre.008`** |
| pending RPC borné + timeout | map actor bornée + timeout request | **Done `pre.004`** |
| reconnect loop bornée | repeated disconnect fixture | Done `pre.007` |
| unsubscribe pendant reconnect ne resubscribe pas | race fixture | Done `pre.007` |
| signature terminale ne resubscribe pas | terminal fixture | **Done `pre.010`** |
| shutdown ne bloque pas | peer hostile/no close ack fixture | **Done `pre.005`** |
| no Store/Program/Wallet/Config dep dans Transport | cargo tree + source canary | **Done `pre.013`, source + cargo tree opérateur** |
| no direct `tracing` dans Transport | workspace audit + source audit | **Done `pre.002`** |
| Invariant | Preuve attendue | Statut |
|---------------------------------------------------|----------------------------------------------|----------------------------------------------------|
| URL/credentials absents de `Debug` | unit tests URL wrapper | **Done `pre.002`** |
| URL/credentials absents des erreurs | validation URL + connection errors safe | **Done through `pre.004`** |
| URL/credentials absents des logs | actor logs only safe endpoint metadata | **Done through `pre.011`, source audit `pre.013`** |
| snapshots sans URL/raw payload | unit shape + public contract | **Done `pre.002`** |
| frame/message finis | settings bornés + `WebSocketConfig` raccordé | **Done `pre.005`** |
| JSON borné indirectement par message | oversized + malformed fixture | **Done `pre.005`** |
| queues notifications bornées | queue typed bornée + overflow isolé | **Done `pre.008`** |
| pending RPC borné + timeout | map actor bornée + timeout request | **Done `pre.004`** |
| reconnect loop bornée | repeated disconnect fixture | Done `pre.007` |
| unsubscribe pendant reconnect ne resubscribe pas | race fixture | Done `pre.007` |
| signature terminale ne resubscribe pas | terminal fixture | **Done `pre.010`** |
| shutdown ne bloque pas | peer hostile/no close ack fixture | **Done `pre.005`** |
| no Store/Program/Wallet/Config dep dans Transport | cargo tree + source canary | **Done `pre.013`, source + cargo tree opérateur** |
| no direct `tracing` dans Transport | workspace audit + source audit | **Done `pre.002`** |
## 8. Dependency compliance initiale

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md -->
<!-- version: 25 -->
<!-- version: 26 -->
# Validation `0.2.8` — Helius LaserStream WebSocket
@@ -108,23 +108,23 @@ Verdict : **gate `0.2.8-pre.001` positif ; `pre.002` + `fix.001` et `pre.003` so
## 3. Matrice provider normative
| Capability | Standard KSP | Helius doc actuelle | Décision `0.2.8` | Surface Helius attendue | Preuve finale attendue |
| Capability | Standard KSP | Helius doc actuelle | Décision `0.2.8` | Surface Helius attendue | Preuve finale attendue |
|------------------------------|----------------:|-------------------------------------------------|--------------------------|-------------------------|---------------------------------------|
| `accountSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `logsSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `programSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `rootSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression |
| `signatureSubscribe` pair | oui | supporté | réutiliser standard | présente | one-shot conservé |
| `slotSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression |
| `blockSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O |
| `slotsUpdatesSubscribe` pair | oui, unstable | page spécifique + overview courant = disponible | réutiliser wire standard | présente | exact wire + warning unstable |
| `voteSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O |
| `transactionSubscribe` | non standard | extension Helius | ajouter typed | présente | request/ack/notification fixtures |
| `transactionUnsubscribe` | non standard | documenté dans référence transaction | ajouter via handle | présente | exact method + late-message race |
| `tokenAccounts` | non standard | `none/balanceChanged/all` | ajouter typed | présente dans filter | enum + serialization |
| `notifyOn` account | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public |
| `notifyOn` program | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public |
| enhanced account extra | non standard | mentionné, wire exact non publié | report explicite | absente | réaudit final |
| `accountSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `logsSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `programSubscribe` pair | oui | supporté | réutiliser wire standard | présente | exact wire + no regression |
| `rootSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression |
| `signatureSubscribe` pair | oui | supporté | réutiliser standard | présente | one-shot conservé |
| `slotSubscribe` pair | oui | supporté | réutiliser standard | présente | exact wire + no regression |
| `blockSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O |
| `slotsUpdatesSubscribe` pair | oui, unstable | page spécifique + overview courant = disponible | réutiliser wire standard | présente | exact wire + warning unstable |
| `voteSubscribe` pair | oui, unstable | non supporté | ne pas exposer Helius | **absente** | API absence + guard interne avant I/O |
| `transactionSubscribe` | non standard | extension Helius | ajouter typed | présente | request/ack/notification fixtures |
| `transactionUnsubscribe` | non standard | documenté dans référence transaction | ajouter via handle | présente | exact method + late-message race |
| `tokenAccounts` | non standard | `none/balanceChanged/all` | ajouter typed | présente dans filter | enum + serialization |
| `notifyOn` account | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public |
| `notifyOn` program | non standard | deprecated, no-op Agave 4.2 | ne pas exposer | absente | absence DTO public |
| enhanced account extra | non standard | mentionné, wire exact non publié | report explicite | absente | réaudit final |
| proactive heartbeat | absent standard | 10 min idle, ping recommandé | Helius-only actor policy | interne | deterministic timer tests |
| replay historique | absent standard | pas de contrat WS KSP | interdit | absent | docs/canary no promise |
@@ -134,16 +134,16 @@ Verdict : **gate `0.2.8-pre.001` positif ; `pre.002` + `fix.001` et `pre.003` so
| Famille | `SolanaStandardWsSession` | `HeliusLaserStreamWsSession` | DTO/wire |
|--------------------|:-------------------------:|:----------------------------:|--------------------|
| Account | oui | oui | partagé standard |
| Block | oui | **non** | standard seulement |
| Logs | oui | oui | partagé standard |
| Program | oui | oui | partagé standard |
| Root | oui | oui | partagé standard |
| Signature | oui | oui | partagé standard |
| Slot | oui | oui | partagé standard |
| SlotsUpdates | oui | oui | partagé standard |
| Vote | oui | **non** | standard seulement |
| Helius Transaction | **non** | oui | provider-specific |
| Account | oui | oui | partagé standard |
| Block | oui | **non** | standard seulement |
| Logs | oui | oui | partagé standard |
| Program | oui | oui | partagé standard |
| Root | oui | oui | partagé standard |
| Signature | oui | oui | partagé standard |
| Slot | oui | oui | partagé standard |
| SlotsUpdates | oui | oui | partagé standard |
| Vote | oui | **non** | standard seulement |
| Helius Transaction | **non** | oui | provider-specific |
### 4.2 Invariants architecture

View File

@@ -1,9 +1,9 @@
<!-- file: docs/validation/012-V0_2_9_YELLOWSTONE_GRPC.md -->
<!-- version: 24 -->
<!-- version: 25 -->
# Validation `0.2.9` — Yellowstone gRPC standard + PublicNode
> **Statut courant : `pre.010-fix.001` est fermée sans warning. `pre.011` est candidate et doit prouver Config Transport V3, le mapping Config -> Yellowstone gRPC, la séparation protocol/provider et le profil PublicNode Mainnet. Ce document a été restructuré : les logs détaillés historiques vivent dans `deltas/0.2.9/`; cette matrice porte les exigences et le verdict courant.**
**Statut courant : `pre.011` est fermée par gate opérateur complet sans warning. `pre.012` est la candidate de fermeture technique : réaudit upstream, smoke PublicNode Mainnet opt-in, graphes Cargo finaux, documentation, audit des tableaux Markdown et prompt `0.2.10 — OrbitFlare Yellowstone gRPC`. Les logs historiques détaillés restent dans `deltas/0.2.9/`.**
## 1. Autorités et baseline courante
@@ -18,7 +18,7 @@ deltas/0.2.9/* pour l'historique immuable et les décisions postérieures au pro
upstream Yellowstone primaire
```
Baseline opérateur immédiatement avant `pre.011` (`0.2.9-pre.010-fix.001`) :
Baseline opérateur immédiatement avant `pre.012` (`0.2.9-pre.011`) :
| Gate | Résultat |
|------------------------------------------|--------------------------|
@@ -26,6 +26,9 @@ Baseline opérateur immédiatement avant `pre.011` (`0.2.9-pre.010-fix.001`) :
| audit Rust workspace | PASS, 0 candidate export |
| `cargo check --workspace` | PASS |
| `cargo clippy --workspace --all-targets` | PASS sans warning |
| Config unit | 113/113 PASS |
| Config public API | 15/15 PASS |
| Config ownership | 5/5 PASS |
| Transport unit | 383/383 PASS |
| Transport public API | 49/49 PASS |
| Transport release completeness | 43/43 PASS |
@@ -33,7 +36,7 @@ Baseline opérateur immédiatement avant `pre.011` (`0.2.9-pre.010-fix.001`) :
| workspace dependency canary | 3/3 PASS |
| `cargo test --workspace` | PASS |
Cette baseline est le seuil de non-régression de `pre.011` pour Transport.
Cette baseline est le seuil de non-régression de `pre.012`.
## 2. Gate dépendances et licence
@@ -47,7 +50,7 @@ Cette baseline est le seuil de non-régression de `pre.011` pour Transport.
| raw client Tonic public | aucun | **PASS** |
| graph final | réinspection `pre.012` | **PENDING FINAL** |
Le graphe n'est pas modifié par `pre.011`; aucune nouvelle dépendance Cargo n'est introduite dans cette tranche.
Le graphe de dépendances n'est pas modifié par `pre.012`; aucune nouvelle dépendance Cargo n'est introduite dans cette tranche.
## 3. Matrice service `Geyser`
@@ -215,17 +218,17 @@ state/error code safe
### 8.1 Schema et backward compatibility
Exigences candidate :
Le gate opérateur `pre.011` ferme les exigences suivantes :
| Exigence | Preuve source actuelle | Verdict avant gate opérateur |
|------------------------------------------|------------------------------------------|------------------------------|
| schema `$id` V3 | `urn:ksp:schema:std.transport:v3` | **SOURCE OK** |
| branches V1/V2 conservées | `documentV1`, `documentV2`, `documentV3` | **SOURCE OK** |
| V1 HTTP-only | fixture historique | **PENDING TEST** |
| V2 HTTP+WS | fixture historique | **PENDING TEST** |
| V3 HTTP+WS+gRPC | fixture V3 + config committée | **PENDING TEST** |
| `grpc_endpoints` optionnel par profil V3 | profiles génériques sans gRPC | **PENDING TEST** |
| no `additionalProperties` relaxation | branches strictes | **SOURCE OK** |
| Exigence | Preuve | Verdict |
|------------------------------------------|-----------------------------------------|----------|
| schema `$id` V3 | `urn:ksp:schema:std.transport:v3` | **PASS** |
| branches V1/V2 conservées | fixtures V1, V2 et document committé | **PASS** |
| V1 HTTP-only | `v1_transport_fixture...` | **PASS** |
| V2 HTTP+WS | fixture V2 + compatibilité constructeur | **PASS** |
| V3 HTTP+WS+gRPC | 113 tests Config | **PASS** |
| `grpc_endpoints` optionnel par profil V3 | profil `devnet_public` sans gRPC | **PASS** |
| propriétés inconnues refusées | branches schema strictes | **PASS** |
### 8.2 Mapping runtime
@@ -248,13 +251,13 @@ API :
|---------------------------------|-------------------------------------|---------------|
| `http_settings()` | inchangée | **OK** |
| `ws_settings()` | V1 None, V2/V3 selon profil | **OK** |
| `grpc_settings()` | V1/V2 None, V3 optionnel | **ADDED** |
| `into_transport_settings()` | tuple historique HTTP + WS inchangé | **PRESERVED** |
| `into_all_transport_settings()` | nouveau tuple HTTP + WS + gRPC | **ADDED** |
| `grpc_settings()` | V1/V2 None, V3 optionnel | **PASS** |
| `into_transport_settings()` | tuple historique HTTP + WS inchangé | **PASS** |
| `into_all_transport_settings()` | nouveau tuple HTTP + WS + gRPC | **PASS** |
### 8.3 Provenance et secrets
Règles candidate :
Règles validées :
```text
metadata publique + provenance KSP_SECRET_* -> reject
@@ -266,11 +269,11 @@ safe_value -> secret segment ********
Transport Debug -> URL/metadata secret absents
```
Le test V3 doit démontrer le cas valide et les deux croisements invalides sans exposer les canaris.
Les tests V3 démontrent le cas valide et les deux croisements invalides sans exposer les canaris.
### 8.4 PublicNode Mainnet
Profil committé attendu :
Profil committé et validé :
```text
profile_id = publicnode_mainnet
@@ -281,31 +284,32 @@ url = https://solana-yellowstone-grpc.publicnode.com:443 # provider affi
metadata = aucune
```
Le mapping doit produire un endpoint TLS Yellowstone standard et `Debug` ne doit pas exposer l'URL.
Le mapping produit un endpoint TLS Yellowstone standard ; le test `committed_v3_publicnode_mainnet_maps_provider_neutral_yellowstone_grpc` passe et `Debug` ne doit pas exposer l'URL.
### 8.5 PublicNode Testnet
Verdict `pre.011` : **DEFERRED, NOT GUESSED**.
Verdict final documentaire : **EXTERNAL BLOCK, NOT GUESSED**.
La page publique réauditée le 2026-08-24 expose une capacité Solana Testnet gRPC, mais l'hostname exact n'a pas été obtenu depuis une source suffisamment autoritative/indexable. Aucun profil Testnet n'est committé avant confirmation.
`pre.012` doit soit :
Le réaudit officiel du 2026-08-24 confirme une capacité Solana Testnet gRPC chez PublicNode, mais l'hostname exact n'a pas été obtenu depuis une source PublicNode suffisamment autoritative. Aucun profil, aucun hostname déduit et aucun smoke Testnet ne sont versionnés.
```text
confirmer hostname + réussir le smoke -> PASS
ou documenter l'impossibilité externe -> EXTERNAL BLOCK, sans endpoint inventé
capacité Testnet gRPC confirmée
hostname exact non confirmé
profil KSP absent
smoke KSP absent
raison interdiction d'inventer un endpoint provider
```
## 9. Provider-neutrality
| Point | Verdict |
|-----------------------------------------------|----------------------|
| type public `PublicNodeGrpc*` sans divergence | absent, **PASS** |
| protocol standard encodé comme provider | non, **PASS** |
| provider descriptif séparé | oui, **PASS source** |
| auth PublicNode hardcodée dans Transport | non, **PASS** |
| Helius/OrbitFlare runtime gRPC dans `0.2.9` | non, **PASS** |
| provider extensions dans N2 | aucune, **PASS** |
| Point | Verdict |
|-----------------------------------------------|------------------|
| type public `PublicNodeGrpc*` sans divergence | absent, **PASS** |
| protocol standard encodé comme provider | non, **PASS** |
| provider descriptif séparé | oui, **PASS** |
| auth PublicNode hardcodée dans Transport | non, **PASS** |
| Helius/OrbitFlare runtime gRPC dans `0.2.9` | non, **PASS** |
| provider extensions dans N2 | aucune, **PASS** |
## 10. Non-régressions obligatoires
@@ -322,7 +326,7 @@ Transport -> std::env KSP_* interdit
tracing direct Transport interdit
```
`pre.011` ne modifie pas Transport runtime ; son seuil est donc au minimum la baseline `pre.010-fix.001`.
`pre.012` ne modifie pas le runtime Transport ; elle ajoute uniquement un smoke live ignoré par défaut et de la documentation/audit. Son seuil de non-régression est la baseline `pre.011`.
## 11. Historique des gates fermé
@@ -340,84 +344,79 @@ Les détails de commandes, warnings corrigés et fichiers exacts restent dans le
| `pre.008` + `fix.001` | Blocks fermé |
| `pre.009` + `fix.001` | bidi/backpressure fermé |
| `pre.010` + `fix.001` | reconnect/replay fermé sans warning |
| `pre.011` | Config V3/PublicNode mapping fermé |
Cette table remplace les anciens appendices numérotés successivement `19.x`, `20`, `21`, etc. qui rendaient le document ambigu.
## 12. Gate opérateur `pre.011`
## 12. Gate opérateur `pre.012`
Commandes requises :
### 12.1 Preuves source déjà matérialisées
| Exigence | État candidate |
|----------------------------------------------|----------------------|
| réaudit `master` Yellowstone | **PASS SOURCE** |
| service `Geyser` et wire N2 inchangés | **PASS SOURCE** |
| licence proto Apache-2.0 toujours déclarée | **PASS SOURCE** |
| PublicNode Mainnet endpoint officiel | **PASS SOURCE** |
| PublicNode Testnet hostname exact | **EXTERNAL BLOCK** |
| smoke Mainnet programmatique sans credential | **ADDED, NOT RUN** |
| README/USAGE Yellowstone + Config V3 | **SOURCE OK** |
| règles tableaux Markdown | **ADDED** |
| audit mécanique tableaux | **ADDED** |
| prompt `0.2.10` OrbitFlare | **ADDED** |
| graphes Cargo finaux | **PENDING OPERATOR** |
| workspace final | **PENDING OPERATOR** |
Le réaudit `master` distingue explicitement le plugin courant du dernier tag GitHub indexé : `master` déclare `yellowstone-grpc-geyser 15.1.2`, `yellowstone-grpc-client 13.3.0`, `yellowstone-grpc-proto 12.6.0` et Agave `4.2.0`, alors que la page des releases indexée expose encore `v14.2.2+solana.4.1.0` comme dernière release publiée. Aucun numéro n'est fusionné artificiellement.
### 12.2 Commandes requises
```bash
cargo fmt --all
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.2.9
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-config-lib
cargo test -p ksp-config-lib --test public_api
cargo test -p ksp-config-lib --test ownership
cargo test -p ksp-onchain-transport-lib
cargo test -p ksp-core-lib --test workspace_dependencies
cargo test --workspace
```
Résultats attendus si aucun fix n'est requis :
```text
audit Rust clean / 0 export candidate
check/clippy PASS sans warning
Config unit baseline 110 + 3 nouveaux tests V3 = 113 attendus
Config public API 15 attendus, canari enrichi
Config ownership 5 attendus
Transport unit >= 383 sans régression
Transport public API >= 49 sans régression
Transport completeness >= 43 sans régression
Transport doctests 4 sans régression
workspace dependencies 3 sans régression
cargo test --workspace PASS
```
Ces nombres sont des attentes de candidate, pas un résultat déclaré avant exécution opérateur.
## 13. Gate `pre.012` et clôture stable
### 13.1 Live PublicNode
Mainnet minimal :
```text
opt-in seulement
settings Transport programmatic
aucun secret
connexion TLS
unary simple et/ou Subscribe borné selon smoke retenu
close borné
aucune dépendance Config ajoutée au test Transport pur
```
Testnet seulement après endpoint exact confirmé.
### 13.2 Compliance finale
```text
réaudit upstream release/proto
cargo tree Transport
cargo tree Transport --duplicates
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib --duplicates
cargo tree --duplicates
HTTP 52 + 14
Standard WS 18/18
Helius WS
public API crate-root
release completeness
Config V1/V2/V3
security/redaction
README/USAGE
prompt release suivante
workspace complet
```
Smoke live séparé :
```bash
cargo test -p ksp-onchain-transport-lib --test yellowstone_publicnode_smoke -- --ignored --nocapture
```
Une commande non exécutée n'est jamais déclarée réussie. Le smoke peut révéler un incident externe ; ce résultat doit être consigné sans transformer un échec réseau/provider en défaut local fictif.
## 13. Compliance finale et verdict stable
### 13.1 Inventaires à préserver
```text
HTTP current typed 52/52
HTTP historical 14/14 Deprecated/Removed
Standard WebSocket 9 familles / 18 opérations
Helius LaserStream WebSocket 7 familles standard + transaction + slotsUpdates
Yellowstone unary 7/7
Yellowstone Subscribe standard N2 + 9 updates
Config Transport V1/V2/V3 backward-readable
```
### 13.2 Documentation et règles
Le format des tableaux Markdown devient normatif dans `RULES_DOCUMENTATION.md` : aucun pipe littéral ou échappé dans une cellule, colonnes alignées sur le contenu le plus large, une seule marge d'espace autour du contenu maximal, et séparateurs dimensionnés exactement. Le canari `scripts/audit_markdown_tables.py` vérifie mécaniquement les fichiers Markdown modifiés hors blocs de code.
Le nettoyage `pre.012` a également normalisé les neuf documents modifiables qui présentaient encore des écarts connus. Le scan de préparation sur les documents KSP, crates et deltas `0.2.9` est vert sur 87 tableaux dans 116 fichiers. Les seuls écarts trouvés par un scan de tout le repository appartiennent à d'anciens deltas `0.1.4` immuables ; ils ne sont pas réécrits uniquement pour du formatage.
### 13.3 Verdict stable
`0.2.9` peut devenir stable seulement si tous les éléments suivants sont vrais :
`0.2.9` peut devenir stable lorsque le gate opérateur `pre.012` confirme tous les points locaux suivants :
```text
standard vs extension explicitement classifié
@@ -428,10 +427,14 @@ resource/backpressure/lifecycle verts
reconnect/replay sans promesse lossless
Config V3 backward V1/V2
provider/protocol distincts
PublicNode Mainnet validé ou incident externe précisément documenté
PublicNode Mainnet smoke exécuté avec résultat consigné
Testnet jamais inventé
HTTP/WS/Helius non régressés
dependency firewall vert
cargo graphs inspectés
README/USAGE finaux
prompt 0.2.10 prêt
workspace final vert
```
Le bloc Testnet n'est pas un faux FAIL local : l'existence du service est confirmée, mais l'endpoint exact reste indisponible dans la source officielle consultée. Il est donc fermé comme limite externe documentée, sans profil ni smoke inventé.