v0.2.4-pre.009

This commit is contained in:
2026-08-18 22:43:09 +02:00
parent 7e84522787
commit e6772c109d
18 changed files with 1891 additions and 49 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 140
# version: 141
[workspace]
resolver = "3"
members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib", "crates/ksp-onchain-transport-lib"]
[workspace.package]
version = "0.2.4-pre.8.fix.1"
version = "0.2.4-pre.9"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 41 -->
<!-- version: 42 -->
# Roadmap KSP
@@ -48,7 +48,7 @@ Le roadmap décrit les objectifs à atteindre et les grandes étapes prévues. U
- [X] `0.2.1`**HTTP transport foundation réduite par le gate `pre.001`** : crate/settings/JSON-RPC/registry 52 current + 14 deprecated historiques, pool/rôles/limites/retry, Config adapter, documentation et 4 méthodes typées canari (`getBalance`, `getGenesisHash`, `getHealth`, `getVersion`) publiés stables.
- [X] `0.2.2` — HTTP Accounts + Tokens + Cluster : 22 wrappers typés (5 Accounts + 5 Tokens + 12 Cluster), canaries de complétude 52+14, smoke Devnet Transport pur et smoke historique Config -> Transport validés, documentation durable et prompt `0.2.3` publiés stables.
- [X] `0.2.3` — HTTP Transactions stable : 11/11 wrappers typés publiés, classification `8 Read / 2 WriteSubmission / 1 Simulation`, no-resend ambigu prouvé pour les write submissions, `KSP-TRANSPORT-007` réaudité conforme sur les 37 wrappers HTTP courants, graphes Cargo et deux smokes Devnet validés ; `0.2.4` reprend les 15 Blocks/Economics restants.
- [/] `0.2.4` — HTTP Blocks + Economics + compliance HTTP finale en cours : `pre.001` confirme le scope exact 10 + 5, Agave stable `v4.2.1`, `KSP-TRANSPORT-007` et un gate de sizing positif avant implémentation.
- [/] `0.2.4` candidate de clôture HTTP Blocks + Economics : 15/15 wrappers `V0_2_4` implémentés, surface typed portée à 52/52 méthodes courantes, 14/14 historiques conservées, réaudit SIMD/inventaire final et `KSP-TRANSPORT-007` global préparés par `pre.009`; publication stable encore réservée à `rel.001`.
- [ ] `0.2.5` — Introduire `ksp-wallet-lib`, le format `.kspwallet`, la gestion sûre des secrets et une architecture d'import/export extensible ; exclure `WalletPolicy`.
- [ ] `0.2.6` — Introduire `ksp-app-wallet-desk` utilisant Config composite + Wallet + transport HTTP, notamment pour afficher l'identité et le solde d'un wallet.
- [ ] `0.2.7` — Étendre `ksp-onchain-transport-lib` au WebSocket Solana standard complet ; permettre plusieurs sessions sur une même URL sans imposer encore un pool automatique complexe.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/README.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# `ksp-onchain-transport-lib`
@@ -69,21 +69,19 @@ Le registre porte notamment :
- remplacement historique éventuel ;
- release de couverture typée KSP.
La release stable `0.2.3` porte la surface typée à **37 méthodes courantes** :
La candidate `0.2.4-pre.009` complète la surface typée des **52 méthodes courantes** :
```text
0.2.1 foundation : 4
0.2.2 Accounts : 5
0.2.2 Tokens : 5
0.2.2 Cluster : 12
0.2.3 Transactions : 11
0.2.1 foundation : 4
0.2.2 Accounts/Tokens/Cluster : 22
0.2.3 Transactions : 11
0.2.4 Blocks/Economics : 15
total : 52
```
Les quatre canaris foundation restent `getBalance`, `getGenesisHash`, `getHealth` et `getVersion`. `0.2.2` ajoute les 22 wrappers Accounts/Tokens/Cluster. `0.2.3` ajoute les 11 wrappers Transactions, dont `requestAirdrop` et `sendTransaction` en `WriteSubmission / NeverAfterDispatch` et `simulateTransaction` en `Simulation / RetrySafe`.
`0.2.4` ajoute les dix wrappers Blocks et les cinq wrappers Economics. Les points sensibles restent notamment `getBlock` moderne + bare encoding legacy deprecated, les quatre `transactionDetails`, les versions transaction numériques génériques, `numRewardPartitions`, `commissionBps`, les overloads de `getBlocks`, les ranges de production, les valeurs d'inflation/minimum de délégation fournies par le runtime et les `null` positionnels de `getInflationReward`.
Les **15 méthodes Blocks/Economics** encore affectées à `0.2.4` peuvent déjà passer par l'exécuteur JSON-RPC standard générique lorsqu'un consumer fournit explicitement descriptor et paramètres JSON, mais cette surface raw/générique **ne vaut pas couverture typée**.
`KSP-TRANSPORT-007` impose qu'un wrapper typé couvre toutes les possibilités RPC supportées retenues par l'audit : paramètres/options, overloads et formes legacy encore supportées, contraintes déterministes utiles et variantes de réponse pertinentes sans perte. Le réaudit `0.2.3-pre.008` confirme cette complétude sur les 37 wrappers courants.
`KSP-TRANSPORT-007` impose qu'un wrapper typé couvre toutes les possibilités RPC supportées retenues par l'audit : paramètres/options, overloads et formes legacy encore supportées, contraintes déterministes utiles et variantes de réponse pertinentes sans perte. Le réaudit final `0.2.4-pre.009` agrège le réaudit 37/37 de `0.2.3` avec les 15 nouveaux wrappers et porte la preuve candidate à **52/52**.
Les 14 méthodes historiques restent découvrables pour la compliance mais sont `Removed` et ne sont pas simulées comme appelables.
@@ -128,7 +126,9 @@ Deux smokes Devnet opt-in sont séparés par responsabilité :
```text
Transport pur : settings programmatiques -> HttpTransportPool
-> Accounts/Tokens/Cluster représentatifs
-> getLatestBlockhash/isBlockhashValid/getTransactionCount
-> trois reads Transactions
-> getBlockHeight
-> getInflationRate/getStakeMinimumDelegation
Composition historique : Config -> std.transport/devnet_public -> HttpTransportPool
-> getHealth/getGenesisHash/getVersion/getBalance
@@ -146,4 +146,6 @@ Les deux sont `ignored` par défaut. Le smoke Transport appartient durablement
- [`../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](../../docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) — matrice finale validée `0.2.2` ;
- [`../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](../../docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé de `0.2.3` ;
- [`../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](../../docs/validation/006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée `0.2.3` ;
- [`../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](../../docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan Blocks/Economics et compliance HTTP finale ;
- [`../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](../../docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice candidate `52/52 + 14/14` et audit `KSP-TRANSPORT-007` global ;
- [`../../config/std.transport.json`](../../config/std.transport.json) — configuration standard HTTP.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-onchain-transport-lib/USAGE.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Utilisation de `ksp-onchain-transport-lib`
@@ -96,7 +96,7 @@ let epoch = pool.get_epoch_info(&role, None).await;
let vote_accounts = pool.get_vote_accounts(&role, None).await;
```
La release stable `0.2.3` contient 37 wrappers typés : 4 foundation + 5 Accounts + 5 Tokens + 12 Cluster + 11 Transactions. Les DTOs Transport conservent les `null`, options et formes wire sans décodage Program/SPL métier.
La candidate `0.2.4-pre.009` contient les **52 wrappers typés courants** : 4 foundation + 22 Accounts/Tokens/Cluster + 11 Transactions + 10 Blocks + 5 Economics. Les DTOs Transport conservent les `null`, options, overloads et formes wire sans décodage Program/SPL métier.
Exemples Transaction représentatifs :
@@ -115,6 +115,16 @@ let transaction_count = pool
`getTransaction` expose la config moderne complète et une forme bare-encoding legacy séparée et deprecated. `requestAirdrop` et `sendTransaction` sont des write submissions : elles utilisent la protection centrale `NeverAfterDispatch`. `simulateTransaction` reste une simulation retry-safe et conserve son résultat riche sans introduire de décodage Program.
Exemples Blocks/Economics représentatifs :
```rust
let block_height = pool.get_block_height(&role, Some(&context)).await;
let inflation_rate = pool.get_inflation_rate(&role).await;
let stake_minimum = pool.get_stake_minimum_delegation(&role, Some(&context)).await;
```
`getBlock` possède également une forme bare-encoding legacy séparée et deprecated. Les valeurs Economics restent celles du runtime : le consumer ne doit pas supposer localement un taux d'inflation ou un minimum de délégation constant.
## 4. Exécution JSON-RPC standard générique
Une méthode courante auditée peut être appelée via son descriptor :
@@ -125,7 +135,7 @@ if let Some(descriptor) = ksp_onchain_transport_lib::find_http_rpc_method("getSl
}
```
Cette API retourne un `serde_json::Value`. Elle est utile pour les consumers techniques et pour préparer les futures surfaces typées, mais elle ne remplace pas le wrapper typé d'une méthode dans la matrice de couverture KSP.
Cette API retourne un `serde_json::Value`. Elle reste utile pour les extensions provider, les diagnostics et les méthodes hors registre standard, mais elle ne remplace jamais le wrapper typé d'une méthode HTTP standard désormais couverte par KSP.
Avant exécution, `ensure_runtime_supported()` est appliqué. Une méthode historique `Removed` retourne `ERROR_CODE_METHOD_REMOVED` au lieu d'émettre un appel réseau fictif.
@@ -172,13 +182,13 @@ La configuration standard route les événements `info` de Transport vers un fic
## 9. Smokes Devnet opt-in
Le smoke **Transport pur** construit ses settings programmatiquement et exerce un sous-ensemble représentatif de `0.2.2` puis trois reads Transactions de `0.2.3` :
Le smoke **Transport pur** construit ses settings programmatiquement et exerce un sous-ensemble représentatif d'Accounts/Tokens/Cluster, trois reads Transactions, puis des reads Blocks/Economics de la candidate `0.2.4` :
```bash
cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture
```
Il appelle `getAccountInfo`, `getTokenAccountsByOwner`, `getEpochInfo`, `getVoteAccounts`, puis `getLatestBlockhash`, `isBlockhashValid` et `getTransactionCount`. La branche Token suit la forme Devnet documentée : owner Pubkey ordinaire de l'exemple officiel, selector `programId` avec l'ID canonique du programme SPL Token, puis config explicite `commitment: finalized` + `encoding: jsonParsed`. Une réponse vide reste acceptable. La branche Transaction reste read-only : elle ne déclenche ni airdrop ni soumission de transaction et ne remplace pas les fixtures déterministes couvrant les 11 wrappers.
Il appelle `getAccountInfo`, `getTokenAccountsByOwner`, `getEpochInfo`, `getVoteAccounts`, puis `getLatestBlockhash`, `isBlockhashValid`, `getTransactionCount`, `getBlockHeight`, `getInflationRate` et `getStakeMinimumDelegation`. La branche Token suit la forme Devnet documentée : owner Pubkey ordinaire de l'exemple officiel, selector `programId` avec l'ID canonique du programme SPL Token, puis config explicite `commitment: finalized` + `encoding: jsonParsed`. Une réponse vide reste acceptable. La branche Transaction reste read-only : elle ne déclenche ni airdrop ni soumission de transaction et ne remplace pas les fixtures déterministes couvrant les 11 wrappers.
Le smoke historique de **composition Config -> Transport** reste également disponible :

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/src/lib.rs
// version: 18
// version: 19
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
@@ -12,8 +12,9 @@
//! are available. The four typed Solana HTTP foundation canaries plus all 22 typed `0.2.2` Accounts, Tokens and Cluster wrappers execute real JSON-RPC
//! requests through the shared transport path. `0.2.3` exposes its shared Transaction wire/config primitives and all eleven Transaction wrappers through
//! `pre.007`: eight reads, two write submissions with centralized no-resend protection, and retry-safe `simulateTransaction`, including complete
//! modern/legacy `getTransaction` coverage. `0.2.4-pre.002` adds the shared Blocks/Economics wire, config and result primitives. `0.2.4-pre.003`
//! activates the first five typed Blocks reads: `getBlockCommitment`, `getBlockHeight`, `getBlockTime`, `getFirstAvailableBlock` and `minimumLedgerSlot`.
//! modern/legacy `getTransaction` coverage. `0.2.4` completes the HTTP surface with all ten Blocks and five Economics wrappers, including complete
//! modern/legacy `getBlock`, positional inflation rewards, runtime-provided economics values and the final `KSP-TRANSPORT-007` compliance target.
//! The candidate surface therefore exposes typed wrappers for all 52 current audited Solana HTTP methods while retaining 14 removed historical descriptors.
mod client;
mod constants;

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/tests/public_api.rs
// version: 22
// version: 23
//! Integration tests for the public `ksp-onchain-transport-lib` consumer contract.
@@ -396,6 +396,7 @@ fn public_v0_2_4_pre_003_simple_block_wrappers_are_available_from_crate_root() {
let _minimum_ledger_slot = ksp_onchain_transport_lib::HttpTransportPool::minimum_ledger_slot;
}
#[test]
fn public_v0_2_4_pre_004_range_and_performance_wrappers_are_available_from_crate_root() {
let _get_blocks = ksp_onchain_transport_lib::HttpTransportPool::get_blocks;
@@ -405,7 +406,9 @@ fn public_v0_2_4_pre_004_range_and_performance_wrappers_are_available_from_crate
#[test]
fn public_v0_2_4_pre_005_block_production_wrapper_is_available_from_crate_root() {
let identity = "11111111111111111111111111111111".parse::<ksp_core_lib::Pubkey>().expect("public fixture identity must parse");
let identity = "11111111111111111111111111111111"
.parse::<ksp_core_lib::Pubkey>()
.expect("public fixture identity must parse");
let range = ksp_onchain_transport_lib::SolanaBlockProductionRange::new(10, std::option::Option::Some(20));
let config = ksp_onchain_transport_lib::SolanaBlockProductionConfig::new(
std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Finalized),
@@ -417,6 +420,7 @@ fn public_v0_2_4_pre_005_block_production_wrapper_is_available_from_crate_root()
let _method = ksp_onchain_transport_lib::HttpTransportPool::get_block_production;
}
#[allow(deprecated)]
#[test]
fn public_v0_2_4_pre_006_get_block_complete_request_forms_are_available_from_crate_root() {
@@ -436,6 +440,7 @@ fn public_v0_2_4_pre_006_get_block_complete_request_forms_are_available_from_cra
assert_eq!(config.rewards(), std::option::Option::Some(true));
}
#[test]
fn public_v0_2_4_pre_007_simple_economics_wrappers_are_available_from_crate_root() {
let _get_inflation_governor = ksp_onchain_transport_lib::HttpTransportPool::get_inflation_governor;
@@ -463,3 +468,62 @@ fn public_v0_2_4_pre_008_inflation_reward_wrapper_is_available_from_crate_root()
assert_eq!(config.commitment(), std::option::Option::Some(ksp_onchain_transport_lib::SolanaCommitment::Confirmed));
assert_eq!(config.min_context_slot(), std::option::Option::Some(431_000_000));
}
#[allow(deprecated)]
#[test]
fn public_v0_2_4_pre_009_all_52_current_typed_wrappers_and_legacy_forms_are_available_from_crate_root() {
let _get_account_info = ksp_onchain_transport_lib::HttpTransportPool::get_account_info;
let _get_balance = ksp_onchain_transport_lib::HttpTransportPool::get_balance;
let _get_largest_accounts = ksp_onchain_transport_lib::HttpTransportPool::get_largest_accounts;
let _get_minimum_balance_for_rent_exemption = ksp_onchain_transport_lib::HttpTransportPool::get_minimum_balance_for_rent_exemption;
let _get_multiple_accounts = ksp_onchain_transport_lib::HttpTransportPool::get_multiple_accounts;
let _get_program_accounts = ksp_onchain_transport_lib::HttpTransportPool::get_program_accounts;
let _get_token_account_balance = ksp_onchain_transport_lib::HttpTransportPool::get_token_account_balance;
let _get_token_accounts_by_delegate = ksp_onchain_transport_lib::HttpTransportPool::get_token_accounts_by_delegate;
let _get_token_accounts_by_owner = ksp_onchain_transport_lib::HttpTransportPool::get_token_accounts_by_owner;
let _get_token_largest_accounts = ksp_onchain_transport_lib::HttpTransportPool::get_token_largest_accounts;
let _get_token_supply = ksp_onchain_transport_lib::HttpTransportPool::get_token_supply;
let _get_fee_for_message = ksp_onchain_transport_lib::HttpTransportPool::get_fee_for_message;
let _get_latest_blockhash = ksp_onchain_transport_lib::HttpTransportPool::get_latest_blockhash;
let _get_recent_prioritization_fees = ksp_onchain_transport_lib::HttpTransportPool::get_recent_prioritization_fees;
let _get_signatures_for_address = ksp_onchain_transport_lib::HttpTransportPool::get_signatures_for_address;
let _get_signature_statuses = ksp_onchain_transport_lib::HttpTransportPool::get_signature_statuses;
let _get_transaction = ksp_onchain_transport_lib::HttpTransportPool::get_transaction;
let _get_transaction_count = ksp_onchain_transport_lib::HttpTransportPool::get_transaction_count;
let _is_blockhash_valid = ksp_onchain_transport_lib::HttpTransportPool::is_blockhash_valid;
let _request_airdrop = ksp_onchain_transport_lib::HttpTransportPool::request_airdrop;
let _send_transaction = ksp_onchain_transport_lib::HttpTransportPool::send_transaction;
let _simulate_transaction = ksp_onchain_transport_lib::HttpTransportPool::simulate_transaction;
let _get_block = ksp_onchain_transport_lib::HttpTransportPool::get_block;
let _get_block_commitment = ksp_onchain_transport_lib::HttpTransportPool::get_block_commitment;
let _get_block_height = ksp_onchain_transport_lib::HttpTransportPool::get_block_height;
let _get_block_production = ksp_onchain_transport_lib::HttpTransportPool::get_block_production;
let _get_blocks = ksp_onchain_transport_lib::HttpTransportPool::get_blocks;
let _get_blocks_with_limit = ksp_onchain_transport_lib::HttpTransportPool::get_blocks_with_limit;
let _get_block_time = ksp_onchain_transport_lib::HttpTransportPool::get_block_time;
let _get_first_available_block = ksp_onchain_transport_lib::HttpTransportPool::get_first_available_block;
let _get_recent_performance_samples = ksp_onchain_transport_lib::HttpTransportPool::get_recent_performance_samples;
let _minimum_ledger_slot = ksp_onchain_transport_lib::HttpTransportPool::minimum_ledger_slot;
let _get_cluster_nodes = ksp_onchain_transport_lib::HttpTransportPool::get_cluster_nodes;
let _get_epoch_info = ksp_onchain_transport_lib::HttpTransportPool::get_epoch_info;
let _get_epoch_schedule = ksp_onchain_transport_lib::HttpTransportPool::get_epoch_schedule;
let _get_genesis_hash = ksp_onchain_transport_lib::HttpTransportPool::get_genesis_hash;
let _get_health = ksp_onchain_transport_lib::HttpTransportPool::get_health;
let _get_highest_snapshot_slot = ksp_onchain_transport_lib::HttpTransportPool::get_highest_snapshot_slot;
let _get_identity = ksp_onchain_transport_lib::HttpTransportPool::get_identity;
let _get_leader_schedule = ksp_onchain_transport_lib::HttpTransportPool::get_leader_schedule;
let _get_max_retransmit_slot = ksp_onchain_transport_lib::HttpTransportPool::get_max_retransmit_slot;
let _get_max_shred_insert_slot = ksp_onchain_transport_lib::HttpTransportPool::get_max_shred_insert_slot;
let _get_slot = ksp_onchain_transport_lib::HttpTransportPool::get_slot;
let _get_slot_leader = ksp_onchain_transport_lib::HttpTransportPool::get_slot_leader;
let _get_slot_leaders = ksp_onchain_transport_lib::HttpTransportPool::get_slot_leaders;
let _get_version = ksp_onchain_transport_lib::HttpTransportPool::get_version;
let _get_vote_accounts = ksp_onchain_transport_lib::HttpTransportPool::get_vote_accounts;
let _get_inflation_governor = ksp_onchain_transport_lib::HttpTransportPool::get_inflation_governor;
let _get_inflation_rate = ksp_onchain_transport_lib::HttpTransportPool::get_inflation_rate;
let _get_inflation_reward = ksp_onchain_transport_lib::HttpTransportPool::get_inflation_reward;
let _get_stake_minimum_delegation = ksp_onchain_transport_lib::HttpTransportPool::get_stake_minimum_delegation;
let _get_supply = ksp_onchain_transport_lib::HttpTransportPool::get_supply;
let _get_block_legacy = ksp_onchain_transport_lib::HttpTransportPool::get_block_legacy;
let _get_transaction_legacy = ksp_onchain_transport_lib::HttpTransportPool::get_transaction_legacy;
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-onchain-transport-lib/tests/release_completeness.rs
// version: 20
// version: 21
//! Release-level completeness canaries for the staged HTTP wrapper sequence.
@@ -445,7 +445,13 @@ fn release_v0_2_4_descriptor_set_is_exact_and_remains_read_retry_safe_through_wr
"getRecentPerformanceSamples",
"minimumLedgerSlot",
];
let mut expected_economics = std::vec!["getInflationGovernor", "getInflationRate", "getInflationReward", "getStakeMinimumDelegation", "getSupply",];
let mut expected_economics = std::vec![
"getInflationGovernor",
"getInflationRate",
"getInflationReward",
"getStakeMinimumDelegation",
"getSupply",
];
let mut actual_blocks = std::vec::Vec::new();
let mut actual_economics = std::vec::Vec::new();
for descriptor in ksp_onchain_transport_lib::current_http_rpc_methods() {
@@ -497,6 +503,7 @@ fn release_v0_2_4_pre_003_simple_blocks_subset_is_exact_and_retry_safe() {
assert_eq!(actual.len(), 5);
}
#[test]
fn release_v0_2_4_pre_004_range_performance_subset_is_exact_and_retry_safe() {
let mut expected = std::vec!["getBlocks", "getBlocksWithLimit", "getRecentPerformanceSamples"];
@@ -531,6 +538,7 @@ fn release_v0_2_4_pre_005_block_production_subset_is_exact_and_retry_safe() {
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
}
#[test]
fn release_v0_2_4_pre_006_get_block_completes_all_ten_block_wrappers_with_legacy_marker() {
let expected = std::vec![
@@ -564,6 +572,7 @@ fn release_v0_2_4_pre_006_get_block_completes_all_ten_block_wrappers_with_legacy
assert!(get_block.request_form_status().has_deprecated_legacy());
}
#[test]
fn release_v0_2_4_pre_007_simple_economics_subset_is_exact_and_retry_safe() {
let mut expected = std::vec!["getInflationGovernor", "getInflationRate", "getStakeMinimumDelegation", "getSupply"];
@@ -608,3 +617,128 @@ fn release_v0_2_4_pre_008_completes_all_five_economics_wrappers_exactly_and_retr
assert_eq!(actual, expected);
assert_eq!(actual.len(), 5);
}
#[test]
fn release_v0_2_4_pre_009_final_http_inventory_and_coverage_partition_are_exact() {
let expected_current = std::vec![
"getAccountInfo",
"getBalance",
"getBlock",
"getBlockCommitment",
"getBlockHeight",
"getBlockProduction",
"getBlocks",
"getBlocksWithLimit",
"getBlockTime",
"getClusterNodes",
"getEpochInfo",
"getEpochSchedule",
"getFeeForMessage",
"getFirstAvailableBlock",
"getGenesisHash",
"getHealth",
"getHighestSnapshotSlot",
"getIdentity",
"getInflationGovernor",
"getInflationRate",
"getInflationReward",
"getLargestAccounts",
"getLatestBlockhash",
"getLeaderSchedule",
"getMaxRetransmitSlot",
"getMaxShredInsertSlot",
"getMinimumBalanceForRentExemption",
"getMultipleAccounts",
"getProgramAccounts",
"getRecentPerformanceSamples",
"getRecentPrioritizationFees",
"getSignaturesForAddress",
"getSignatureStatuses",
"getSlot",
"getSlotLeader",
"getSlotLeaders",
"getStakeMinimumDelegation",
"getSupply",
"getTokenAccountBalance",
"getTokenAccountsByDelegate",
"getTokenAccountsByOwner",
"getTokenLargestAccounts",
"getTokenSupply",
"getTransaction",
"getTransactionCount",
"getVersion",
"getVoteAccounts",
"isBlockhashValid",
"minimumLedgerSlot",
"requestAirdrop",
"sendTransaction",
"simulateTransaction",
];
let expected_historical = std::vec![
"confirmTransaction",
"getConfirmedBlock",
"getConfirmedBlocks",
"getConfirmedBlocksWithLimit",
"getConfirmedSignaturesForAddress2",
"getConfirmedTransaction",
"getFeeCalculatorForBlockhash",
"getFeeRateGovernor",
"getFees",
"getRecentBlockhash",
"getSignatureConfirmation",
"getSignatureStatus",
"getSnapshotSlot",
"getStakeActivation",
];
let current = ksp_onchain_transport_lib::current_http_rpc_methods();
let historical = ksp_onchain_transport_lib::historical_http_rpc_methods();
let mut actual_current = std::vec::Vec::with_capacity(current.len());
let mut actual_historical = std::vec::Vec::with_capacity(historical.len());
let mut v0_2_1 = 0_usize;
let mut v0_2_2 = 0_usize;
let mut v0_2_3 = 0_usize;
let mut v0_2_4 = 0_usize;
let mut historical_current = 0_usize;
for descriptor in current {
actual_current.push(descriptor.method());
assert_eq!(descriptor.runtime_status(), ksp_onchain_transport_lib::RpcRuntimeStatus::Supported);
assert_ne!(descriptor.documentation_status(), ksp_onchain_transport_lib::RpcDocumentationStatus::Deprecated);
match descriptor.coverage_release() {
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_1 => v0_2_1 += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_2 => v0_2_2 += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_3 => v0_2_3 += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::V0_2_4 => v0_2_4 += 1,
ksp_onchain_transport_lib::HttpRpcCoverageRelease::Historical => historical_current += 1,
}
match descriptor.operation_kind() {
ksp_onchain_transport_lib::RpcOperationKind::Read | ksp_onchain_transport_lib::RpcOperationKind::Simulation => {
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::RetrySafe);
},
ksp_onchain_transport_lib::RpcOperationKind::WriteSubmission => {
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::NeverAfterDispatch);
},
}
}
for descriptor in historical {
actual_historical.push(descriptor.method());
assert_eq!(descriptor.documentation_status(), ksp_onchain_transport_lib::RpcDocumentationStatus::Deprecated);
assert_eq!(descriptor.runtime_status(), ksp_onchain_transport_lib::RpcRuntimeStatus::Removed);
assert_eq!(descriptor.coverage_release(), ksp_onchain_transport_lib::HttpRpcCoverageRelease::Historical);
assert_eq!(descriptor.transport_retry_class(), ksp_onchain_transport_lib::TransportRetryClass::NotApplicable);
}
actual_current.sort_unstable();
actual_historical.sort_unstable();
let mut expected_current = expected_current;
let mut expected_historical = expected_historical;
expected_current.sort_unstable();
expected_historical.sort_unstable();
assert_eq!(actual_current, expected_current);
assert_eq!(actual_historical, expected_historical);
assert_eq!(actual_current.len(), 52);
assert_eq!(actual_historical.len(), 14);
assert_eq!((v0_2_1, v0_2_2, v0_2_3, v0_2_4), (4, 22, 11, 15));
assert_eq!(historical_current, 0);
}

View File

@@ -1,7 +1,7 @@
// file: crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs
// version: 4
// version: 5
//! Opt-in live Devnet smoke for representative pure Transport Accounts/Tokens/Cluster/Transactions reads.
//! Opt-in live Devnet smoke for representative pure Transport reads across the complete HTTP typed surface.
fn devnet_pool() -> ksp_core_lib::Result<ksp_onchain_transport_lib::HttpTransportPool> {
let role = ksp_onchain_transport_lib::HttpRoleName::new("default");
@@ -42,7 +42,7 @@ fn devnet_pool() -> ksp_core_lib::Result<ksp_onchain_transport_lib::HttpTranspor
#[tokio::test(flavor = "current_thread")]
#[ignore = "opt-in live Solana Devnet smoke; performs external network requests"]
async fn programmatic_devnet_transport_reaches_accounts_tokens_cluster_and_transaction_read_wrappers() {
async fn programmatic_devnet_transport_reaches_accounts_tokens_cluster_transactions_blocks_and_economics_reads() {
let pool = devnet_pool().expect("programmatic Devnet Transport settings must construct a pool");
let role = ksp_onchain_transport_lib::HttpRoleName::new("default");
@@ -117,4 +117,22 @@ async fn programmatic_devnet_transport_reaches_accounts_tokens_cluster_and_trans
.await
.expect("Devnet getTransactionCount smoke must succeed");
assert!(transaction_count > 0);
let block_height = pool
.get_block_height(&role, std::option::Option::Some(&transaction_context))
.await
.expect("Devnet getBlockHeight smoke must succeed");
assert!(block_height > 0);
let inflation_rate = pool.get_inflation_rate(&role).await.expect("Devnet getInflationRate smoke must succeed");
assert!(inflation_rate.total().is_finite());
assert!(inflation_rate.validator().is_finite());
assert!(inflation_rate.foundation().is_finite());
let stake_minimum_delegation = pool
.get_stake_minimum_delegation(&role, std::option::Option::Some(&transaction_context))
.await
.expect("Devnet getStakeMinimumDelegation smoke must succeed");
assert!(stake_minimum_delegation.context().slot() > 0);
assert!(*stake_minimum_delegation.value() > 0);
}

402
deltas/0.2.4/pre.009.md Normal file
View File

@@ -0,0 +1,402 @@
<!-- file: deltas/0.2.4/pre.009.md -->
<!-- version: 1 -->
# Delta `0.2.4-pre.009` — clôture HTTP finale, compliance `52/52 + 14/14` et préparation Wallet
## Base requise
Livraison précédente validée :
```text
0.2.4-pre.008-fix.001
workspace.package.version = "0.2.4-pre.8.fix.1"
```
La validation locale fournie pour cette base est entièrement propre :
```text
cargo fmt --all -> terminé
cargo check --workspace -> terminé sans warning
cargo clippy --workspace --all-targets -> terminé sans warning
cargo test -p ksp-onchain-transport-lib -> 240 unit tests OK
26 public API tests OK
21 release-completeness tests OK
1 smoke Devnet ignoré comme prévu
0 échec
```
Cette base inclut donc le fix purement Clippy de `pre.008-fix.001` sans modification fonctionnelle de `getInflationReward`.
## Objectif
`pre.009` est la prerelease de clôture de la série HTTP commencée en `0.2.1`.
Elle ne doit ajouter aucun nouveau comportement RPC standard. Elle doit au contraire prouver et documenter que la surface acquise est complète et cohérente :
```text
52 méthodes HTTP courantes officielles
52 wrappers typed KSP correspondants
14 méthodes historiques Deprecated / runtime Removed
14 descriptors historiques KSP correspondants
partition typed : 4 foundation + 22 Accounts/Tokens/Cluster + 11 Transactions + 15 Blocks/Economics
```
Elle doit également :
- réauditer la référence HTTP officielle et les SIMDs susceptibles de modifier cette surface ;
- figer les canaries finales de présence, de classification et de frontières ;
- étendre le smoke Transport pur aux nouvelles familles Blocks/Economics ;
- publier le document de conformité final `0.2.4` ;
- mettre à jour les documents vivants de la série ;
- fournir le prompt de démarrage de `0.2.5 — Wallet foundation` ;
- préparer `rel.001`, qui devra rester strictement publicationnel.
## Version Cargo
Nouvelle prerelease technique :
```text
0.2.4-pre.8.fix.1 -> 0.2.4-pre.9
```
Aucune dépendance, feature Cargo ou frontière de crate n'est modifiée.
## Réaudit officiel final de la surface HTTP
Le réaudit de la référence Solana HTTP courante retrouve exactement les `52` méthodes enregistrées par KSP.
La comparaison est effectuée sur les noms, pas seulement sur un compteur :
```text
officiel courant - registre KSP = {}
registre KSP - officiel courant = {}
```
Les `14` méthodes historiques présentées dans la navigation Deprecated officielle correspondent également exactement au registre historique KSP :
```text
officiel Deprecated - historique KSP = {}
historique KSP - officiel Deprecated = {}
```
Aucun nouveau RPC HTTP standard n'est donc introduit dans la release à cette date.
La baseline runtime de contrat utilisée pendant `0.2.4` reste :
```text
Agave v4.2.1
```
La rollout Agave `v4.2` est en cours pendant cette clôture ; cette prerelease ne transforme pas un calendrier de déploiement en affirmation d'activation cluster-wide.
## Réaudit SIMD final
Les statuts upstream observés pendant la clôture sont :
| SIMD | Sujet lié au HTTP KSP | Statut courant | Conséquence pour `0.2.4` |
|--------|---------------------------------------------|---------------------|---------------------------------------------------------------------------|
| `0180` | leader schedule keyed by vote account | `Review` | aucune nouvelle méthode HTTP officielle ; conserver le wire stable audité |
| `0298` | `bank_hash` dans le block footer | `Idea` | ne pas ajouter `bankHash` spéculativement |
| `0301` | remplacement proposé par `parent_bank_hash` | PR fermé, non mergé | aucune surface KSP |
| `0307` | block footer + extension `getBlock` | `Review` | pas de `footer` dans le contrat stable `v4.2.1` |
| `0385` | transaction V1 | `Review` | conserver `SolanaTransactionVersion::Number(u8)` générique |
| `0490` | Stake Program v5 / minimum delegation | `Review` | valeur fournie par le runtime, jamais codée en dur |
| `0550` | double disinflation | `Review` | valeurs inflation runtime, aucune formule KSP |
| `0553` | base inclusion + resource fee | `Draft` | évolution économique/fee ; aucun nouveau wrapper HTTP stable |
Les extensions wire déjà acquises sont également réauditées pour éviter qu'une clôture centrée sur la watchlist n'en perde une :
| SIMD | Statut courant | Contrat KSP confirmé |
|-----------------------------------------------|----------------|----------------------------------------------------------------------------------------------------------|
| `0118` Partitioned Epoch Rewards Distribution | `Activated` | `numRewardPartitions` reste lossless en omitted/null/value ; aucune synthèse locale |
| `0291` Commission Rate in Basis Points | `Review` | `commission` et `commissionBps` restent indépendants dans les rewards ; aucun calcul de conversion local |
Le statut `Review` de SIMD-0291 ne retire pas le wire déjà livré par Agave `v4.2.1`. Le réaudit ne justifie donc aucune extension wire spéculative dans `pre.009` ni aucune suppression d'un champ stable déjà acquis.
## Canarie public API finale
`tests/public_api.rs` ajoute :
```text
public_v0_2_4_pre_009_all_52_current_typed_wrappers_and_legacy_forms_are_available_from_crate_root
```
Cette canarie référence les `52` wrappers typed des méthodes courantes via `HttpTransportPool`.
Elle référence aussi séparément les deux formes legacy de requête qui ne constituent pas des méthodes RPC supplémentaires :
```text
get_block_legacy
get_transaction_legacy
```
Le but est de détecter immédiatement une suppression ou une invisibilité accidentelle d'un wrapper public pendant les futures refactorisations.
## Canarie release-completeness finale
`tests/release_completeness.rs` ajoute :
```text
release_v0_2_4_pre_009_final_http_inventory_and_coverage_partition_are_exact
```
Elle fige explicitement :
```text
52 noms courants exacts
14 noms historiques exacts
4 méthodes Foundation
22 méthodes V0_2_2
11 méthodes V0_2_3
15 méthodes V0_2_4
```
Elle vérifie également les invariants de classification :
```text
courant -> runtime Supported, documentation non Deprecated
Read -> RetrySafe
Simulation -> RetrySafe
WriteSubmission -> NeverAfterDispatch
historique -> Deprecated + Removed + Historical + NotApplicable
```
Cette preuve complète les canaries `KSP-TRANSPORT-007` déjà acquises ; elle ne les remplace pas.
## Compliance `KSP-TRANSPORT-007`
Le document final :
```text
docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
```
consolide la preuve `52/52` et les points sensibles accumulés depuis `0.2.1` :
- ordre et cardinalité des paramètres/réponses ;
- configs omises versus objets explicitement présents ;
- overloads modernes et historiques ;
- validations déterministes avant I/O ;
- préservation `omitted / null / value` ;
- listes positionnelles et ordre provider ;
- `getBlock` moderne + bare encoding legacy ;
- `transactionDetails` complet ;
- SIMD-0118 `numRewardPartitions` ;
- SIMD-0291 `commissionBps` ;
- version transaction numérique non nulle ;
- Economics runtime sans constantes locales inventées ;
- `getInflationReward` positionnel et cardinalité stricte.
## Smoke Transport pur final
Le smoke opt-in :
```text
crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs
```
reste :
- purement Transport ;
- settings construits programmatiquement ;
- read-only ;
- opt-in / ignoré par défaut ;
- indépendant de Config.
Il conserve les appels déjà présents Accounts/Tokens/Cluster/Transactions et ajoute trois appels peu fragiles :
```text
getBlockHeight(finalized)
getInflationRate()
getStakeMinimumDelegation(finalized)
```
Aucune valeur économique exacte n'est codée en dur. Le smoke vérifie uniquement des invariants de santé de réponse.
Le smoke de composition `Config -> Transport -> Devnet` reste une exception transitoire dans `ksp-config-lib` et doit toujours migrer vers une future surface dédiée d'intégration/orchestration/demo.
## Documentation finale `0.2.4`
Sont mis à jour :
```text
ROADMAP.md
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
docs/000-README.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/plans/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md
docs/validation/000-README.md
prompts/000-README.md
```
Le plan `011` passe en version `6` et enregistre le réaudit final sans modifier les contrats RPC déjà matérialisés.
Le raw RPC est désormais décrit comme une surface d'extension provider/diagnostic hors registre standard ; il ne constitue pas une alternative aux `52` wrappers typed standard.
`CHANGELOG.md` reste volontairement inchangé dans cette prerelease : la publication stable et son entrée finale appartiennent à `rel.001`.
## Document de validation final
Ajout :
```text
docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
```
Ce document sert de point de contrôle avant `rel.001`. Il contient notamment :
- le réaudit officiel `52 + 14` ;
- la matrice des `52` méthodes courantes ;
- la matrice des `14` historiques ;
- la partition `4 / 22 / 11 / 15` ;
- le réaudit SIMD ;
- les contrats sensibles Blocks/Economics ;
- les commandes de validation immédiate et finale ;
- les audits `cargo tree` de frontières ;
- les deux smokes Devnet opt-in ;
- les conditions de passage à `rel.001`.
## Prompt `0.2.5 — Wallet foundation`
Ajout :
```text
prompts/010-V0_2_5_START_PROMPT.md
```
Le prompt impose une `0.2.5-pre.001` d'audit + brainstorming + sizing avant toute implémentation cryptographique lourde.
Il cadre notamment :
```text
ksp-wallet-lib
format natif versionné .kspwallet
Wallet -> Core/Logging + primitives crypto/key low-level seulement
Wallet -X-> Config/Transport/Store/Tauri/ExecutionPolicy
pas de crypto maison
pas de secret dans Config
pas de WalletPolicy dans 0.2.5
pas de Wallet Desk dans 0.2.5
```
La sélection du KDF, de l'AEAD, du CSPRNG et de la stratégie de secret en mémoire n'est pas préjugée : elle doit être auditée contre les primitives actuelles lors de `pre.001`.
Le prompt exige également les invariants de sécurité principaux : mauvais mot de passe, tampering, format inconnu/tronqué, redaction, absence de secret en clair, changement de mot de passe sans changement de keypair, persistence atomique/no-clobber et signature vérifiable.
## Fichiers modifiés
```text
Cargo.toml
ROADMAP.md
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-onchain-transport-lib/src/lib.rs
crates/ksp-onchain-transport-lib/tests/public_api.rs
crates/ksp-onchain-transport-lib/tests/release_completeness.rs
crates/ksp-onchain-transport-lib/tests/transport_devnet_smoke.rs
docs/000-README.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/plans/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md
docs/validation/000-README.md
prompts/000-README.md
```
## Fichiers ajoutés
```text
docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
prompts/010-V0_2_5_START_PROMPT.md
deltas/0.2.4/pre.009.md
```
Aucun fichier n'est supprimé.
## Validation immédiate attendue
Après application de l'overlay :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
```
Compte attendu pour Transport :
```text
240 unit tests OK
27 public API tests OK
22 release-completeness tests OK
1 smoke Devnet ignoré comme prévu
0 échec
```
Le nombre de unit tests reste volontairement stable : `pre.009` ajoute des canaries d'intégration/public API et non une nouvelle logique RPC.
## Checkpoint final avant `rel.001`
Une fois la validation immédiate propre, exécuter aussi :
```bash
cargo test -p ksp-config-lib
cargo test -p ksp-core-lib
cargo test -p ksp-app-config-desk
cargo test --workspace
```
Audits de graphes :
```bash
cargo tree -p ksp-onchain-transport-lib -i ksp-config-lib
cargo tree -p ksp-onchain-transport-lib -i ksp-store-lib
cargo tree -p ksp-onchain-transport-lib -i ksp-program-lib
cargo tree -p ksp-onchain-transport-lib -i tracing
cargo tree -p ksp-config-lib -i ksp-onchain-transport-lib
cargo tree -p ksp-config-lib -i tracing
cargo tree -p ksp-onchain-transport-lib | grep -E 'solana-(client|rpc-client|rpc-client-api)'
cargo tree -p ksp-onchain-transport-lib | grep -E 'ksp-(config|store|program)'
```
Les commandes `cargo tree -i` qui signalent qu'un package n'existe pas dans le graphe sont acceptables lorsqu'elles démontrent précisément l'absence de dépendance recherchée ; le résultat doit être interprété et consigné, pas masqué. Pour `tracing`, une présence transitive sous `ksp-logging-lib` est conforme : l'interdit architectural porte sur une dépendance **directe** de Transport vers `tracing`, pas sur l'absence totale de `tracing` dans son graphe transitif.
Smokes réseau opt-in :
```bash
cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture
cargo test -p ksp-config-lib --test transport_devnet_smoke -- --ignored --nocapture
```
Le premier est le smoke Transport pur durable. Le second reste la composition transitoire `Config -> Transport` déjà documentée.
## Commit attendu
Après validation immédiate et checkpoint final propres :
```text
v0.2.4-pre.009
```
## Suite — `rel.001`
La livraison suivante doit être :
```text
0.2.4-rel.001
```
Elle doit être strictement publicationnelle :
- finaliser `CHANGELOG.md` et les statuts ROADMAP/documents de publication ;
- produire `deltas/0.2.4/rel.001.md` ;
- passer `workspace.package.version` de la prerelease candidate à `0.2.4` ;
- ne pas ajouter de wrapper, DTO, validation RPC ou comportement réseau ;
- rejouer les contrôles de publication nécessaires ;
- créer le tag stable `v0.2.4` après validation et commit de la release.
`0.2.5` ne commence qu'après cette publication stable.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/000-README.md -->
<!-- version: 31 -->
<!-- version: 32 -->
# Documentation KSP
@@ -51,7 +51,8 @@ docs/
│ ├── 003-V0_2_1_ONCHAIN_HTTP.md
│ ├── 004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md
│ ├── 005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md
── 006-V0_2_3_HTTP_TRANSACTIONS.md
── 006-V0_2_3_HTTP_TRANSACTIONS.md
│ └── 007-V0_2_4_HTTP_FINAL_COMPLIANCE.md
└── rules/
├── FILE_CONTRACTS.md
├── PROMPT_STRUCTURE.md
@@ -68,7 +69,7 @@ D'autres sous-répertoires seront ajoutés uniquement lorsque leur rôle aura é
## Documents de planification
Le plan historique de la phase fondatrice clôturée est conservé dans [`plans/001-V0_0_3_PLAN.md`](plans/001-V0_0_3_PLAN.md). La séquence active des premières releases fonctionnelles est définie dans [`plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`](plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md). Le plan détaillé de la release stable `0.1.1` est conservé comme historique clôturé dans [`plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md`](plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.2` est conservé comme historique clôturé dans [`plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md`](plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.3 — Configuration foundation` est conservé comme historique clôturé dans [`plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.4 — ksp-app-config-desk` est conservé comme historique clôturé dans [`plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md`](plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md), avec sa matrice finale [`validation/001-V0_1_4_CONFIG_DESKTOP.md`](validation/001-V0_1_4_CONFIG_DESKTOP.md). Son prompt d'ouverture historique reste [`../prompts/004-V0_1_4_START_PROMPT.md`](../prompts/004-V0_1_4_START_PROMPT.md). La release stable `0.2.0` clôt l'audit de bot3 et le découpage de la série. Son plan directeur est conservé comme historique clôturé dans [`plans/007-V0_2_0_SERIES_PLANNING.md`](plans/007-V0_2_0_SERIES_PLANNING.md), avec sa matrice finale [`validation/002-V0_2_0_SERIES_PLANNING.md`](validation/002-V0_2_0_SERIES_PLANNING.md). La release stable `0.2.1 — HTTP Solana foundation` a été ouverte par [`../prompts/006-V0_2_1_START_PROMPT.md`](../prompts/006-V0_2_1_START_PROMPT.md). Son gate de sizing et sa matrice exhaustive sont conservés dans [`plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md), avec la validation finale [`validation/003-V0_2_1_ONCHAIN_HTTP.md`](validation/003-V0_2_1_ONCHAIN_HTTP.md), README/USAGE Transport et le smoke Devnet opt-in de composition Config -> Transport. Le prompt [`../prompts/007-V0_2_2_START_PROMPT.md`](../prompts/007-V0_2_2_START_PROMPT.md) a ouvert la release stable `0.2.2 — HTTP Accounts + Tokens + Cluster`. Son plan clôturé [`plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) conserve l'audit et l'implémentation des 22 wrappers typés, tandis que [`validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) enregistre les validations déterministes, les graphes Cargo et les deux smokes Devnet passés avant publication. Le prompt [`../prompts/008-V0_2_3_START_PROMPT.md`](../prompts/008-V0_2_3_START_PROMPT.md) a ouvert la release stable `0.2.3 — HTTP Transactions`. Son plan clôturé [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) conserve l'audit et l'implémentation des 11 wrappers ; le réaudit [`validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) confirme la complétude des 37 wrappers HTTP typés et [`validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](validation/006-V0_2_3_HTTP_TRANSACTIONS.md) enregistre les validations finales, graphes Cargo et deux smokes Devnet passés avant publication. Le prompt [`../prompts/009-V0_2_4_START_PROMPT.md`](../prompts/009-V0_2_4_START_PROMPT.md) ouvre `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`. Son plan actif [`plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md), établi par `0.2.4-pre.001`, fixe les 15 wrappers restants, la baseline Agave stable `v4.2.1`, le gate de sizing positif et la compliance finale `52/52 + 14/14`.
Le plan historique de la phase fondatrice clôturée est conservé dans [`plans/001-V0_0_3_PLAN.md`](plans/001-V0_0_3_PLAN.md). La séquence active des premières releases fonctionnelles est définie dans [`plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`](plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md). Le plan détaillé de la release stable `0.1.1` est conservé comme historique clôturé dans [`plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md`](plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.2` est conservé comme historique clôturé dans [`plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md`](plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.3 — Configuration foundation` est conservé comme historique clôturé dans [`plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.4 — ksp-app-config-desk` est conservé comme historique clôturé dans [`plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md`](plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md), avec sa matrice finale [`validation/001-V0_1_4_CONFIG_DESKTOP.md`](validation/001-V0_1_4_CONFIG_DESKTOP.md). Son prompt d'ouverture historique reste [`../prompts/004-V0_1_4_START_PROMPT.md`](../prompts/004-V0_1_4_START_PROMPT.md). La release stable `0.2.0` clôt l'audit de bot3 et le découpage de la série. Son plan directeur est conservé comme historique clôturé dans [`plans/007-V0_2_0_SERIES_PLANNING.md`](plans/007-V0_2_0_SERIES_PLANNING.md), avec sa matrice finale [`validation/002-V0_2_0_SERIES_PLANNING.md`](validation/002-V0_2_0_SERIES_PLANNING.md). La release stable `0.2.1 — HTTP Solana foundation` a été ouverte par [`../prompts/006-V0_2_1_START_PROMPT.md`](../prompts/006-V0_2_1_START_PROMPT.md). Son gate de sizing et sa matrice exhaustive sont conservés dans [`plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md), avec la validation finale [`validation/003-V0_2_1_ONCHAIN_HTTP.md`](validation/003-V0_2_1_ONCHAIN_HTTP.md), README/USAGE Transport et le smoke Devnet opt-in de composition Config -> Transport. Le prompt [`../prompts/007-V0_2_2_START_PROMPT.md`](../prompts/007-V0_2_2_START_PROMPT.md) a ouvert la release stable `0.2.2 — HTTP Accounts + Tokens + Cluster`. Son plan clôturé [`plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) conserve l'audit et l'implémentation des 22 wrappers typés, tandis que [`validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) enregistre les validations déterministes, les graphes Cargo et les deux smokes Devnet passés avant publication. Le prompt [`../prompts/008-V0_2_3_START_PROMPT.md`](../prompts/008-V0_2_3_START_PROMPT.md) a ouvert la release stable `0.2.3 — HTTP Transactions`. Son plan clôturé [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) conserve l'audit et l'implémentation des 11 wrappers ; le réaudit [`validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) confirme la complétude des 37 wrappers HTTP typés et [`validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](validation/006-V0_2_3_HTTP_TRANSACTIONS.md) enregistre les validations finales, graphes Cargo et deux smokes Devnet passés avant publication. Le prompt [`../prompts/009-V0_2_4_START_PROMPT.md`](../prompts/009-V0_2_4_START_PROMPT.md) ouvre `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`. Son plan [`plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md), établi par `0.2.4-pre.001`, est amené en candidate par `pre.009` après implémentation des 15 wrappers et compliance `52/52 + 14/14`; la matrice [`validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) porte la preuve finale candidate. Le prompt [`../prompts/010-V0_2_5_START_PROMPT.md`](../prompts/010-V0_2_5_START_PROMPT.md) prépare `0.2.5 — Wallet foundation` après publication stable de `0.2.4`.
`IDEAS.md` conserve les pistes et questions qui ne sont pas encore des engagements du roadmap ni des décisions architecturales.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
<!-- version: 12 -->
<!-- version: 13 -->
# Inventaire initial des composants KSP
@@ -23,7 +23,7 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse
| Logging | `ksp-logging-lib` | lib | Stable | `0.1.2` | façade unique tracing KSP |
| Config | `ksp-config-lib` | lib | Stable | `0.1.3` | documents, profils, env et persistence Config |
| Config Desk | `ksp-app-config-desk` | app | Stable | `0.1.4` | validation/management Config |
| On-chain HTTP | `ksp-onchain-transport-lib` | lib | Stable | `0.2.1` | foundation HTTP + 37 wrappers typés stables après 0.2.3 |
| On-chain HTTP | `ksp-onchain-transport-lib` | lib | Stable | `0.2.1` | foundation stable + candidate HTTP typed 52/52 en 0.2.4 |
| Wallet | `ksp-wallet-lib` | lib | Retenu | `0.2.5` | `.kspwallet`, secrets, signature, import/export |
| Wallet Desk | `ksp-app-wallet-desk` | app | Retenu | `0.2.6` | Wallet + Config composite + HTTP/balance |
| Standard WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.7` | WebSocket Solana complet, sessions/subscriptions |
@@ -78,7 +78,7 @@ ksp-data-api
## Transport
`ksp-onchain-transport-lib` doit couvrir l'intégralité des opérations documentées de la surface ciblée par chaque release. `0.2.1` stabilise la foundation HTTP et quatre wrappers typés canari. `0.2.2` stabilise 22 wrappers Accounts/Tokens/Cluster supplémentaires. `0.2.3` stabilise les 11 Transactions et porte la surface typed à 37 méthodes ; les 15 méthodes Blocks/Economics restent affectées à `0.2.4`, qui exécutera aussi la compliance finale de la surface 52 current + 14 historiques. Les statuts deprecated/obsolete encore fonctionnels et unstable/experimental restent exposés avec warning runtime KSP.
`ksp-onchain-transport-lib` doit couvrir l'intégralité des opérations documentées de la surface ciblée par chaque release. `0.2.1` stabilise la foundation HTTP et quatre wrappers typés canari, `0.2.2` ajoute 22 wrappers Accounts/Tokens/Cluster et `0.2.3` stabilise les 11 Transactions. La candidate `0.2.4-pre.009` ajoute les 10 Blocks + 5 Economics et atteint 52/52 méthodes HTTP courantes typées, avec 14/14 historiques Deprecated/Removed conservées pour compliance. Les statuts deprecated/obsolete encore fonctionnels et unstable/experimental restent exposés avec warning runtime KSP.
La Config standard Transport appartient à `ksp-config-lib`, qui adapte vers les settings publics du transport ; le transport ne dépend jamais de Config.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/000-README.md -->
<!-- version: 38 -->
<!-- version: 39 -->
# Plans KSP
@@ -19,7 +19,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
- [`008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](008-V0_2_1_ONCHAIN_HTTP_PLAN.md) — plan de `0.2.1`, établi par `0.2.1-pre.001`, recalibré par `pre.001-fix.001` et amené en clôture candidate par `pre.007`; il conserve l'inventaire 52 méthodes HTTP courantes + 14 Deprecated historiques, le design Transport/Config et le split de couverture typée sur `0.2.1``0.2.4`.
- [`009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) — plan clôturé de la release stable `0.2.2`, établi par `pre.001`, corrigé après réaudit Agave v4.2.1 puis exécuté jusqu'à `pre.007-fix.002`; il couvre les 22 wrappers Accounts/Tokens/Cluster, le smoke Transport opt-in et la préparation de `0.2.3`.
- [`010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) — plan historique clôturé de la release stable `0.2.3 — HTTP Transactions`, ouvert par `pre.001`, exécuté jusqu'à `pre.009` puis publié par `rel.001`; il couvre les 11 méthodes, la classification `8 Read / 2 WriteSubmission / 1 Simulation`, `KSP-TRANSPORT-007`, le no-resend et la préparation de `0.2.4`.
- [`011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan actif de `0.2.4`, ouvert par `pre.001`; il fixe les 10 Blocks + 5 Economics, les overloads/legacy, les wires réutilisables, les limites runtime et la compliance finale `52/52 + 14/14` sous `KSP-TRANSPORT-007`.
- [`011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) — plan de `0.2.4`, ouvert par `pre.001` et amené en clôture candidate par `pre.009`; il couvre les 10 Blocks + 5 Economics, les overloads/legacy, les wires/runtime sensibles et la compliance finale `52/52 + 14/14` sous `KSP-TRANSPORT-007`.
Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 40 -->
<!-- version: 41 -->
# Séquence des releases fonctionnelles KSP
@@ -394,7 +394,7 @@ Chaque `pre.001` réaudite la documentation officielle actuelle. Les méthodes D
`0.2.3-pre.001` réaudite le 2026-08-18 la catégorie Transactions contre la documentation Solana actuelle et Agave v4.2.1 : les 11 méthodes prévues restent exactes, la classification `8 Read / RetrySafe`, `2 WriteSubmission / NeverAfterDispatch` et `1 Simulation / RetrySafe` reste correcte, et le gate de sizing est positif. `pre.002``pre.007` livrent ensuite les primitives wire puis les 11 wrappers, `pre.008` réaudite rétroactivement `KSP-TRANSPORT-007` sur les 37 wrappers HTTP typés sans remédiation fonctionnelle, et `pre.009` prépare la candidate finale avec documentation, smoke Transport read-only étendu et prompt `0.2.4`. `0.2.3-rel.001` publie cette surface stable après validation du workspace, des graphes Cargo Transport/Config et des deux smokes Devnet. Aucun `base64`, `bs58`, `wincode` ni client RPC Solana supplémentaire n'est ajouté : les payloads sérialisés restent opaques dans Transport tant qu'un besoin de décodage local n'est pas démontré. Le plan détaillé clôturé est `docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`.
`0.2.4-pre.001` réaudite le même jour l'inventaire HTTP officiel et la baseline runtime actuelle : les 15 méthodes réservées restent exactement 10 Blocks + 5 Economics, la navigation Deprecated reste à 14 historiques et Agave stable `v4.2.1` confirme les overloads/limites/extensions sensibles (`getBlock` legacy, `getBlocks`, plafond 500_000, performance samples 720, `commissionBps`). Le gate de sizing est positif sans split de release. Le plan actif `docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md` prévoit des tranches dédiées à `getBlock`, `getBlockProduction`, `getInflationReward`, puis une compliance finale `52/52 current + 14/14 historical` sous `KSP-TRANSPORT-007` avant `0.2.5 — Wallet foundation`.
`0.2.4-pre.001` réaudite le même jour l'inventaire HTTP officiel et la baseline runtime actuelle : les 15 méthodes réservées restent exactement 10 Blocks + 5 Economics, la navigation Deprecated reste à 14 historiques et Agave stable `v4.2.1` confirme les overloads/limites/extensions sensibles (`getBlock` legacy, `getBlocks`, plafond 500_000, performance samples 720, `commissionBps`). Le gate de sizing est positif sans split de release. `pre.002``pre.008` livrent ensuite les DTOs/wires et les 15 wrappers ; `pre.008-fix.001` corrige uniquement la conformité Clippy. `pre.009` réaudite l'index officiel et les SIMDs HTTP sensibles, confirme l'égalité exacte des ensembles 52 current + 14 Deprecated avec le registre, ajoute les canaries de wrapper/compliance globales, étend le smoke Transport aux familles Blocks/Economics, synchronise la documentation et prépare `0.2.5 — Wallet foundation`. Le plan détaillé est `docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`.
## `0.2.5` — Wallet foundation

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Plan `0.2.4` — HTTP Blocks + Economics + compliance HTTP finale
@@ -18,6 +18,8 @@ Ce plan ouvre `0.2.4` par `0.2.4-pre.001` sur la base stable attendue `v0.2.3`.
La mission de `0.2.4` est strictement de compléter les **10 Blocks + 5 Economics** déjà affectées à `V0_2_4`, puis de fermer la compliance HTTP globale **52/52 current + 14/14 historical** sous la règle `KSP-TRANSPORT-007`.
`0.2.4-pre.009` amène ce plan au statut **candidate de clôture** : les 15/15 wrappers `V0_2_4` sont implémentés, l'inventaire officiel final reste 52 current + 14 Deprecated, les deux ensembles correspondent exactement au registre KSP et la matrice durable de clôture est `docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`. Le statut stable reste réservé à `rel.001`.
## Gate de sizing `pre.001`
Question obligatoire :
@@ -427,13 +429,65 @@ historical Deprecated/Removed == 14/14
KSP-TRANSPORT-007 audited current == 52/52
```
La compliance `KSP-TRANSPORT-007` des 37 wrappers de `0.2.1``0.2.3` reste acquise par `docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`; la clôture `0.2.4` vérifie qu'aucune régression n'a été introduite et applique la même règle aux 15 nouveaux wrappers. Le réaudit final inclut explicitement l'état des SIMD susceptibles de modifier la surface HTTP ou sa sémantique observable, au minimum SIMD-0180, SIMD-0298, SIMD-0301, SIMD-0307, SIMD-0385, SIMD-0490, SIMD-0550 et SIMD-0553, afin qu'une évolution devenue stable pendant la session ne soit pas oubliée. Il réaudite aussi l'inventaire officiel lui-même afin de détecter d'éventuels nouveaux endpoints issus de SIMD-0180 ou d'une autre évolution d'interface.
La compliance `KSP-TRANSPORT-007` des 37 wrappers de `0.2.1``0.2.3` reste acquise par `docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`; la clôture `0.2.4` vérifie qu'aucune régression n'a été introduite et applique la même règle aux 15 nouveaux wrappers. Le réaudit final inclut explicitement les extensions wire déjà acquises SIMD-0118 et SIMD-0291, puis l'état des SIMD susceptibles de modifier la surface HTTP ou sa sémantique observable, au minimum SIMD-0180, SIMD-0298, SIMD-0301, SIMD-0307, SIMD-0385, SIMD-0490, SIMD-0550 et SIMD-0553, afin qu'une évolution devenue stable pendant la session ne soit pas oubliée. Il réaudite aussi l'inventaire officiel lui-même afin de détecter d'éventuels nouveaux endpoints issus de SIMD-0180 ou d'une autre évolution d'interface.
## Réaudit final `pre.009`
Le réaudit du **18 août 2026** confirme l'index HTTP officiel actuel sans recalibrage :
```text
Solana current HTTP exact names == KSP current registry exact names == 52
Solana Deprecated exact names == KSP historical exact names == 14
missing == 0
extra == 0
```
La navigation officielle actuelle ne contient aucun nouvel endpoint HTTP issu de SIMD-0180.
État final de la watchlist prospective :
```text
SIMD-0180 Review
SIMD-0298 Idea
SIMD-0301 PR closed / unmerged
SIMD-0307 Review
SIMD-0385 Review
SIMD-0490 Review
SIMD-0550 Review
SIMD-0553 Draft
```
Extensions SIMD déjà matérialisées dans le wire stable et réauditées à la clôture :
```text
SIMD-0118 Activated -> numRewardPartitions préservé en omitted/null/value
SIMD-0291 Review -> commission et commissionBps préservés indépendamment
```
Le statut `Review` de SIMD-0291 ne retire pas le champ déjà exposé par Agave `v4.2.1` : `KSP-TRANSPORT-007` impose de conserver ce wire réellement livré. SIMD-0118 est `Activated` et confirme définitivement que `numRewardPartitions` fait partie des extensions de bloc à ne pas aplatir ni synthétiser.
Conséquences :
- aucun changement anticipé de `getLeaderSchedule` pour SIMD-0180 ;
- aucun `footer`, `bankHash` ou `parentBankHash` spéculatif dans `getBlock` ;
- `SolanaTransactionVersion::Number(u8)` reste générique ;
- minimum de délégation et inflation restent des valeurs runtime ;
- SIMD-0553 ne crée aucun nouveau contrat HTTP stable dans la baseline auditée.
La preuve typed finale est doublée :
```text
public API canary -> référence les 52 wrappers current + 2 wrappers legacy séparés
release canary -> fige noms exacts 52 + 14 et partition 4/22/11/15
```
La matrice complète est conservée dans `docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`.
## Smokes live
Les smokes restent opt-in et secondaires par rapport aux fixtures locales.
Le smoke Transport pur peut être étendu uniquement avec quelques reads robustes, par exemple `getBlockHeight`, `getFirstAvailableBlock`, `minimumLedgerSlot`, `getInflationRate` ou `getStakeMinimumDelegation`. Éviter un `getBlock` dépendant d'un slot fixe ou tout scénario fragile lié à des récompenses d'un epoch précis.
`pre.009` étend le smoke Transport pur avec `getBlockHeight`, `getInflationRate` et `getStakeMinimumDelegation`. Ces reads restent robustes : aucun slot historique fixe, aucun compte reward spécifique et aucune valeur économique codée en dur. Éviter un `getBlock` dépendant d'un slot fixe ou tout scénario fragile lié à des récompenses d'un epoch précis.
Le smoke historique Config -> Transport reste une exception transitoire de composition et ne devient pas la destination générale des futurs scénarios cross-crates.
@@ -452,7 +506,7 @@ pre.006 réaudit SIMD-0298/0307 + getBlock moderne + bare encoding legacy + tra
pre.007 réaudit SIMD-0490/0550 + Economics simples : getInflationGovernor, getInflationRate,
getStakeMinimumDelegation, getSupply
pre.008 réaudit commitment runtime + getInflationReward + null positionnels + commissionBps SIMD-0291 + invariants
pre.009 réaudit SIMD HTTP (0180/0298/0301/0307/0385/0490/0550/0553 minimum)
pre.009 réaudit SIMD HTTP (0118/0180/0291/0298/0301/0307/0385/0490/0550/0553 minimum)
+ réaudit inventaire officiel + compliance finale 52/52 + 14/14
+ KSP-TRANSPORT-007 + docs + smokes + graphes + prompt 0.2.5 — Wallet foundation
rel.001 publication strictement publicationnelle
@@ -490,6 +544,6 @@ réécriture des deltas historiques
## Questions ouvertes
Aucune question bloquante pour `pre.002`.
Aucune question bloquante pour la candidate `pre.009`.
Les noms Rust exacts des DTOs peuvent encore être ajustés pendant l'implémentation. En revanche, les formes RPC, overloads, distinctions wire et limites fixées dans ce plan ne doivent pas être réduits pour simplifier l'API KSP.
Les choix fonctionnels et wire de `0.2.4` sont désormais figés pour cette release. Toute nouvelle évolution officielle détectée après cette candidate appartient à une release ultérieure, sauf défaut de conformité démontré nécessitant un fix avant publication.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/000-README.md -->
<!-- version: 9 -->
<!-- version: 10 -->
# Validations KSP
@@ -16,3 +16,4 @@ Documents :
- [`005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) — réaudit rétroactif de complétude `KSP-TRANSPORT-007` des 37 wrappers HTTP typés livrés de `0.2.1` à `0.2.3-pre.007`, avec preuves Solana/Agave et verdict méthode par méthode.
- [`006-V0_2_3_HTTP_TRANSACTIONS.md`](006-V0_2_3_HTTP_TRANSACTIONS.md) — matrice finale validée de `0.2.3`, 11 wrappers Transactions, sécurité write/simulation, réaudit 52+14, `KSP-TRANSPORT-007` 37/37, graphes Cargo et deux smokes Devnet passés avant publication stable.
- [`007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) — matrice candidate de clôture `0.2.4`, inventaire exact 52 current + 14 Deprecated, preuve typed 52/52, audit SIMD final, `KSP-TRANSPORT-007`, smokes et gates de graphes/publication.

View File

@@ -0,0 +1,429 @@
<!-- file: docs/validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md -->
<!-- version: 1 -->
# Validation candidate `0.2.4` — HTTP Blocks + Economics + compliance finale
## Objet
Cette matrice porte la preuve de clôture candidate de `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`.
Elle complète les validations historiques :
- [`003-V0_2_1_ONCHAIN_HTTP.md`](003-V0_2_1_ONCHAIN_HTTP.md) — foundation HTTP et registre initial ;
- [`004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) — 22 wrappers Accounts/Tokens/Cluster ;
- [`005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) — réaudit `KSP-TRANSPORT-007` des 37 wrappers acquis avant `0.2.4` ;
- [`006-V0_2_3_HTTP_TRANSACTIONS.md`](006-V0_2_3_HTTP_TRANSACTIONS.md) — 11 wrappers Transactions et clôture stable `0.2.3`.
`0.2.4-pre.009` n'ajoute pas de nouvelle méthode RPC métier. Il agrège les preuves de complétude, étend le smoke live aux familles nouvellement livrées, synchronise la documentation et prépare `0.2.5`.
`0.2.4-rel.001` reste strictement publicationnelle après validation opérateur complète de cette candidate.
## Base opérateur validée
La base `0.2.4-pre.008-fix.001` a été validée le **18 août 2026** avec :
```text
cargo fmt --all OK
cargo check --workspace OK
cargo clippy --workspace --all-targets OK
Transport
240 unit passed
26 public API passed
21 release completeness passed
1 smoke live ignored par défaut
0 failure
```
Le fix ne modifie pas le contrat `getInflationReward`; il ajoute uniquement le `return` explicite exigé par la policy Clippy workspace.
## Réaudit officiel final — inventaire HTTP
Dernier contrôle effectué le **18 août 2026** contre l'index HTTP Solana courant :
```text
https://solana.com/docs/rpc/http
```
L'index contient toujours exactement **52 méthodes HTTP courantes**.
La navigation Deprecated officielle, visible depuis les pages sous :
```text
https://solana.com/docs/rpc/deprecated/
```
contient toujours exactement **14 méthodes historiques**.
Le rapprochement a été réalisé sur les **noms exacts**, pas uniquement sur les compteurs :
```text
official current names == KSP current registry names == 52/52
official deprecated names == KSP historical registry names == 14/14
missing == 0
extra == 0
```
Aucun nouvel endpoint HTTP issu de SIMD-0180 ou d'une autre évolution d'interface n'apparaît dans l'index officiel actuel.
## Baseline Agave et audit SIMD final
La baseline runtime conservée pour le contrat de cette release reste **Agave `v4.2.1`**, déjà auditée depuis `pre.001`.
Le calendrier public Agave v4.2 observé le 18 août 2026 montre que le rollout v4.2 est encore en cours : Devnet a été livré en juillet/août et les étapes Mainnet-beta d'adoption générale/activation sont positionnées en août. Cette situation ne justifie pas de remplacer rétroactivement la baseline wire de la release sans différence stable démontrée.
Audit final minimal imposé par le plan :
| SIMD | Statut observé le 2026-08-18 | Conséquence HTTP KSP |
|---------------------------------------------------|------------------------------|-------------------------------------------------------------------------------------------------------------------|
| `0180` Vote Account Address Keyed Leader Schedule | Review | aucune nouvelle méthode HTTP officielle ; ne pas changer `getLeaderSchedule` par anticipation |
| `0298` Bank Hash in Block Footer | Idea | aucun `bankHash` ajouté au wire stable `getBlock` |
| `0301` parent bank hash | PR fermé, non mergé | aucun `parentBankHash` spéculatif |
| `0307` Add Block Footer | Review | aucun `footer` ajouté à `SolanaGetBlockConfig`/`SolanaConfirmedBlock` tant que la baseline stable ne l'expose pas |
| `0385` Transaction V1 | Review | conserver `SolanaTransactionVersion::Number(u8)` générique et la canary version `1` |
| `0490` Stake v5 | Review | `getStakeMinimumDelegation` reflète uniquement la valeur runtime ; aucun minimum local codé en dur |
| `0550` Double Disinflation Rate | Review | `getInflationGovernor`/`getInflationRate` reflètent les valeurs runtime ; aucune formule locale |
| `0553` Base Inclusion and Resource-based Fee | Draft | changement économique/consensus à surveiller ; aucun nouveau wrapper ou champ HTTP stable ajouté |
Extensions wire déjà acquises et réauditées explicitement : **SIMD-0118** et **SIMD-0291**.
| SIMD | Statut observé le 2026-08-18 | Contrat déjà matérialisé dans KSP |
|-----------------------------------------------|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| `0118` Partitioned Epoch Rewards Distribution | Activated | `getBlock.numRewardPartitions` reste lossless : omission, `null` et valeur sont distincts ; KSP ne synthétise jamais `0` |
| `0291` Commission Rate in Basis Points | Review | `commission` et `commissionBps` restent indépendants dans les rewards de bloc et d'inflation ; les sous-arbres transaction restent lossless |
Le statut documentaire `Review` de SIMD-0291 ne justifie pas de supprimer un champ déjà livré par Agave `v4.2.1`. Inversement, KSP ne déduit jamais `commissionBps` depuis `commission`, ni l'inverse.
Sources SIMD :
```text
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0118-partitioned-epoch-reward-distribution.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0180-vote-account-leader-schedule.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0291-commission-rate-in-basis-points.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0298-bank-hash-in-block-footer.md
https://github.com/solana-foundation/solana-improvement-documents/pull/301
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0307-add-block-footer.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0490-upgrade-stake-to-v5.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0550-double-disinflation.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0553-resource-fee-burn.md
```
## Compliance des 52 méthodes courantes
La canary `public_v0_2_4_pre_009_all_52_current_typed_wrappers_and_legacy_forms_are_available_from_crate_root` référence directement chaque méthode Rust publique ci-dessous. Une méthode ne compte donc pas comme typed-complete uniquement parce qu'un descriptor ou l'exécuteur raw existe.
| Méthode RPC | Catégorie | Release typed | Classe | Wrapper public |
|-------------------------------------|--------------|---------------|--------------------------------------|------------------------------------------|
| `getAccountInfo` | Accounts | `0.2.2` | Read / RetrySafe | `get_account_info` |
| `getBalance` | Accounts | `0.2.1` | Read / RetrySafe | `get_balance` |
| `getLargestAccounts` | Accounts | `0.2.2` | Read / RetrySafe | `get_largest_accounts` |
| `getMinimumBalanceForRentExemption` | Accounts | `0.2.2` | Read / RetrySafe | `get_minimum_balance_for_rent_exemption` |
| `getMultipleAccounts` | Accounts | `0.2.2` | Read / RetrySafe | `get_multiple_accounts` |
| `getProgramAccounts` | Accounts | `0.2.2` | Read / RetrySafe | `get_program_accounts` |
| `getTokenAccountBalance` | Tokens | `0.2.2` | Read / RetrySafe | `get_token_account_balance` |
| `getTokenAccountsByDelegate` | Tokens | `0.2.2` | Read / RetrySafe | `get_token_accounts_by_delegate` |
| `getTokenAccountsByOwner` | Tokens | `0.2.2` | Read / RetrySafe | `get_token_accounts_by_owner` |
| `getTokenLargestAccounts` | Tokens | `0.2.2` | Read / RetrySafe | `get_token_largest_accounts` |
| `getTokenSupply` | Tokens | `0.2.2` | Read / RetrySafe | `get_token_supply` |
| `getFeeForMessage` | Transactions | `0.2.3` | Read / RetrySafe | `get_fee_for_message` |
| `getLatestBlockhash` | Transactions | `0.2.3` | Read / RetrySafe | `get_latest_blockhash` |
| `getRecentPrioritizationFees` | Transactions | `0.2.3` | Read / RetrySafe | `get_recent_prioritization_fees` |
| `getSignaturesForAddress` | Transactions | `0.2.3` | Read / RetrySafe | `get_signatures_for_address` |
| `getSignatureStatuses` | Transactions | `0.2.3` | Read / RetrySafe | `get_signature_statuses` |
| `getTransaction` | Transactions | `0.2.3` | Read / RetrySafe | `get_transaction` + legacy |
| `getTransactionCount` | Transactions | `0.2.3` | Read / RetrySafe | `get_transaction_count` |
| `isBlockhashValid` | Transactions | `0.2.3` | Read / RetrySafe | `is_blockhash_valid` |
| `requestAirdrop` | Transactions | `0.2.3` | WriteSubmission / NeverAfterDispatch | `request_airdrop` |
| `sendTransaction` | Transactions | `0.2.3` | WriteSubmission / NeverAfterDispatch | `send_transaction` |
| `simulateTransaction` | Transactions | `0.2.3` | Simulation / RetrySafe | `simulate_transaction` |
| `getBlock` | Blocks | `0.2.4` | Read / RetrySafe | `get_block` + legacy |
| `getBlockCommitment` | Blocks | `0.2.4` | Read / RetrySafe | `get_block_commitment` |
| `getBlockHeight` | Blocks | `0.2.4` | Read / RetrySafe | `get_block_height` |
| `getBlockProduction` | Blocks | `0.2.4` | Read / RetrySafe | `get_block_production` |
| `getBlocks` | Blocks | `0.2.4` | Read / RetrySafe | `get_blocks` |
| `getBlocksWithLimit` | Blocks | `0.2.4` | Read / RetrySafe | `get_blocks_with_limit` |
| `getBlockTime` | Blocks | `0.2.4` | Read / RetrySafe | `get_block_time` |
| `getFirstAvailableBlock` | Blocks | `0.2.4` | Read / RetrySafe | `get_first_available_block` |
| `getRecentPerformanceSamples` | Blocks | `0.2.4` | Read / RetrySafe | `get_recent_performance_samples` |
| `minimumLedgerSlot` | Blocks | `0.2.4` | Read / RetrySafe | `minimum_ledger_slot` |
| `getClusterNodes` | Cluster | `0.2.2` | Read / RetrySafe | `get_cluster_nodes` |
| `getEpochInfo` | Cluster | `0.2.2` | Read / RetrySafe | `get_epoch_info` |
| `getEpochSchedule` | Cluster | `0.2.2` | Read / RetrySafe | `get_epoch_schedule` |
| `getGenesisHash` | Cluster | `0.2.1` | Read / RetrySafe | `get_genesis_hash` |
| `getHealth` | Cluster | `0.2.1` | Read / RetrySafe | `get_health` |
| `getHighestSnapshotSlot` | Cluster | `0.2.2` | Read / RetrySafe | `get_highest_snapshot_slot` |
| `getIdentity` | Cluster | `0.2.2` | Read / RetrySafe | `get_identity` |
| `getLeaderSchedule` | Cluster | `0.2.2` | Read / RetrySafe | `get_leader_schedule` |
| `getMaxRetransmitSlot` | Cluster | `0.2.2` | Read / RetrySafe | `get_max_retransmit_slot` |
| `getMaxShredInsertSlot` | Cluster | `0.2.2` | Read / RetrySafe | `get_max_shred_insert_slot` |
| `getSlot` | Cluster | `0.2.2` | Read / RetrySafe | `get_slot` |
| `getSlotLeader` | Cluster | `0.2.2` | Read / RetrySafe | `get_slot_leader` |
| `getSlotLeaders` | Cluster | `0.2.2` | Read / RetrySafe | `get_slot_leaders` |
| `getVersion` | Cluster | `0.2.1` | Read / RetrySafe | `get_version` |
| `getVoteAccounts` | Cluster | `0.2.2` | Read / RetrySafe | `get_vote_accounts` |
| `getInflationGovernor` | Economics | `0.2.4` | Read / RetrySafe | `get_inflation_governor` |
| `getInflationRate` | Economics | `0.2.4` | Read / RetrySafe | `get_inflation_rate` |
| `getInflationReward` | Economics | `0.2.4` | Read / RetrySafe | `get_inflation_reward` |
| `getStakeMinimumDelegation` | Economics | `0.2.4` | Read / RetrySafe | `get_stake_minimum_delegation` |
| `getSupply` | Economics | `0.2.4` | Read / RetrySafe | `get_supply` |
Les deux formes legacy encore supportées sont couvertes séparément et marquées deprecated :
```text
getTransaction -> HttpTransportPool::get_transaction_legacy
getBlock -> HttpTransportPool::get_block_legacy
```
Partition exacte :
```text
0.2.1 foundation 4
0.2.2 Accounts/Tokens/Cluster 22
0.2.3 Transactions 11
0.2.4 Blocks/Economics 15
--------------------------------
total 52
```
Classification globale attendue :
```text
Read / RetrySafe
Simulation / RetrySafe
WriteSubmission / NeverAfterDispatch
```
Les seules write submissions actuelles restent `requestAirdrop` et `sendTransaction`; aucune classe `NeverAfterDispatch` n'est affaiblie par `0.2.4`.
## Compliance des 14 historiques
Les 14 entrées restent découvrables pour audit/compliance mais sont `Deprecated / Removed / NotApplicable` et ne sont pas envoyées au réseau :
| Méthode historique | Documentation | Runtime KSP | Remplacement/aide |
|-------------------------------------|---------------|-------------|-------------------------------------|
| `confirmTransaction` | Deprecated | Removed | getSignatureStatuses |
| `getConfirmedBlock` | Deprecated | Removed | getBlock |
| `getConfirmedBlocks` | Deprecated | Removed | getBlocks |
| `getConfirmedBlocksWithLimit` | Deprecated | Removed | getBlocksWithLimit |
| `getConfirmedSignaturesForAddress2` | Deprecated | Removed | getSignaturesForAddress |
| `getConfirmedTransaction` | Deprecated | Removed | getTransaction |
| `getFeeCalculatorForBlockhash` | Deprecated | Removed | isBlockhashValid / getFeeForMessage |
| `getFeeRateGovernor` | Deprecated | Removed | getFeeForMessage |
| `getFees` | Deprecated | Removed | getFeeForMessage |
| `getRecentBlockhash` | Deprecated | Removed | getLatestBlockhash |
| `getSignatureConfirmation` | Deprecated | Removed | getSignatureStatuses |
| `getSignatureStatus` | Deprecated | Removed | getSignatureStatuses |
| `getSnapshotSlot` | Deprecated | Removed | getHighestSnapshotSlot |
| `getStakeActivation` | Deprecated | Removed | aucun remplacement direct |
La canary `release_v0_2_4_pre_009_final_http_inventory_and_coverage_partition_are_exact` fige simultanément :
```text
52 noms current exacts
14 noms historiques exacts
4 / 22 / 11 / 15 par HttpRpcCoverageRelease
Supported pour les 52 current
Deprecated + Removed + NotApplicable pour les 14 historiques
RetrySafe pour Read/Simulation current
NeverAfterDispatch pour WriteSubmission current
```
## `KSP-TRANSPORT-007` — preuve globale 52/52
Le réaudit `0.2.3` a déjà conclu **37/37 conformes** avant l'ouverture de `0.2.4`.
Les 15 nouveaux wrappers appliquent la même règle sans réduction de contrat.
### Blocks — 10/10
Points de sensibilité couverts :
- `getBlock` moderne + bare encoding legacy deprecated ;
- encodings `binary/base58/base64/json/jsonParsed` réellement supportés par la baseline ;
- `transactionDetails = full/signatures/none/accounts` ;
- `maxSupportedTransactionVersion` et version numérique générique, y compris canary `1` ;
- distinction résultat `null` / erreurs RPC ;
- `transactions`, `signatures`, `rewards`, `numRewardPartitions` avec préservation des états wire pertinents ;
- `commission` nullable + `commissionBps` indépendant ;
- `getBlocks` avec ses quatre overloads exacts et `RpcContextConfig` complet ;
- `getBlocksWithLimit(0)` valide et plafond 500000 ;
- `getRecentPerformanceSamples <= 720` et ancien wire sans `numNonVoteTransactions` ;
- `getBlockProduction` identity/range/context sans restriction de commitment inventée ;
- wrappers sans config exactement en `params: []`.
### Economics — 5/5
Points de sensibilité couverts :
- aucune formule d'inflation locale ;
- aucun minimum de délégation codé en dur ;
- `getSupply` conserve `excludeNonCirculatingAccountsList` omis/false/true ;
- `getInflationReward` conserve ordre, doublons, `null` positionnels et cardinalité ;
- aucun plafond d'adresses inventé pour `getInflationReward` ;
- `epoch`, `commitment`, `minContextSlot` transmis ;
- `getInflationReward` rejette `processed` avant I/O car la voie runtime exige au moins `confirmed` ;
- `commission` nullable et `commissionBps` présent/omis/null indépendants ;
- erreurs RPC de contexte/rewards period conservées comme erreurs applicatives distantes.
Verdict candidate :
```text
KSP-TRANSPORT-007 current wrappers == 52/52
remédiation fonctionnelle finale == aucune
```
## Smoke Devnet Transport pur
Le smoke Transport reste opt-in, programmatique et read-only :
```text
settings programmatiques
-> getAccountInfo
-> getTokenAccountsByOwner
-> getEpochInfo
-> getVoteAccounts
-> getLatestBlockhash
-> isBlockhashValid
-> getTransactionCount
-> getBlockHeight
-> getInflationRate
-> getStakeMinimumDelegation
```
Les trois derniers appels ajoutent une traversée live représentative des familles Blocks/Economics sans dépendre d'un slot historique particulier, d'un compte reward spécifique ou d'une valeur économique codée en dur.
Commande :
```bash
cargo test -p ksp-onchain-transport-lib --test transport_devnet_smoke -- --ignored --nocapture
```
Le smoke historique de composition reste séparé et transitoire :
```bash
cargo test -p ksp-config-lib --test transport_devnet_smoke -- --ignored --nocapture
```
Il ne devient pas un modèle de placement des futurs smokes cross-crates.
## Frontières et graphes Cargo
Frontière attendue :
```text
ksp-config-lib -> ksp-onchain-transport-lib
ksp-onchain-transport-lib -> ksp-core-lib
ksp-onchain-transport-lib -> ksp-logging-lib
ksp-onchain-transport-lib -X-> ksp-config-lib
ksp-onchain-transport-lib -X-> Store
ksp-onchain-transport-lib -X-> Program
ksp-onchain-transport-lib -X-> tracing direct
```
`0.2.4` n'ajoute aucune dépendance externe au `Cargo.toml` de Transport.
Graphes à inspecter sur la candidate :
```bash
cargo tree -p ksp-onchain-transport-lib
cargo tree -p ksp-onchain-transport-lib -d
cargo tree -p ksp-onchain-transport-lib -e features
cargo tree -p ksp-onchain-transport-lib -e normal
cargo tree -p ksp-config-lib
cargo tree -p ksp-config-lib -d
cargo tree -p ksp-config-lib -e features
cargo tree -p ksp-config-lib -e normal
```
Interprétation importante : `tracing` peut apparaître **transitivement** sous `ksp-logging-lib`, ce qui est conforme à l'architecture. L'interdit porte sur une dépendance **directe** de `ksp-onchain-transport-lib` vers `tracing`. Les graphes doivent donc être lus par chaîne de dépendances et non validés par la simple présence/absence du nom `tracing` dans l'arbre complet.
Les canaries workspace de dépendances restent des règles globales et ne sont pas déplacées dans Transport.
## Gate candidate `0.2.4-pre.009`
Validation déterministe immédiate attendue :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
```
Compteurs Transport attendus après les deux nouvelles canaries finales :
```text
240 unit
27 public API
22 release completeness
1 smoke live ignored par défaut
```
Gate de clôture avant `rel.001` :
```bash
cargo test -p ksp-config-lib
cargo test -p ksp-core-lib
cargo test -p ksp-app-config-desk
cargo test --workspace
```
Puis inspection des huit graphes Cargo ci-dessus et exécution explicite des deux smokes Devnet.
Les résultats opérateur de `pre.009` seront enregistrés ici pendant `rel.001`; ils ne sont pas anticipés dans la candidate.
## Documentation et prochaine release
La candidate synchronise :
```text
ROADMAP.md
README/USAGE Transport
inventaire composant
séquence fonctionnelle
plan 011
index docs/plans/validation/prompts
```
Le prompt suivant est :
```text
prompts/010-V0_2_5_START_PROMPT.md
0.2.5 — Wallet foundation
```
Il conserve notamment les frontières déjà décidées :
```text
ksp-wallet-lib
.kspwallet
protection des secrets
signature
import/export extensible
changement de mot de passe
atomicité/no-clobber
Wallet -X-> Config
Wallet -X-> Transport
Wallet -X-> execution policy
WalletPolicy hors Wallet
```
## Publication `rel.001`
Après validation opérateur complète :
```text
workspace.package.version -> 0.2.4
ROADMAP : 0.2.4 -> [X]
CHANGELOG : synthèse stable 0.2.4
plan 011 / validation 007 : preuves finales opérateur + statut stable
README/USAGE/inventaires : candidate -> stable
deltas/0.2.4/rel.001.md
commit : v0.2.4-rel.001
tag stable : v0.2.4
```
Aucun wrapper, DTO, comportement runtime, dependency ou feature Cargo ne doit être ajouté pendant `rel.001`.

View File

@@ -1,5 +1,5 @@
<!-- file: prompts/000-README.md -->
<!-- version: 13 -->
<!-- version: 14 -->
# Prompts KSP
@@ -30,3 +30,4 @@ Le prompt générique `0.1.x` a été affiné pendant `0.0.3` puis remplacé par
- [`007-V0_2_2_START_PROMPT.md`](007-V0_2_2_START_PROMPT.md) — prompt préparé par la dernière prerelease de `0.2.1`, destiné à ouvrir `0.2.2 — HTTP Accounts + Tokens + Cluster` après publication stable de `0.2.1`; il cible les 22 wrappers typés restants de ces familles et impose un nouvel audit officiel/gate de sizing à `pre.001`.
- [`008-V0_2_3_START_PROMPT.md`](008-V0_2_3_START_PROMPT.md) — prompt préparé par la dernière prerelease de `0.2.2`, destiné à ouvrir `0.2.3 — HTTP Transactions` après publication stable de `0.2.2`; il cible les 11 méthodes Transactions et impose un audit actuel ainsi que la politique no-resend des write submissions.
- [`009-V0_2_4_START_PROMPT.md`](009-V0_2_4_START_PROMPT.md) — prompt préparé par `0.2.3-pre.009`, destiné à ouvrir `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale` après publication stable de `0.2.3`; il cible les 15 wrappers restants et impose `KSP-TRANSPORT-007` ainsi qu'un nouvel audit/sizing à `pre.001`.
- [`010-V0_2_5_START_PROMPT.md`](010-V0_2_5_START_PROMPT.md) — prompt préparé par `0.2.4-pre.009`, destiné à ouvrir `0.2.5 — Wallet foundation` après publication stable de `0.2.4`; il impose un `pre.001` d'audit/brainstorming/sizing avant choix cryptographiques et cadre `.kspwallet`, secrets, signature, persistence atomique et import/export extensible sans `WalletPolicy`.

View File

@@ -0,0 +1,725 @@
<!-- file: prompts/010-V0_2_5_START_PROMPT.md -->
<!-- version: 1 -->
# Prompt de démarrage `0.2.5` — Wallet foundation
## 1. Contexte de reprise
La base attendue est la release stable :
```text
v0.2.4
```
`0.2.1` à `0.2.4` ont stabilisé la foundation HTTP Solana puis complété toute la surface HTTP courante auditée :
```text
52/52 méthodes HTTP courantes avec wrapper typed
14/14 méthodes historiques Deprecated / runtime Removed conservées
KSP-TRANSPORT-007 appliqué à la surface complète
```
La prochaine release est :
```text
0.2.5 — Wallet foundation
```
Sa mission n'est pas d'ajouter une UI ni de commencer l'exécution métier. Elle introduit le **cœur Wallet autonome** dont les applications et l'exécution future pourront dépendre.
La première tranche est :
```text
0.2.5-pre.001
```
et commence obligatoirement par **audit actuel + reprise de l'héritage utile + brainstorming + sizing** avant toute implémentation cryptographique ou format lourd.
## 2. Mission de `0.2.5`
Créer :
```text
crates/ksp-wallet-lib
```
et stabiliser le format natif :
```text
.kspwallet
```
Le Wallet doit fournir au minimum les capacités conceptuelles suivantes :
```text
création
ouverture / déverrouillage
identité publique / Pubkey
protection du secret
signature
changement de mot de passe sans changement de keypair
persistence atomique / no-clobber
projection publique sûre
import/export extensible
```
La release doit aboutir à une bibliothèque utilisable **sans Config, sans Transport, sans Tauri et sans execution policy**.
## 3. Frontières architecturales déjà décidées
La direction attendue reste :
```text
ksp-wallet-lib
-> ksp-core-lib
-> ksp-logging-lib
-> primitives crypto/key/signature low-level explicitement retenues
```
Interdictions :
```text
ksp-wallet-lib -X-> ksp-config-lib
ksp-wallet-lib -X-> ksp-onchain-transport-lib
ksp-wallet-lib -X-> ksp-execution-policy-api
ksp-wallet-lib -X-> Store
ksp-wallet-lib -X-> Tauri
```
Le Wallet **stocke, ouvre et signe**. Il ne décide pas si une transaction ou une dépense est autorisée.
Les règles de dépense, programme, réseau, simulation, plafonds ou approbation appartiennent à la future frontière :
```text
ksp-execution-policy-api
```
et non à `ksp-wallet-lib`.
## 4. Décisions Wallet déjà acquises
Les décisions suivantes ne doivent pas être rouvertes sans raison nouvelle et documentée :
1. le format natif KSP se nomme `.kspwallet` ;
2. KSP ne crée pas de `ksp-wallet-api` séparée dans l'architecture actuelle ;
3. `WalletPolicy` est explicitement exclu du Wallet ;
4. le wallet JSON temporaire historique bot2/bot3 n'est pas migré ;
5. l'ancien nom `.kswallet` n'est pas le nom final KSP ;
6. les secrets wallet ne doivent jamais être déplacés dans Config par commodité ;
7. Wallet n'a pas besoin de Transport pour son cœur ;
8. l'import/export doit rester extensible, mais seules les conversions réellement nécessaires doivent être implémentées ;
9. les futurs scénarios doivent pouvoir utiliser de vrais `.kspwallet`, y compris des wallets dédiés Devnet/tests ;
10. Wallet Desk arrive séparément en `0.2.6`.
Références KSP à relire avant le plan :
```text
docs/rules/RULES_KSP.md
docs/rules/RULES_DEPENDENCIES.md
docs/architecture/002-LAYERS_AND_DEPENDENCIES.md
docs/architecture/003-COMPONENT_CONTRACTS.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/architecture/005-DEPENDENCY_GRAPH.md
docs/architecture/007-EXECUTION_AND_POLICY.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/007-V0_2_0_SERIES_PLANNING.md
docs/validation/002-V0_2_0_SERIES_PLANNING.md
docs/IDEAS.md
```
## 5. `pre.001` — audit officiel actuel + brainstorming + sizing
`pre.001` ne doit pas démarrer directement par le chiffrement du fichier.
Il doit d'abord produire un plan Wallet dédié et répondre explicitement aux questions suivantes.
### 5.1 Héritage bot3/bot2
Réauditer les implémentations historiques réellement disponibles de Wallet afin de classer chaque idée en :
```text
réutiliser conceptuellement
refondre
abandonner
reporter
```
Examiner notamment, lorsqu'ils existent dans les sources historiques :
- création de keypair ;
- lecture/écriture du format wallet ;
- modèle de mot de passe ;
- secret/public separation ;
- changement de mot de passe ;
- signature ;
- import/export ;
- aliases/metadata ;
- atomicité/no-clobber ;
- redaction ;
- temporary wallet JSON ;
- ancien `.kswallet` ;
- `WalletPolicy`.
Ne pas copier automatiquement une dépendance, un format ou une primitive cryptographique uniquement parce qu'elle existait dans bot3.
### 5.2 Primitives Solana actuelles
Réaduiter les crates low-level Solana réellement nécessaires pour :
```text
Pubkey
keypair / secret material
Signer
Signature
```
Objectifs :
- garder les dépendances au niveau le plus bas possible ;
- ne pas tirer un client RPC Solana ;
- ne pas recréer localement une primitive cryptographique standard bien maintenue ;
- conserver toutes les dépendances tierces communes dans `[workspace.dependencies]`.
L'audit doit vérifier les versions réellement actuelles au moment de la session, pas recopier les versions historiques bot3.
### 5.3 Protection cryptographique du fichier
Comparer les primitives cryptographiques maintenues et adaptées au besoin réel du `.kspwallet`.
Le plan doit décider explicitement, avec justification :
```text
KDF mot de passe
AEAD / chiffrement authentifié
CSPRNG
gestion salt / nonce
paramètres KDF sérialisés
versionnement du format
stratégie de migration
zeroization / secret memory handling
```
Ne pas inventer de cryptographie KSP.
Ne pas figer dans ce prompt un choix tel qu'Argon2id, scrypt, AES-GCM ou XChaCha20-Poly1305 sans réaudit actuel ; `pre.001` doit sélectionner les primitives selon sécurité, maintenance, portabilité, dépendances et compatibilité Rust réellement observées.
### 5.4 Modèle de fichier `.kspwallet`
Le plan doit définir les invariants du format avant l'API de persistence.
Le format doit pouvoir identifier sans ambiguïté au minimum :
```text
format/version KSP
algorithmes/paramètres nécessaires au déchiffrement
salt/nonce ou équivalents
payload protégé
metadata publique strictement autorisée
intégrité/authenticité
```
Questions à trancher :
- JSON, binaire ou enveloppe hybride ;
- magic/version ;
- représentation de la Pubkey ;
- metadata publique lisible wallet verrouillé ou non ;
- place de l'alias ;
- champs obligatoires/optionnels ;
- limites de taille ;
- politique unknown-version ;
- politique unknown-field ;
- migrations futures ;
- checksum séparé utile ou redondant avec AEAD ;
- compatibilité endianness/encodage si format binaire.
Le format doit être documentable et testable sans exposer le secret.
### 5.5 Secret en mémoire
Définir explicitement l'ownership du secret déverrouillé.
Au minimum :
- pas de `Debug`/`Display` révélant le secret ;
- pas de valeur secrète dans les erreurs/logs/contextes KSP ;
- éviter `Copy` et les clones implicites de secret ;
- zeroization des buffers possédés lorsque raisonnablement possible ;
- durée de vie du secret déverrouillé explicitement contrôlée ;
- distinction nette public metadata / encrypted payload / unlocked secret ;
- aucune conservation du mot de passe en clair au-delà du besoin cryptographique.
Le plan doit être honnête sur les limites réelles de zeroization dans Rust et des allocations/transcodages choisis ; ne pas promettre une garantie que la stack ne peut pas fournir.
### 5.6 Persistence
Définir la stratégie :
```text
create
open/read
atomic replace
no-clobber create
change password
permissions filesystem
recovery after interrupted write
```
Le changement de mot de passe doit :
- conserver la même identité/keypair ;
- produire un nouveau matériau de protection approprié ;
- ne pas dégrader l'atomicité ;
- ne jamais laisser un fichier partiellement remplacé comme nouveau wallet valide.
Le plan doit distinguer comportement portable et durcissement spécifique Unix si nécessaire.
### 5.7 Import/export extensible
Établir une architecture ouverte qui permette d'ajouter des formats sans enum central fermé imposant de modifier le cœur à chaque intégration.
Auditer les formats réellement utiles maintenant parmi les pistes historiques, par exemple :
```text
Solana CLI keypair JSON
Backpack
Phantom
Solflare
Trust Wallet
autres formats réellement disponibles dans les sources/audits
```
Cette liste est une **liste d'audit**, pas un engagement d'implémentation complet.
`pre.001` sélectionne le minimum de formats nécessaire pour prouver l'extensibilité et le round-trip utile de la release.
Ne pas ajouter des dépendances « au cas où ».
### 5.8 Sizing
Évaluer séparément :
```text
crate/API foundation
format wire
crypto/KDF/AEAD
persistence
signing
change-password
import/export
security tests
docs/USAGE
```
Si le scope ne paraît plus clôturable proprement dans la session, découper **avant** l'implémentation lourde plutôt que réduire silencieusement les garanties de sécurité.
## 6. API publique à concevoir
Les noms exacts sont décidés pendant le plan, mais les responsabilités doivent rester distinctes.
Il doit exister des contrats clairs pour :
```text
wallet public identity/info
wallet locked/encrypted representation
wallet unlocked/signing capability
create/open/save/change-password
import/export/inspect
```
Ne pas exposer directement un champ `secret: Vec<u8>` comme API publique de commodité.
Une API explicitement dangereuse d'export du secret ne doit exister que si un format d'export retenu l'exige réellement et avec une sémantique qui évite l'exposition accidentelle.
La capacité de signature doit permettre aux couches supérieures d'obtenir une signature sans devoir extraire le secret brut.
## 7. Erreurs
Utiliser le type d'erreur commun KSP.
Prévoir des catégories suffisamment précises pour distinguer au minimum :
```text
format invalide
version non supportée
paramètres crypto invalides
authentification/déchiffrement échoué
password invalide ou secret non déverrouillable
I/O
no-clobber / destination existante
persistence atomique
import/export non supporté
key material invalide
signature
```
Les messages et contextes ne doivent pas contenir :
```text
password
secret bytes
seed phrase
private key
payload chiffré complet
KDF input
```
Éviter également de créer un oracle inutile en distinguant trop finement les causes d'échec d'authentification lorsque cela affaiblirait la sécurité.
## 8. Logging
`ksp-wallet-lib` utilise exclusivement la façade `ksp-logging-lib`.
Les événements utiles peuvent inclure :
```text
opération create/open/import/export/change-password/sign
format/version non secrète
succès/échec catégorisé
durée
destination/path seulement selon politique sûre retenue
```
Ne jamais logger :
```text
mot de passe
secret
seed
private key
signature payload arbitraire
contenu complet du wallet
ciphertext complet
nonce/salt si le log n'en a aucun besoin opérationnel
```
Même `trace` ne constitue pas une exception.
## 9. Tests de sécurité et de contrat
Les tests déterministes doivent couvrir au minimum les domaines suivants.
### Format
- round-trip du format natif ;
- magic/version corrects ;
- unknown version rejetée ;
- fichier tronqué/reformaté rejeté ;
- champs/tailles invalides rejetés ;
- corruption/tampering détectée ;
- absence du secret en clair dans le fichier.
### Mot de passe / crypto
- bon mot de passe ouvre le wallet ;
- mauvais mot de passe échoue sans fuite ;
- changement de mot de passe conserve la Pubkey/keypair ;
- ancien mot de passe ne déverrouille plus le nouveau fichier ;
- nouveau mot de passe fonctionne ;
- salt/nonce/paramètres ne sont pas accidentellement réutilisés lorsque le design impose leur renouvellement.
### Secret / diagnostics
- `Debug`/snapshots/projections publiques ne contiennent pas le secret ;
- erreurs n'échoent pas password/secret ;
- logs de test ne contiennent pas de secret ;
- types secrets n'acquièrent pas `Copy` par accident ;
- zeroization testable lorsqu'elle est réellement observable sans faux sentiment de sécurité.
### Persistence
- create ;
- destination existante/no-clobber ;
- write atomique ;
- remplacement lors du changement de mot de passe ;
- échec intermédiaire ne détruisant pas le wallet précédent, dans la mesure testable par la couche ;
- permissions/durcissement filesystem retenus.
### Signature
- Pubkey dérivée correcte ;
- signature produite et vérifiable ;
- changement de mot de passe ne change pas la signature déterministe d'un même message si la primitive de signature est déterministe ;
- le consumer peut signer sans extraction publique du secret brut.
### Import/export
- format(s) retenu(s) ;
- validation stricte ;
- round-trip lorsque le format le permet ;
- inspect sans import si cette capability est retenue ;
- architecture extensible démontrée sans dépendance au format natif dans les adapters externes.
### Public API / architecture
- canary publique depuis crate root ;
- aucune dépendance Wallet -> Config/Transport/ExecutionPolicy ;
- aucune dépendance crypto dupliquée injustifiée ;
- aucun accès environnement direct ;
- aucun `unsafe` ajouté.
## 10. Tests et fixtures contenant des secrets
Les secrets de tests doivent être **explicitement des fixtures non réelles**.
Ne jamais utiliser :
- un wallet personnel ;
- une seed Mainnet ;
- une clé provenant d'un `.env` opérateur ;
- un fichier `.kspwallet` réel.
Si une fixture déterministe est nécessaire, son caractère test-only doit être évident et elle ne doit jamais être utilisable comme secret de production recommandé.
## 11. Dépendances
Toutes les dépendances tierces communes sont déclarées au `Cargo.toml` racine sous `[workspace.dependencies]`.
Les membres consomment :
```toml
<dependency>.workspace = true
```
Éviter :
- crypto maison ;
- deux crates concurrentes pour la même primitive sans justification ;
- stack async ou sérialisation supplémentaire sans besoin ;
- client Solana RPC ;
- dépendance Tauri ;
- Config ;
- Store.
Toute nouvelle dépendance liée au secret doit être auditée au minimum sur :
```text
maintenance actuelle
version Rust/MSRV pertinente
features par défaut
unsafe/transitifs importants
zeroize support
format/compatibilité
duplications cargo tree
```
## 12. Async / sync
Les opérations I/O doivent respecter la règle async-first du projet.
Le plan doit néanmoins distinguer :
- calcul CPU KDF potentiellement coûteux ;
- opérations filesystem ;
- signature CPU locale.
Ne pas bloquer naïvement un runtime async avec une dérivation de clé coûteuse. Décider explicitement si l'API de bas niveau est sync avec wrapper async, utilise `spawn_blocking`, ou adopte une autre frontière cohérente.
Ce choix doit rester compatible avec l'usage futur Tauri sans introduire Tauri dans Wallet.
## 13. Publication sûre / identité publique
Wallet doit pouvoir fournir une représentation sûre destinée aux consommateurs qui n'ont besoin que de l'identité publique.
Cette représentation peut contenir les metadata explicitement retenues telles que :
```text
Pubkey
alias
format/version
état locked/unlocked si pertinent
```
mais jamais le secret ou des dérivés inutiles de secret.
La terminologie « publication » signifie ici **exposition sûre de l'identité publique**, pas envoi réseau ni publication blockchain.
## 14. Hors périmètre `0.2.5`
Sont exclus sauf décision de rescoping explicite pendant le gate `pre.001` :
```text
ksp-app-wallet-desk
lecture réseau du solde
HTTP/WebSocket/gRPC
WalletPolicy
execution policy
construction/simulation/envoi de transaction
Store
seed phrase UI
hardware wallet / Ledger
remote signer
browser extension
mobile app
cloud key management
custody service
trading
```
Les pistes d'import/export peuvent être étudiées sans rendre leurs applications/providers propriétaires du cœur Wallet.
## 15. Relation avec `0.2.6 — Wallet Desk`
`0.2.6` doit pouvoir composer :
```text
Config
+ ksp-wallet-lib
+ ksp-onchain-transport-lib
+ ksp-logging-lib
-> ksp-app-wallet-desk
```
Le premier flux réseau attendu est notamment :
```text
ouvrir/sélectionner un .kspwallet
-> obtenir sa Pubkey publique
-> getBalance via Transport HTTP
-> afficher identité + solde
```
Aucune logique réseau nécessaire à ce flux ne doit remonter dans `ksp-wallet-lib`.
## 16. Prévision souple des prereleases
Prévision initiale à réévaluer par `pre.001` :
```text
pre.001 audit bot3 + dépendances/crypto actuelles + brainstorming + format/API + sizing
pre.002 crate foundation + contrats public/secret + erreurs + canaries architecture
pre.003 enveloppe .kspwallet + versionnement + KDF/AEAD + fixtures déterministes
pre.004 create/open + persistence atomique/no-clobber + durcissement filesystem retenu
pre.005 signature + projection publique + changement de mot de passe
pre.006 architecture import/export + premier(s) format(s) réellement retenu(s)
pre.007 security/compliance audit + README/USAGE + graphes + tests complémentaires
pre.008 clôture candidate + documentation finale + prompt 0.2.6 — Wallet Desk
rel.001 publication strictement publicationnelle
```
Cette prévision est **souple**.
Si un fil cryptographique ou de persistence exige une correction, ajouter une prerelease/fix plutôt que compresser les validations.
Si `pre.001` conclut qu'un format/import particulier doit être reporté, le report doit être explicite et ne doit pas affaiblir les garanties du format natif.
## 17. Validation continue
Après chaque changement Rust :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
```
Pendant le développement :
```bash
cargo test -p ksp-wallet-lib
```
Aux checkpoints justifiés et à la clôture :
```bash
cargo test --workspace
```
Réaduiter les graphes Cargo de Wallet et de ses consumers lorsqu'ils apparaissent.
## 18. Discipline des deltas
Les deltas historiques sont immuables.
Utiliser :
```text
deltas/0.2.5/pre.001.md
deltas/0.2.5/pre.002.md
...
deltas/0.2.5/pre.NNN-fix.NNN.md
deltas/0.2.5/rel.001.md
```
La dernière prerelease doit préparer une candidate complètement validable.
`rel.001` doit rester strictement publicationnelle :
```text
version stable
ROADMAP
CHANGELOG stable
statut final du plan/validation
commit rel
tag stable
```
Aucune nouvelle capacité Wallet fonctionnelle ne doit être ajoutée à `rel.001`.
## 19. Livrables de `pre.001`
Avant toute implémentation lourde, produire au minimum :
1. le plan détaillé `0.2.5` ;
2. l'audit des règles/frontières KSP ;
3. l'audit des implémentations historiques Wallet utiles ;
4. l'audit des primitives Solana/key/signature actuelles ;
5. l'audit comparatif des primitives KDF/AEAD/RNG ;
6. la proposition de format `.kspwallet` ;
7. le modèle de secret en mémoire ;
8. la stratégie de persistence/atomicité ;
9. la stratégie import/export ;
10. la matrice de risques sécurité ;
11. les dépendances pressenties et leur justification ;
12. les tests/canaries nécessaires ;
13. le sizing et la prévision de prereleases ;
14. les questions ouvertes réellement bloquantes.
Le gate `pre.001` doit conclure explicitement :
```text
GO
```
ou :
```text
SPLIT / RESCOPE
```
avec justification.
## 20. Critère de sortie de `0.2.5`
`0.2.5` ne peut être publié stable que si :
- `ksp-wallet-lib` est autonome et documenté ;
- `.kspwallet` est versionné et documenté ;
- le secret n'est jamais stocké en clair dans le format natif ;
- le secret/password ne fuit pas dans Debug/Display/logs/errors ;
- create/open/sign/change-password sont validés ;
- l'identité publique reste accessible par un contrat sûr ;
- la persistence retenue est atomique/no-clobber selon son contrat ;
- les corruptions/tampering sont détectées ;
- import/export extensible est démontré avec le minimum de formats retenu ;
- `WalletPolicy` est absent ;
- Wallet ne dépend pas de Config/Transport/ExecutionPolicy ;
- les graphes Cargo sont réaudités ;
- les tests déterministes et le workspace passent ;
- README/USAGE/validation sont synchronisés ;
- le prompt `0.2.6 — Wallet Desk` est finalisé ;
- `rel.001` reste publicationnelle.
## 21. Première action de la session
Commencer par :
```text
audit actuel
-> brainstorming
-> matrice des décisions
-> sizing
-> plan pre.001
```
Ne pas commencer par coder le chiffrement du fichier.