From d06284fca2da2405ea137113dda081f9bdfa5bd9 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Tue, 18 Aug 2026 10:47:19 +0200 Subject: [PATCH] v0.2.3-pre.001 --- Cargo.toml | 4 +- ROADMAP.md | 4 +- deltas/0.2.3/pre.001.md | 205 ++++++ docs/000-README.md | 10 +- docs/plans/000-README.md | 3 +- docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md | 4 +- .../010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md | 636 ++++++++++++++++++ 7 files changed, 856 insertions(+), 10 deletions(-) create mode 100644 deltas/0.2.3/pre.001.md create mode 100644 docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md diff --git a/Cargo.toml b/Cargo.toml index 6b79c32..ca46a7d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/ROADMAP.md b/ROADMAP.md index 7a08d1b..a2de861 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,5 @@ - + # 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 l’absence 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. diff --git a/deltas/0.2.3/pre.001.md b/deltas/0.2.3/pre.001.md new file mode 100644 index 0000000..a03f318 --- /dev/null +++ b/deltas/0.2.3/pre.001.md @@ -0,0 +1,205 @@ + + + +# 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 15–20 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. diff --git a/docs/000-README.md b/docs/000-README.md index 8afafb4..659fa51 100644 --- a/docs/000-README.md +++ b/docs/000-README.md @@ -1,5 +1,5 @@ - + # 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. diff --git a/docs/plans/000-README.md b/docs/plans/000-README.md index f1b01f2..32f870d 100644 --- a/docs/plans/000-README.md +++ b/docs/plans/000-README.md @@ -1,5 +1,5 @@ - + # 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. diff --git a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md index 31448d5..bdd358a 100644 --- a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md +++ b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md @@ -1,5 +1,5 @@ - + # 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 n’est ajouté à l’ouverture : 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é 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`. diff --git a/docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md b/docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md new file mode 100644 index 0000000..ce93222 --- /dev/null +++ b/docs/plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md @@ -0,0 +1,636 @@ + + + +# 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 15–20 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` 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>` | message base64 opaque ; `null` préservé | +| `getLatestBlockhash` | `SolanaContextConfig?` | contexte + `{ blockhash, lastValidBlockHeight }` | blockhash wire non vide ; contexte conservé | +| `getRecentPrioritizationFees` | `Vec?` | `Vec<{ slot, prioritizationFee }>` | maximum 128 adresses ; ordre serveur conservé | +| `getSignaturesForAddress` | `Pubkey`, config pagination | `Vec` | `limit` `1..=1000`; newest -> oldest; nulls préservés | +| `getSignatureStatuses` | `Vec`, config history? | contexte + `Vec>` | maximum 256; positions/nulls conservés; tableau vide accepté par Agave courant | +| `getTransaction` | signature, config moderne **ou** encoding bare legacy | `Option` | transaction absente = `null`; encoding/version/meta lossless | +| `getTransactionCount` | `SolanaContextConfig?` | `u64` | forme simple, config contextuelle | +| `isBlockhashValid` | blockhash, `SolanaContextConfig?` | `SolanaRpcResponse` | 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 +blockTime Option +confirmationStatus Option +transactionIndex Option +``` + +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 +``` + +Un statut présent conserve : + +```text +slot u64 +confirmations Option +err transaction error nullable +status forme legacy de résultat, encore présente sur le wire +confirmationStatus Option +``` + +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 +encoding Option +maxSupportedTransactionVersion Option +``` + +La compatibilité auditée garde en plus une forme legacy explicite : + +```text +getTransaction(signature, "") +``` + +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 +transaction EncodedTransaction +meta Option +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 +minContextSlot Option +limit Option +before Option +until Option +``` + +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 +searchTransactionHistory Option +``` + +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 +recentBlockhash Option +``` + +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 +skipPreflight Option/default false +preflightCommitment Option +maxRetries Option +minContextSlot Option +``` + +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 +encoding Option +replaceRecentBlockhash bool/default false +sigVerify bool/default false +minContextSlot Option +innerInstructions bool/default false +accounts Option +``` + +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.