v0.2.3-pre.001

This commit is contained in:
2026-08-18 10:47:19 +02:00
parent fff69ead9c
commit d06284fca2
7 changed files with 856 additions and 10 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 119
# version: 120
[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.2"
version = "0.2.3-pre.1"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 37 -->
<!-- version: 38 -->
# Roadmap KSP
@@ -47,7 +47,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.
- [ ] `0.2.3` — Compléter les 11 méthodes HTTP Transactions, y compris write/submission technique avec politique no-resend ambigu.
- [/] `0.2.3` — Compléter les 11 méthodes HTTP Transactions, y compris write/submission technique avec politique no-resend ambigu ; `pre.001` confirme le périmètre, la classification `8 Read / 2 WriteSubmission / 1 Simulation`, le gate de sizing positif et labsence de nouvelle dépendance.
- [ ] `0.2.4` — Compléter les 10 méthodes HTTP Blocks + 5 Economics et exécuter la compliance finale de toute la surface HTTP 52 current + 14 deprecated historiques.
- [ ] `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.

205
deltas/0.2.3/pre.001.md Normal file
View File

@@ -0,0 +1,205 @@
<!-- file: deltas/0.2.3/pre.001.md -->
<!-- version: 1 -->
# Delta `0.2.3-pre.001` — réaudit HTTP Transactions, sécurité et sizing
## Base requise
Release stable attendue :
```text
v0.2.2
```
L'archive KSP fournie porte `workspace.package.version = "0.2.2"`. Elle ne contient pas `.git`; le tag `v0.2.2` n'est donc pas revérifiable
localement depuis le zip.
## Objectif
Exécuter la première tranche obligatoire de `0.2.3` sans implémentation fonctionnelle lourde : relire les contrats KSP, réauditer la surface
HTTP Solana officielle actuelle, confirmer la matrice des 11 méthodes Transactions, vérifier les règles de sécurité Read/WriteSubmission/Simulation,
cadrer les DTOs et formes wire, réévaluer les dépendances d'encodage et trancher le gate de sizing.
## Version Cargo
Conformément à `VER-ID-009`, la prerelease non-fix synchronise le signal technique :
```text
0.2.2 -> 0.2.3-pre.1
```
Aucune source Rust, dépendance Cargo ou configuration runtime n'est modifiée dans cette tranche.
## Résultats principaux
- index HTTP Solana courant réaudité : **52 méthodes courantes** ;
- navigation Deprecated officielle : **14 méthodes historiques**, inchangées ;
- les 11 méthodes affectées à `HttpRpcCoverageRelease::V0_2_3` restent exactement :
`getFeeForMessage`, `getLatestBlockhash`, `getRecentPrioritizationFees`, `getSignaturesForAddress`, `getSignatureStatuses`, `getTransaction`,
`getTransactionCount`, `isBlockhashValid`, `requestAirdrop`, `sendTransaction`, `simulateTransaction` ;
- la partition KSP reste donc `0.2.1 = 4`, `0.2.2 = 22`, `0.2.3 = 11`, `0.2.4 = 15` sans avancement prématuré ;
- la classification centrale reste correcte : **8 Read / RetrySafe**, **2 WriteSubmission / NeverAfterDispatch** (`requestAirdrop`, `sendTransaction`),
**1 Simulation / RetrySafe** (`simulateTransaction`) ;
- `sendTransaction.maxRetries` reste une option RPC de retry côté nœud et ne doit jamais être confondue avec la retry policy HTTP KSP ;
- un résultat ambigu après dispatch d'une WriteSubmission (`timeout`, rupture après envoi, HTTP temporaire après dispatch ou équivalent) interdit toute
resoumission automatique par KSP ;
- `getFeeForMessage` transporte un message encodé en base64 et retourne un `RpcResponse` dont la valeur fee est nullable ;
- `getLatestBlockhash` conserve `blockhash` + `lastValidBlockHeight` sous contexte ;
- `getRecentPrioritizationFees` conserve un tableau optionnel d'adresses, borné à **128** par la documentation/runtime courant, et un résultat ordonné
de couples `slot/prioritizationFee` ;
- `getSignaturesForAddress` conserve `before/until/limit`, `minContextSlot`, l'ordre newest-to-oldest et une limite runtime **1..=1000** ;
- la source Agave courante expose aussi `transactionIndex` comme champ optionnel de la structure de signature ; le wire KSP ne doit pas le perdre ;
- `getSignatureStatuses` conserve une cardinalité maximale de **256**, `searchTransactionHistory`, l'ordre positionnel des résultats et les `null`
documentés ; la source Agave courante n'interdit pas un tableau d'entrée vide ;
- `getTransaction` conserve l'objet de config moderne (`commitment`, `encoding`, `maxSupportedTransactionVersion`) et la forme legacy du second paramètre
`encoding` uniquement pour compatibilité, explicitement non recommandée ; son résultat reste nullable et doit préserver les formes transaction/meta/version
sans imposer un modèle Program métier ;
- `requestAirdrop` reste une soumission malgré son rôle de faucet : une signature retournée ou une issue réseau ambiguë n'autorise aucun resend aveugle ;
- `sendTransaction` ne construit ni ne signe la transaction : Transport transmet une transaction déjà construite/signée et préserve les options RPC ;
- `simulateTransaction` reste retry-safe, accepte `base58`/`base64` côté runtime courant, et `sigVerify=true` est incompatible avec
`replaceRecentBlockhash=true` ;
- le résultat courant de simulation comporte de nombreux champs optionnels (`logs`, `accounts`, unités consommées, return data, inner instructions,
replacement blockhash, fee, balances, token balances, loaded addresses) qui doivent être préservés sans décodage Program.
## Gate de sizing
Question obligatoire :
```text
Les 11 wrappers Transactions, leurs DTOs/wires, les règles write/simulation, les tests et la documentation peuvent-ils être clôturés proprement dans cette session ?
```
Réponse :
```text
OUI.
```
Aucun split de release n'est nécessaire. Le volume est inférieur à `0.2.2`, mais trois fils restent volontairement isolés : `getTransaction`, les
WriteSubmission/no-resend et `simulateTransaction`. Si une tranche réelle dépasse le budget KSP d'environ 1520 minutes, une prerelease
supplémentaire sera créée dans `0.2.3` sans déplacer silencieusement une méthode vers `0.2.4`.
## Décision dépendances et encodages
Aucune nouvelle dépendance n'est ajoutée à `pre.001` :
```text
base64 NON
bs58 NON
wincode NON
solana-client NON
crate RPC/SDK Solana haut niveau NON
```
Transport peut préserver les messages/transactions sérialisés sous forme de chaînes accompagnées d'un enum d'encodage typé. Les validations locales
retenues sont celles qui n'exigent pas de désérialiser la transaction : cardinalités, limites fixes, variantes d'encodage/config autorisées et
incompatibilités de paramètres.
Ajouter uniquement `base64`/`bs58` ne suffirait pas à reproduire correctement les validations runtime actuelles, qui comprennent aussi limites de taille,
désérialisation de message/transaction, versioning et sanitization. Tant qu'aucun besoin KSP concret n'exige ce décodage local, ces contrôles restent la
responsabilité du runtime RPC. Toute future dépendance d'encodage devra être justifiée par un invariant KSP précis et testable.
## Prévision de travail
```text
pre.001 audit officiel + matrice + sécurité + DTOs/wire + dépendances + sizing
pre.002 primitives/configs/results Transactions partagés + fixtures communes
pre.003 reads contextuels : fee/message, latest blockhash, transaction count, blockhash validity
pre.004 prioritization fees + signatures for address + signature statuses
pre.005 getTransaction moderne + compatibilité legacy + transaction/meta/version wire
pre.006 requestAirdrop + sendTransaction + preuves end-to-end no-resend
pre.007 simulateTransaction + résultat riche + invariants de config
pre.008 réaudit final + canaries + smoke opt-in pertinent + README/USAGE + validation + prompt 0.2.4
```
Une prerelease supplémentaire reste autorisée si le budget réel d'une tranche l'exige.
## Fichiers ajoutés
```text
docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md
deltas/0.2.3/pre.001.md
```
## Fichiers modifiés
```text
Cargo.toml
ROADMAP.md
docs/000-README.md
docs/plans/000-README.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
```
`docs/000-README.md` synchronise aussi son arbre de validation avec le fichier `docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md` déjà
présent dans la release stable mais omis de cet index.
## Fichiers supprimés
Aucun.
## Fichiers volontairement inchangés
```text
CHANGELOG.md
docs/plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md
docs/plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md
docs/validation/003-V0_2_1_ONCHAIN_HTTP.md
docs/validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-onchain-transport-lib/src/**
crates/ksp-onchain-transport-lib/unit_tests/**
crates/ksp-onchain-transport-lib/tests/**
```
Les anciens deltas restent historiques et ne sont pas réécrits.
## Validations exécutées
- relecture des sources KSP obligatoires du prompt `0.2.3` ;
- inspection de l'archive stable KSP fournie et de la surface Transport `0.2.2` ;
- confirmation locale que le registry expose toujours `52 current / 14 historical` et partitionne les releases `4 / 22 / 11 / 15` ;
- confirmation locale que les 11 descriptors `V0_2_3` se répartissent `8 Read/RetrySafe + 2 WriteSubmission/NeverAfterDispatch + 1 Simulation/RetrySafe` ;
- inspection de `execute_standard_rpc`, du mapping de dispatch et de la retry policy centrale pour confirmer l'arrêt après dispatch ambigu d'une
WriteSubmission ;
- consultation de l'index HTTP Solana officiel courant, de `Solana RPC JSON Structures` et des 11 pages Transactions ;
- consultation de la navigation Deprecated officielle courante ;
- consultation des sources primaires Agave liées par la documentation HTTP et cross-audit du tag `v4.2.1` pour configs, cardinalités, unions wire,
champs optionnels, simulation et validations runtime ;
- confirmation du maintien de la compatibilité legacy `getTransaction` sans la présenter comme forme recommandée ;
- contrôle de l'absence de nouvelle dépendance d'encodage/RPC dans `Cargo.toml` et dans le manifest Transport ;
- contrôle que `pre.001` ne modifie aucune source/test Rust ni `CHANGELOG.md`.
## Validations non exécutées
Le sandbox courant ne fournit pas le binaire `cargo` (`command -v cargo` ne retourne aucun chemin). Les validations Cargo suivantes n'ont donc pas
été exécutées ici et doivent être rejouées sur le checkout de développement avant commit :
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
```
Aucun `cargo tree` n'est nécessaire dans cette tranche car aucune dépendance ni feature n'a changé. Les quatre vues `cargo tree` du prompt restent
obligatoires à la clôture de `0.2.3` et lors de toute prerelease qui modifierait une dépendance/feature.
L'archive KSP fournie ne contient pas `.git`; le commit attendu après application et validations suit `VER-GIT-001` :
```text
v0.2.3-pre.001
```
## Questions ouvertes
Aucune question bloquante pour `pre.002`.
Les noms Rust définitifs des DTOs restent ajustables pendant l'implémentation, mais les invariants wire, cardinalités, compatibilités et frontières de
sécurité fixés par le plan `010` ne doivent pas être relâchés pour simplifier artificiellement les wrappers.
## Suite
`0.2.3-pre.002` : introduire les primitives/configs/results Transactions partagés et les fixtures déterministes communes avant les premiers wrappers
Transactions.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/000-README.md -->
<!-- version: 27 -->
<!-- version: 28 -->
# Documentation KSP
@@ -41,12 +41,14 @@ docs/
│ ├── 006-V0_1_4_CONFIG_DESKTOP_PLAN.md
│ ├── 007-V0_2_0_SERIES_PLANNING.md
│ ├── 008-V0_2_1_ONCHAIN_HTTP_PLAN.md
── 009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md
── 009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md
│ └── 010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md
├── validation/
│ ├── 000-README.md
│ ├── 001-V0_1_4_CONFIG_DESKTOP.md
│ ├── 002-V0_2_0_SERIES_PLANNING.md
── 003-V0_2_1_ONCHAIN_HTTP.md
── 003-V0_2_1_ONCHAIN_HTTP.md
│ └── 004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md
└── rules/
├── FILE_CONTRACTS.md
├── PROMPT_STRUCTURE.md
@@ -63,7 +65,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) ouvre la release suivante `0.2.3 — HTTP Transactions`.
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) ouvre `0.2.3 — HTTP Transactions`. Son plan actif [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md), établi par `0.2.3-pre.001`, confirme les 11 méthodes, les contrats wire, la classification write/simulation et le gate de sizing avant implémentation.
`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/plans/000-README.md -->
<!-- version: 34 -->
<!-- version: 35 -->
# Plans KSP
@@ -18,6 +18,7 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou
- [`007-V0_2_0_SERIES_PLANNING.md`](007-V0_2_0_SERIES_PLANNING.md) — plan historique clôturé de la release stable `0.2.0`, ouvert par `pre.001`, consolidé par `pre.002`, audité par `pre.003` puis publié par `rel.001`; il fixe l'ordre `0.2.1+`, la stratégie RAW/CORE/DECODE/SPECIALIZED, les vertical slices Program et le prompt `0.2.1`.
- [`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 actif de `0.2.3 — HTTP Transactions`, ouvert par `pre.001`; il confirme les 11 méthodes, la classification `8 Read / 2 WriteSubmission / 1 Simulation`, les wires transactionnels et le no-resend après dispatch ambigu.
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: 36 -->
<!-- version: 37 -->
# Séquence des releases fonctionnelles KSP
@@ -392,6 +392,8 @@ Chaque `pre.001` réaudite la documentation officielle actuelle. Les méthodes D
`0.2.2-pre.001` a confirmé la partition de 22 méthodes et son fix documentaire a recoupé les formes wire avec Agave v4.2.1. Les tranches `pre.002``pre.006` ont livré les DTOs puis les 5 Accounts, 5 Tokens et 12 Cluster. `pre.007`, puis `pre.007-fix.001` et `pre.007-fix.002`, ont fermé les canaries exactes 22/22, le smoke Devnet Transport pur, README/USAGE, la matrice de validation `004` et le prompt `0.2.3`. `0.2.2-rel.001` publie cette surface stable après validation du workspace et des deux smokes Devnet. Le smoke cross-crates Config -> Transport de `0.2.1` reste séparé et transitoire.
`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. Aucun `base64`, `bs58`, `wincode` ni client RPC Solana supplémentaire nest ajouté à louverture : les payloads sérialisés restent opaques dans Transport tant quun besoin de décodage local nest pas démontré. Le plan détaillé actif est `docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`.
## `0.2.5` — Wallet foundation
Mission : créer `ksp-wallet-lib` et le format `.kspwallet`.

View File

@@ -0,0 +1,636 @@
<!-- file: docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md -->
<!-- version: 2 -->
# Plan `0.2.3` — HTTP Transactions
## Statut
Ce plan est ouvert par `0.2.3-pre.001` sur la base stable `v0.2.2`.
`0.2.1` a stabilisé la foundation HTTP Solana et quatre wrappers typés canari. `0.2.2` a ajouté les 22 wrappers Accounts/Tokens/Cluster,
les DTOs wire communs, le smoke Devnet Transport pur et les canaries exactes de complétude.
La release `0.2.3` complète uniquement les **11 méthodes Transactions** déjà affectées à `HttpRpcCoverageRelease::V0_2_3`. Elle ne crée ni
client HTTP parallèle, ni executor métier de transaction, ni dépendance Transport -> Config/Store/Program.
## Sources normatives réauditées le 2026-08-18
Sources documentaires principales :
```text
https://solana.com/docs/rpc/http
https://solana.com/docs/rpc/json-structures
```
Pages Transaction réauditées :
```text
https://solana.com/docs/rpc/http/getfeeformessage
https://solana.com/docs/rpc/http/getlatestblockhash
https://solana.com/docs/rpc/http/getrecentprioritizationfees
https://solana.com/docs/rpc/http/getsignaturesforaddress
https://solana.com/docs/rpc/http/getsignaturestatuses
https://solana.com/docs/rpc/http/gettransaction
https://solana.com/docs/rpc/http/gettransactioncount
https://solana.com/docs/rpc/http/isblockhashvalid
https://solana.com/docs/rpc/http/requestairdrop
https://solana.com/docs/rpc/http/sendtransaction
https://solana.com/docs/rpc/http/simulatetransaction
```
Sources primaires Agave utilisées pour lever les ambiguïtés du wire et des limites runtime :
```text
https://github.com/anza-xyz/agave/blob/v4.2.1/rpc/src/rpc.rs
https://github.com/anza-xyz/agave/blob/v4.2.1/rpc-client-types/src/config.rs
https://github.com/anza-xyz/agave/blob/v4.2.1/rpc-client-types/src/request.rs
https://github.com/anza-xyz/agave/blob/v4.2.1/rpc-client-types/src/response.rs
https://github.com/anza-xyz/agave/blob/v4.2.1/transaction-status-client-types/src/lib.rs
```
Les liens `Source` du site RPC Solana consultés pointent encore vers Agave `v3.1.8` et les exemples affichent encore `apiVersion: 3.1.8`.
Comme pour la clôture `0.2.2`, KSP recoupe donc la documentation publique avec Agave `v4.2.1`, dont le workspace déclare la version `4.2.1`,
sans prendre de dépendance sur ses crates RPC/client.
## Audit global et périmètre confirmé
L'index HTTP Solana courant contient toujours **52 méthodes** et sa catégorie Transactions contient exactement :
```text
getFeeForMessage
getLatestBlockhash
getRecentPrioritizationFees
getSignaturesForAddress
getSignatureStatuses
getTransaction
getTransactionCount
isBlockhashValid
requestAirdrop
sendTransaction
simulateTransaction
```
La navigation Deprecated officielle conserve les **14 méthodes historiques** déjà enregistrées dans KSP :
```text
confirmTransaction
getConfirmedBlock
getConfirmedBlocks
getConfirmedBlocksWithLimit
getConfirmedSignaturesForAddress2
getConfirmedTransaction
getFeeCalculatorForBlockhash
getFeeRateGovernor
getFees
getRecentBlockhash
getSignatureConfirmation
getSignatureStatus
getSnapshotSlot
getStakeActivation
```
Aucune méthode Transaction n'est ajoutée, supprimée ou déplacée par rapport à la partition KSP stable `0.2.2` :
```text
0.2.1 exact = 4
0.2.2 exact = 22
0.2.3 exact = 11
0.2.4 reste = 15
```
Les onze pages courantes ciblées restent des méthodes HTTP courantes. `getTransaction` conserve une **forme de requête moderne** par objet de
configuration et une **forme legacy de compatibilité** où le second paramètre est directement la chaîne d'encoding ; la documentation actuelle
marque explicitement cette forme bare comme dépréciée et recommande l'objet.
## Gate de sizing obligatoire
Question :
```text
Les 11 wrappers Transactions, leurs DTOs/wires, les règles write/simulation, les tests et la documentation peuvent-ils être clôturés proprement dans cette session ?
```
Réponse :
```text
OUI.
```
Le périmètre est plus petit que `0.2.2`, mais les méthodes sont plus hétérogènes. Le sizing reste acceptable en isolant les trois zones coûteuses :
1. `getTransaction` et son wire encoding/version/meta ;
2. `requestAirdrop` + `sendTransaction` et les preuves de no-resend après dispatch ambigu ;
3. `simulateTransaction` et son résultat riche.
Aucun split de release n'est donc nécessaire à `pre.001`. Si une tranche réelle dépasse 1520 minutes, une prerelease supplémentaire est
ajoutée dans `0.2.3` sans déplacer silencieusement une méthode vers `0.2.4`.
## Classification de sécurité confirmée
La metadata KSP existante reste correcte après réaudit :
```text
8 Read / RetrySafe
2 WriteSubmission / NeverAfterDispatch : requestAirdrop, sendTransaction
1 Simulation / RetrySafe : simulateTransaction
```
La règle centrale reste normative :
> une `WriteSubmission` ne doit jamais être resoumise automatiquement lorsque KSP ne peut pas prouver que la tentative précédente n'a pas été dispatchée.
Un timeout après envoi, un HTTP temporaire reçu après dispatch, un rate-limit reçu après dispatch ou une rupture dont l'état de dispatch est
ambigu arrêtent donc la boucle de retry Transport pour `requestAirdrop` et `sendTransaction`.
Une erreur explicitement classée `NotDispatched` peut encore suivre la policy centrale existante ; aucun wrapper write ne possède sa propre boucle.
Le champ RPC `sendTransaction.maxRetries` est **distinct** : il configure les retransmissions du noeud RPC après acceptation de la requête et ne
constitue jamais une autorisation de retry HTTP côté KSP.
`simulateTransaction` n'émet pas la transaction sur le réseau et reste `Simulation / RetrySafe` dans la metadata Transport.
## Flux architectural obligatoire
Tous les wrappers de cette release suivent le flux unique :
```text
wrapper typed
-> descriptor central
-> execute_standard_rpc
-> pool/admission
-> executor HTTP
-> validation JSON-RPC
-> decode typed
```
Restent interdits :
```text
wrapper -> reqwest direct
wrapper -> nouveau client HTTP
wrapper -> retry/deadline/admission bypass
Transport -> Config
Transport -> Store
Transport -> Program
Transport -> tracing direct
```
Les wrappers réutilisent `SolanaCommitment`, `SolanaContextConfig`, `SolanaRpcContext`, `SolanaRpcResponse<T>` et les erreurs KSP existantes lorsque
leur contrat s'applique.
## Décision dépendances et payloads sérialisés
### Décision `pre.001`
Aucune nouvelle dépendance n'est ajoutée :
```text
base64 NON
bs58 NON
wincode NON
solana-client NON
crate RPC SDK NON
```
Motif : les trois entrées sérialisées de cette release peuvent être transportées comme **chaînes encodées opaques** accompagnées d'un encoding
typé. KSP n'a pas besoin de désérialiser un message ou une transaction pour construire la requête, appliquer la policy de retry, préserver le
wire ou décoder la réponse.
Agave réalise des contrôles de décodage, de désérialisation, de sanitization et de taille de transaction. Les reproduire complètement côté KSP
impliquerait davantage que `base64`/`bs58` : cela rapprocherait Transport d'un codec transactionnel et d'un SDK wire complet sans besoin fonctionnel
établi. `pre.001` ne crée donc pas cette responsabilité.
KSP applique en revanche avant I/O les invariants qui ne nécessitent aucun décodage du payload : cardinalités documentées/runtime, encodings
acceptés par l'opération, formes de config, incompatibilités de flags et paramètres structuraux.
Cette décision peut être réouverte dans une future tranche si un besoin concret exige une validation locale des bytes sérialisés. L'ajout devra
alors être borné, déclaré dans `[workspace.dependencies]` et justifié par un test qui démontre la valeur de la validation locale.
### Encodings à distinguer
Pour les **entrées** `sendTransaction` et `simulateTransaction`, la source Agave actuelle accepte les encodings binaires `base58` et `base64` ;
les encodings JSON ne sont pas des formats d'entrée valides pour ces deux opérations.
`getFeeForMessage` reçoit une chaîne base64. La page publique documente les messages legacy et v0. KSP ne parse pas la version du message et ne
fige donc pas artificiellement le type public sur une liste de versions sérialisées que le runtime pourrait faire évoluer.
Pour la **sortie** `getTransaction`, le wire doit rester plus large : `base58`, `base64`, `json`, `jsonParsed`, ainsi que les formes legacy encore
acceptées/auditées. Les formes encodées et JSON ne doivent pas être écrasées dans un seul `String` ambigu.
## Matrice exacte des 11 méthodes
| Méthode | Paramètres ordonnés / config | Résultat à préserver | Validation / particularités |
|-------------------------------|-------------------------------------------------------|--------------------------------------------------|--------------------------------------------------------------------------------|
| `getFeeForMessage` | `messageBase64`, `SolanaContextConfig?` | `SolanaRpcResponse<Option<u64>>` | message base64 opaque ; `null` préservé |
| `getLatestBlockhash` | `SolanaContextConfig?` | contexte + `{ blockhash, lastValidBlockHeight }` | blockhash wire non vide ; contexte conservé |
| `getRecentPrioritizationFees` | `Vec<Pubkey>?` | `Vec<{ slot, prioritizationFee }>` | maximum 128 adresses ; ordre serveur conservé |
| `getSignaturesForAddress` | `Pubkey`, config pagination | `Vec<SignatureInfo>` | `limit` `1..=1000`; newest -> oldest; nulls préservés |
| `getSignatureStatuses` | `Vec<signature>`, config history? | contexte + `Vec<Option<SignatureStatus>>` | maximum 256; positions/nulls conservés; tableau vide accepté par Agave courant |
| `getTransaction` | signature, config moderne **ou** encoding bare legacy | `Option<ConfirmedTransaction>` | transaction absente = `null`; encoding/version/meta lossless |
| `getTransactionCount` | `SolanaContextConfig?` | `u64` | forme simple, config contextuelle |
| `isBlockhashValid` | blockhash, `SolanaContextConfig?` | `SolanaRpcResponse<bool>` | blockhash passé tel quel au runtime sauf invariant KSP non ambigu |
| `requestAirdrop` | `Pubkey`, lamports, config? | signature | `WriteSubmission`; aucun resend après dispatch ambigu |
| `sendTransaction` | transaction encodée, config? | première signature | `base58/base64`; `maxRetries` est node-side; no-resend KSP |
| `simulateTransaction` | transaction encodée, config? | contexte + résultat simulation | `base58/base64`; `sigVerify` incompatible avec `replaceRecentBlockhash` |
## DTOs et wires communs prévus
Les noms Rust exacts restent ajustables à `pre.002`, mais les responsabilités suivantes sont figées.
### Blockhash et latest blockhash
Le résultat de `getLatestBlockhash` conserve :
```text
blockhash String/newtype wire KSP
lastValidBlockHeight u64
```
Le même petit objet `{ blockhash, lastValidBlockHeight }` peut être réutilisé lorsque `simulateTransaction` retourne un `replacementBlockhash`.
Aucune primitive cryptographique supplémentaire n'est nécessaire pour le transporter.
### Signature information
`getSignaturesForAddress` conserve au minimum :
```text
signature String/newtype KSP
slot u64
err JSON transaction error nullable
memo Option<String>
blockTime Option<i64>
confirmationStatus Option<Processed|Confirmed|Finalized>
transactionIndex Option<u32>
```
La page HTTP actuelle ne liste pas `transactionIndex`, mais Agave `v4.2.1` l'expose comme champ optionnel avec `serde(default)` et omission lorsque
absent. KSP doit donc l'accepter sans le rendre obligatoire, afin de ne pas perdre une donnée runtime actuelle ni casser les providers qui ne
l'émettent pas encore.
`err` reste un contrat transaction-error wire et ne devient pas un modèle Program. Une représentation `serde_json::Value` bornée à cette frontière
est acceptable tant que KSP ne possède pas encore le codec générique des erreurs de transaction.
### Signature status
`getSignatureStatuses` préserve l'ordre exact du tableau d'entrée. Chaque position de sortie est :
```text
Option<SignatureStatus>
```
Un statut présent conserve :
```text
slot u64
confirmations Option<usize/u64>
err transaction error nullable
status forme legacy de résultat, encore présente sur le wire
confirmationStatus Option<Processed|Confirmed|Finalized>
```
La forme `status` historique à l'intérieur de l'objet courant n'est pas confondue avec les anciennes **méthodes RPC** Deprecated du registre.
KSP peut la préserver de manière lossless sans la recommander comme nouvelle API métier.
### Transaction encoding/config
Le contrat moderne `getTransaction` doit disposer d'un objet de config contenant :
```text
commitment Option<SolanaCommitment>
encoding Option<TransactionEncoding>
maxSupportedTransactionVersion Option<u8>
```
La compatibilité auditée garde en plus une forme legacy explicite :
```text
getTransaction(signature, "<encoding>")
```
Cette API legacy doit être nommée/annotée de manière à ne pas sembler être la voie recommandée. Le descriptor existant
`StableWithDeprecatedLegacy` reste correct.
Le résultat confirmé garde un top-level typé :
```text
slot u64
blockTime Option<i64>
transaction EncodedTransaction
meta Option<transaction-meta wire>
version legacy | number
```
`EncodedTransaction` doit préserver les différentes formes réellement sérialisées :
```text
objet JSON/jsonParsed
chaîne legacy binaire
[string, "base58" | "base64"]
```
KSP ne doit pas dupliquer tout `solana-transaction-status-client-types` pour obtenir cette union. Les sous-structures transaction/message/meta qui
sont riches, évolutives ou dépendantes de `jsonParsed` peuvent rester lossless via des DTOs étroits + `serde_json::Value` aux frontières prévues.
Le meta doit au minimum respecter la distinction **absent/null/présent** imposée par le wire et ne jamais inventer des listes ou zéros lorsque le
provider omet une donnée optionnelle.
### `getRecentPrioritizationFees`
Le paramètre optionnel est un tableau d'adresses. La documentation actuelle fixe un maximum de **128** et précise que, lorsqu'il est fourni, les
samples correspondent aux transactions ayant verrouillé toutes ces adresses en writable. La cache d'un noeud conserve actuellement jusqu'à
150 blocs de données de prioritization fees ; ce nombre décrit le runtime/cache et n'est pas une cardinalité de réponse à imposer côté client.
Le résultat conserve simplement :
```text
slot u64
prioritizationFee u64
```
### Pagination `getSignaturesForAddress`
La config prévue conserve :
```text
commitment Option<SolanaCommitment>
minContextSlot Option<u64>
limit Option<usize>
before Option<String/newtype signature>
until Option<String/newtype signature>
```
Agave `v4.2.1` applique `1000` par défaut et refuse `limit == 0` ou `limit > 1000`. KSP peut donc rejeter cette cardinalité avant I/O sans dépendance
supplémentaire.
### `getSignatureStatuses`
La requête conserve :
```text
signatures Vec<String/newtype signature>
searchTransactionHistory Option<bool>
```
La documentation et Agave bornent le tableau à **256** signatures. La source actuelle refuse uniquement `> 256`; un tableau vide reste donc une
forme valide à ne pas interdire arbitrairement.
Quand `searchTransactionHistory` est absent/faux, le noeud recherche seulement son cache récent. KSP transporte l'option sans transformer
silencieusement l'appel en recherche historique coûteuse.
## Write submissions
### `requestAirdrop`
La config courante conserve :
```text
commitment Option<SolanaCommitment>
recentBlockhash Option<String>
```
Le résultat est une signature de transaction. L'appel déclenche la création/soumission d'une transaction de faucet : il reste donc
`WriteSubmission / NeverAfterDispatch` même si la réponse n'est qu'une signature.
Aucun retry ad hoc n'est autorisé dans le wrapper. Un résultat ambigu après dispatch remonte au caller.
### `sendTransaction`
Transport reçoit une transaction **déjà construite et signée**. Il ne devient ni builder, ni signer, ni executor métier.
La config courante conserve :
```text
encoding Option<Base58|Base64>
skipPreflight Option/default false
preflightCommitment Option<SolanaCommitment>
maxRetries Option<usize>
minContextSlot Option<u64>
```
Le runtime RPC vérifie normalement les signatures et simule la transaction avant relay lorsque `skipPreflight` est faux. Une réponse réussie ne
constitue pas une confirmation on-chain ; le résultat est la première signature embarquée dans la transaction.
La distinction de retry doit rester explicite :
```text
sendTransaction.maxRetries = retry/retransmission du noeud RPC
KSP HttpRetrySettings = retry de la requête HTTP
```
La première peut être configurée par l'appel. La seconde reste bloquée après tout dispatch ambigu grâce au descriptor central.
## `simulateTransaction`
La simulation conserve les options Agave actuelles :
```text
commitment Option<SolanaCommitment>
encoding Option<Base58|Base64>
replaceRecentBlockhash bool/default false
sigVerify bool/default false
minContextSlot Option<u64>
innerInstructions bool/default false
accounts Option<SimulationAccountsConfig>
```
L'invariant runtime courant :
```text
sigVerify == true && replaceRecentBlockhash == true -> invalid params
```
KSP doit le rejeter avant I/O, car il est déterministe et ne nécessite aucun décodage de la transaction.
La sous-config `accounts` conserve l'encoding Account compatible et un tableau d'adresses. Agave rejette actuellement les encodings Account
`binary/base58` pour ce retour et borne dynamiquement le nombre demandé au nombre de comptes de la transaction. Comme KSP ne décode pas la
transaction en `0.2.3`, cette limite dynamique reste une validation runtime/provider et n'est pas réimplémentée avec une dépendance transactionnelle.
Le résultat de simulation Agave `v4.2.1` contient notamment, sous forme optionnelle lorsque pertinente :
```text
err
logs
accounts
unitsConsumed
loadedAccountsDataSize
returnData
innerInstructions
replacementBlockhash
fee
preBalances
postBalances
preTokenBalances
postTokenBalances
loadedAddresses
```
Transport doit préserver ces champs et leurs `null`/absences sans décoder les instructions ou retours Program en modèles métier.
## Erreurs et validations avant I/O
Les wrappers réutilisent le domaine d'erreur KSP. Les contrôles locaux ciblés comprennent au minimum :
```text
getRecentPrioritizationFees : <= 128 adresses
getSignaturesForAddress : limit 1..=1000 quand fourni
getSignatureStatuses : <= 256 signatures
sendTransaction : encoding d'entrée binaire supporté
simulateTransaction : encoding d'entrée binaire supporté
simulateTransaction : sigVerify XOR replaceRecentBlockhash pour le couple interdit
```
Les validations nécessitant de décoder/sanitizer les bytes de message/transaction restent côté RPC pour cette release.
Les erreurs JSON-RPC significatives — invalid params, min-context non atteint, transaction non trouvée sous forme `null`, preflight failure,
transaction history indisponible, unsupported transaction version — doivent être couvertes par fixtures lorsque la méthode correspondante peut
les produire. KSP ne convertit pas une erreur RPC applicative en retry de transport.
## Stratégie de tests
Chaque wrapper possède des fixtures HTTP locales déterministes qui vérifient selon son contrat :
- méthode et tableau `params` exacts, dans l'ordre exact ;
- omission correcte du paramètre config lorsqu'il est absent ;
- success typed ;
- `null` / champ optionnel / champ omis ;
- erreur JSON-RPC ;
- cardinalité rejetée avant I/O lorsque KSP la connaît sans décodage ;
- forme legacy `getTransaction` séparée de la forme moderne ;
- `maxSupportedTransactionVersion` ;
- encodings transaction ;
- positions `null` de `getSignatureStatuses` ;
- ordre newest-first de `getSignaturesForAddress` ;
- champs de simulation riches et optionnels.
### Tests write/no-resend
Les tests `requestAirdrop` et `sendTransaction` ne doivent pas se contenter de tester la fonction pure `evaluate_transport_retry` déjà existante.
Ils doivent exercer le chemin wrapper -> executor avec un serveur fixture capable de compter les requêtes et démontrer au minimum :
```text
connection failure prouvée NotDispatched -> policy centrale applicable
HTTP 429 après dispatch -> une seule soumission write
HTTP 5xx temporaire après dispatch -> une seule soumission write
timeout/issue ambiguë après dispatch -> aucune seconde soumission automatique
```
L'objectif n'est pas de créer une policy parallèle dans les wrappers, mais de prouver que les descriptors write utilisent réellement la policy
centrale dans l'exécution standard.
### Simulation
`simulateTransaction` reste retry-safe. Les fixtures doivent donc vérifier la config, l'incompatibilité `sigVerify/replaceRecentBlockhash`, les
résultats partiels/nullables et au moins un scénario de retry transport sûr déjà supporté par l'executor commun.
## Canaries de complétude à conserver
À toute la release :
```text
current == 52
historical == 14
0.2.1 exact == 4
0.2.2 exact == 22
0.2.3 exact == 11
0.2.4 exact == 15
```
Aucun wrapper `0.2.4` n'est déclaré typed-complete avant sa release.
La canarie `0.2.3 exact == 11` ne devient réellement verte qu'une fois les onze wrappers publics et leurs tests de surface en place. Le registry
peut déjà contenir leurs descriptors sans que cela ne compte comme couverture typée.
## Smokes live
Les fixtures locales restent normatives pour la correctness des wrappers. Les smokes live sont opt-in et ne les remplacent pas.
La décision finale de smoke est réservée à la prerelease de clôture. Toute extension doit respecter l'ownership déjà stabilisée :
- un smoke **Transport pur** qui construit ses settings programmatiquement peut rester sous `ksp-onchain-transport-lib` ;
- un nouveau smoke cross-crates `Config + Transport + ...` ne doit pas être ajouté sous Config comme destination générale ;
- `requestAirdrop` et `sendTransaction` ne seront pas exercés live sans justification forte, car un smoke de lecture/simulation suffit à valider la
route Transaction sans introduire d'effet de bord ou de dépendance faucet/provider.
Un candidat raisonnable pour la clôture est un smoke Transport pur combinant `getLatestBlockhash` et une lecture Transaction déterministe ; une
simulation live n'est retenue que si une fixture transactionnelle stable peut être fournie sans déplacer la construction/signature métier dans
Transport.
## Prévision souple des prereleases
```text
pre.001 audit officiel/Agave + matrice + sécurité + wire/deps + sizing
pre.002 primitives/configs/results Transactions partagés + fixtures communes
pre.003 getFeeForMessage + getLatestBlockhash + getTransactionCount + isBlockhashValid
pre.004 getRecentPrioritizationFees + getSignaturesForAddress + getSignatureStatuses
pre.005 getTransaction moderne + compatibilité legacy + transaction/meta/version wire
pre.006 requestAirdrop + sendTransaction + preuves end-to-end no-resend
pre.007 simulateTransaction + résultat riche + invariants de config
pre.008 réaudit final + canaries + smoke opt-in si pertinent + README/USAGE + validation + prompt 0.2.4
```
Une prerelease intermédiaire peut être ajoutée si le volume réel d'une tranche dépasse le budget. La dernière prerelease reste une tranche de
clôture documentaire/validation et ne doit pas devenir une implémentation massive tardive.
## Critères de clôture de `0.2.3`
La release ne peut être candidate stable que si :
- les 11 wrappers sont publics et passent tous par `execute_standard_rpc` ;
- les trois classes de sécurité restent exactes `8 Read / 2 WriteSubmission / 1 Simulation` ;
- `requestAirdrop` et `sendTransaction` prouvent l'absence de resend automatique après dispatch ambigu ;
- `getTransaction` préserve la forme moderne et la compatibilité legacy explicitement dépréciée ;
- `maxSupportedTransactionVersion` est préservé ;
- les cardinalités 128 / 1000 / 256 sont testées selon leur contrat exact ;
- les tableaux et `null` positionnels sont préservés ;
- `simulateTransaction` préserve son config/result sans décodage Program ;
- les canaries 52/14/4/22/11/15 passent ;
- aucune dépendance Transport -> Config/Store/Program/tracing direct n'est introduite ;
- README/USAGE, plan, matrice de validation et prompt `0.2.4` sont synchronisés ;
- les validations Cargo de clôture et graphes de dépendances ont une preuve opérateur ou une exécution réelle ;
- `CHANGELOG.md` reste réservé à `0.2.3-rel.001` ;
- la release stable finale reste strictement publicationnelle.
## Validations prévues pendant le développement
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
```
## Validations prévues à la clôture
```bash
cargo fmt --all
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-onchain-transport-lib
cargo test -p ksp-config-lib
cargo test -p ksp-core-lib
cargo test -p ksp-app-config-desk
cargo test --workspace
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
```
Aucune commande n'est déclarée réussie sans exécution réelle ou preuve opérateur.
## Résultat de `pre.001`
`pre.001` s'arrête volontairement avant toute source Rust fonctionnelle :
- périmètre 11/11 confirmé ;
- classification sécurité confirmée ;
- architecture commune confirmée ;
- wire/config/result audités ;
- limites locales/runtime distinguées ;
- aucune nouvelle dépendance justifiée ;
- gate de sizing positif ;
- découpage `pre.002``pre.008` défini.
La tranche suivante peut commencer par les primitives wire communes sans réouvrir le scope de release.