v0.2.4-pre.001-fix.001

This commit is contained in:
2026-08-18 19:51:00 +02:00
parent c03a3eaf5d
commit cb19742cf7
2 changed files with 300 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Plan `0.2.4` — HTTP Blocks + Economics + compliance HTTP finale
@@ -83,6 +83,24 @@ 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/response.rs
```
SIMDs primaires ciblés par l'audit `KSP-TRANSPORT-007` :
```text
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0096-reward-collected-priority-fee-in-entirety.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0118-partitioned-epoch-reward-distribution.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0123-block-revenue-distribution.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0180-vote-account-leader-schedule.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0185-vote-account-v4.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0186-loaded-transaction-data-size-specification.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0291-commission-rate-in-basis-points.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0298-bank-hash-in-block-footer.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0307-add-block-footer.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0490-upgrade-stake-to-v5.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0550-double-disinflation.md
https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0553-resource-fee-burn.md
```
## Inventaire officiel réaudité
L'index HTTP Solana actuel contient toujours exactement les catégories suivantes :
@@ -139,25 +157,76 @@ Pour `0.2.4`, cela impose notamment :
- de ne pas réduire `getBlocks` à la seule forme `[start, end, config]` ;
- de conserver le bare encoding legacy de `getBlock` sans le présenter comme forme recommandée ;
- de préserver `transactionDetails = full | signatures | none | accounts` et les conséquences sur la présence des champs de bloc ;
- de préserver `transactionDetails = full ou signatures ou none ou accounts` et les conséquences sur la présence des champs de bloc ;
- de préserver les champs wire riches des transactions/meta/rewards sans importer un client RPC Solana haut niveau ;
- de conserver les `null` positionnels de `getInflationReward` et le champ runtime `commissionBps` lorsqu'il est présent ;
- de ne pas inventer de limite d'adresses `getInflationReward` si aucune limite sémantique fixe n'est établie par la documentation/runtime courant ; la limite générale de taille de requête HTTP n'est pas transformée artificiellement en cardinalité métier KSP.
## Audit SIMD lié à `KSP-TRANSPORT-007`
Le statut d'un SIMD n'est pas, à lui seul, le critère d'implémentation de Transport. La règle est la suivante :
- si la baseline Solana/Agave stable expose déjà un paramètre, un champ ou une variante wire provenant d'une évolution SIMD, KSP doit le préserver même si le document SIMD n'a pas encore le statut `Activated` ;
- si un SIMD modifie seulement la sémantique d'une valeur calculée par le runtime sans modifier son wire, KSP ne doit ni recalculer ni figer cette valeur localement ;
- si un SIMD `Draft`/`Review` propose une extension RPC absente de la baseline stable retenue, KSP ne l'invente pas mais l'inscrit dans la watchlist et la réaudite avant le wrapper concerné puis à la compliance finale.
### SIMD applicables à la baseline `v4.2.1`
**SIMD-0118 — Partitioned Epoch Rewards Distribution** est `Activated` et a un impact direct sur `getBlock`. Le wire stable `UiConfirmedBlock` expose `numRewardPartitions` sous forme optionnelle. La future structure de bloc KSP doit donc :
- conserver `num_reward_partitions`/`numRewardPartitions` sans synthétiser `0` lorsqu'il est absent ;
- utiliser `SolanaWireField<u64>` ou une représentation équivalente capable de préserver au minimum l'omission, et de ne pas écraser un éventuel `null` de compatibilité ;
- couvrir par fixture un bloc avec `numRewardPartitions` présent et un bloc où le champ est omis ;
- ne pas déduire localement le nombre de partitions à partir des rewards ou de l'epoch.
**SIMD-0291 — Commission Rate in Basis Points** est encore en `Review`, mais Agave stable `v4.2.1` expose déjà les champs RPC de compatibilité correspondants. Il affecte trois surfaces KSP :
- `getVoteAccounts.inflationRewardsCommissionBps` : déjà couvert et testé dans la surface `0.2.2`; aucune remédiation n'est requise ;
- `getBlock.rewards[].commissionBps` : à couvrir dans `0.2.4` avec un reward wire de bloc dédié, distinct du reward d'inflation ;
- `getInflationReward[].commissionBps` : à couvrir dans `0.2.4` dans le DTO `SolanaInflationReward` ou nom final équivalent.
Pour les deux nouveaux wires de rewards, `commission` reste nullable et `commissionBps` doit préserver son caractère optionnel/omis. Les deux structures ne doivent pas être fusionnées artificiellement : le reward de bloc possède notamment `pubkey`, `lamports`, `postBalance` et `rewardType`, alors que le reward d'inflation possède `epoch`, `effectiveSlot`, `amount` et `postBalance`.
La surface `getTransaction` de `0.2.3` ne nécessite pas de correction SIMD-0291 : `meta` est déjà conservé losslessly en `SolanaWireField<serde_json::Value>`, ce qui préserve les rewards imbriqués et leurs extensions sans décodage métier.
### SIMDs déjà absorbés ou sans nouveau wire HTTP
**SIMD-0185 — Vote Account v4** est `Accepted`. Les nouvelles données de vote account peuvent faire évoluer les sous-arbres retournés par les parsers `jsonParsed`, mais `SolanaParsedAccountData.parsed` reste un `serde_json::Value` lossless. Agave `v4.2.1` n'ajoute pas les collector fields de Vote Account v4 au DTO dédié `RpcVoteAccountInfo`; aucune extension spéculative de `SolanaVoteAccountInfo` n'est donc ajoutée maintenant.
**SIMD-0186 — Loaded Transaction Data Size Specification** est `Accepted` et précise la sémantique consensus de la taille de données chargées. La surface `simulateTransaction` de `0.2.3` expose déjà `loadedAccountsDataSize` via `SolanaWireField<u32>` et couvre son omission : aucune nouvelle structure n'est requise. Transport ne doit pas recalculer cette valeur à partir des comptes de la transaction ; il restitue le résultat runtime.
**SIMD-0385 — Transaction V1 Format** est encore en `Review`. Agave `v4.2.1` possède déjà du plumbing V1 dans ses types transaction-status, mais le contrat KSP acquis est volontairement générique : `SolanaTransactionVersion::Number(u8)` n'est pas limité à `0`, et les payloads JSON restent lossless. `0.2.4` doit conserver cette propriété dans `getBlock` et ajouter une canary déterministe avec une version numérique non nulle afin d'interdire une régression vers un modèle `legacy ou v0` seulement.
**SIMD-0096 — Reward full priority fee to validator** est `Activated`, mais change la distribution économique des priority fees sans changer le wire HTTP que KSP doit décoder. Transport continue à restituer les valeurs runtime ; aucune structure spécifique n'est ajoutée.
**SIMD-0550 — Double Disinflation Rate** est en `Review` et précise explicitement que `getInflationRate` et `getInflationGovernor` refléteront la nouvelle schedule sans changement d'API. KSP ne doit donc figer ni `initial`, ni `taper`, ni le taux courant : les DTOs restent des valeurs runtime `f64` et aucune formule d'inflation n'est réimplémentée dans Transport. Un réaudit avant la tranche Economics et à la clôture vérifie qu'aucun nouveau champ n'a été ajouté par la baseline stable.
### Watchlist obligatoire pendant `0.2.4`
**SIMD-0180 — Vote Account Address Keyed Leader Schedule** est en `Review`. Son volet RPC demande explicitement que les endpoints historiques de leader schedule et slot leader continuent à retourner l'identité validator afin de préserver la compatibilité, tout en prévoyant de nouveaux endpoints vote-account-keyed. Le wrapper KSP `getLeaderSchedule` acquis en `0.2.2` ne doit donc pas être modifié spéculativement. En revanche, le réaudit d'inventaire de `pre.009` doit détecter si de nouveaux endpoints ont rejoint la surface HTTP officielle : ce serait alors une évolution de l'inventaire RPC, pas un changement silencieux du wire de `getLeaderSchedule`.
**SIMD-0307 — Add Block Footer** est en `Review` et propose précisément une extension de `getBlock` : option de config `footer` et champs footer dans la réponse. Ces éléments sont absents de `RpcBlockConfig` et `UiConfirmedBlock` dans Agave stable `v4.2.1`; ils ne doivent donc pas être inventés dans `pre.002`. **SIMD-0298 — Add `bank_hash` to block footer** est encore au statut `Idea` et prévoit d'étendre ce même footer avec `bank_hash`. Les deux SIMDs doivent être réaudités ensemble au début de la tranche `getBlock` et à `pre.009`. Si une baseline stable expose alors le footer, `KSP-TRANSPORT-007` impose de couvrir toutes ses options et tous ses champs stables, y compris `bankHash` s'il fait partie du wire effectivement livré.
**SIMD-0490 — Upgrade BPF Stake Program to v5.0.0** est en `Review` et prévoit notamment une hausse du minimum de délégation ainsi que son exposition par le RPC de minimum delegation. Pour `getStakeMinimumDelegation`, KSP doit donc traiter la valeur contextualisée comme une valeur runtime opaque en lamports : aucun minimum `1 lamport`, `1 SOL` ou autre ne doit être codé en dur ou validé côté Transport. Le SIMD sera réaudité avant `pre.007` et à `pre.009`.
**SIMD-0553 — Base Inclusion and Resource-based Fee** est en `Draft`. Il change la sémantique du total de fees de `getFeeForMessage`, `simulateTransaction` et `getTransaction.meta.fee` sans imposer actuellement de changement de forme JSON. Les wrappers `0.2.3` doivent donc rester pass-through/lossless et ne pas recalculer le fee. La compliance finale `52/52` réauditera cette proposition afin de détecter une éventuelle extension stable de schéma apparue pendant la release.
Les SIMDs `Review` liés au block-revenue sharing, notamment SIMD-0123, peuvent modifier à terme la provenance/sémantique des rewards, mais n'ajoutent pas de champ HTTP stable dans la baseline `v4.2.1`. Le reward wire de KSP doit donc rester fidèle aux champs effectivement retournés et ne pas encoder une taxonomie économique non présente sur le wire.
## Matrice Blocks — 10 wrappers
| Méthode | Requête à couvrir | Résultat à préserver | Contraintes / décisions `KSP-TRANSPORT-007` |
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getBlock` | `slot`; second paramètre absent, bare encoding legacy, ou config `{commitment, encoding, transactionDetails, maxSupportedTransactionVersion, rewards}` | `object ou null`; `previousBlockhash`, `blockhash`, `parentSlot`, transactions/signatures/rewards selon config, `numRewardPartitions`, `blockTime`, `blockHeight` | commitment runtime au moins `confirmed`; réutiliser les encodings/version/transaction wire de `0.2.3`; préserver omission vs null ; garder les erreurs runtime de bloc/version comme erreurs RPC, sans les masquer |
| `getBlockCommitment` | `slot` uniquement | `{commitment: array<u64> ou null, totalStake: u64}` | aucune config à inventer ; préserver commitment nullable |
| `getBlockHeight` | config contextuelle optionnelle `{commitment, minContextSlot}` | `u64` | réutiliser `SolanaContextConfig`; `minContextSlot` est transmis tel quel au runtime |
| `getBlockProduction` | config optionnelle `{commitment, identity, range:{firstSlot,lastSlot?}}` | `SolanaRpcResponse<{byIdentity, range}>` | `identity` typée Pubkey ; validation locale déterministe `lastSlot >= firstSlot` lorsque les deux sont fournis ; préserver les couples `[leaderSlots, blocksProduced]` |
| `getBlocks` | `[start]`, `[start,end]`, `[start,config]`, `[start,end,config]` | `Vec<u64>` | commitment au moins `confirmed`; conserver l'overload untagged du second paramètre ; `end < start` donne `[]`; rejeter localement une différence `end-start > 500_000` |
| `getBlocksWithLimit` | `start`, `limit`, config contextuelle optionnelle | `Vec<u64>` | commitment au moins `confirmed`; `limit <= 500_000`; `limit = 0` est valide et donne `[]` |
| `getBlockTime` | `slot` uniquement | `i64 ou null` | préserver l'absence de timestamp ; les cas cleaned/skipped/not available restent des erreurs RPC runtime, pas des valeurs synthétiques |
| `getFirstAvailableBlock` | aucun paramètre | `u64` | requête exacte `params: []` ; aucune config |
| `getRecentPerformanceSamples` | `limit?` | tableau de `{slot,numTransactions,numSlots,samplePeriodSecs,numNonVoteTransactions?}` | défaut runtime `720`; maximum `720`; rejeter avant I/O `limit > 720`; préserver `numNonVoteTransactions` nullable/ancien runtime |
| `minimumLedgerSlot` | aucun paramètre | `u64` | requête exacte `params: []`; conserver les erreurs ledger/runtime |
| Méthode | Requête à couvrir | Résultat à préserver | Contraintes / décisions `KSP-TRANSPORT-007` |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `getBlock` | `slot`; second paramètre absent, bare encoding legacy, ou config `{commitment, encoding, transactionDetails, maxSupportedTransactionVersion, rewards}` | `object ou null`; `previousBlockhash`, `blockhash`, `parentSlot`, transactions/signatures/rewards selon config, `numRewardPartitions`, `blockTime`, `blockHeight` | commitment runtime au moins `confirmed`; réutiliser les encodings/version/transaction wire de `0.2.3`; préserver omission vs null; `numRewardPartitions` suit SIMD-0118; les rewards préservent `commissionBps` de SIMD-0291; garder les erreurs runtime de bloc/version comme erreurs RPC, sans les masquer |
| `getBlockCommitment` | `slot` uniquement | `{commitment: array<u64> ou null, totalStake: u64}` | aucune config à inventer; préserver commitment nullable |
| `getBlockHeight` | config contextuelle optionnelle `{commitment, minContextSlot}` | `u64` | réutiliser `SolanaContextConfig`; `minContextSlot` est transmis tel quel au runtime |
| `getBlockProduction` | config optionnelle `{commitment, identity, range:{firstSlot,lastSlot?}}` | `SolanaRpcResponse<{byIdentity, range}>` | `identity` typée Pubkey; validation locale déterministe `lastSlot >= firstSlot` lorsque les deux sont fournis; préserver les couples `[leaderSlots, blocksProduced]` |
| `getBlocks` | `[start]`, `[start,end]`, `[start,config]`, `[start,end,config]` | `Vec<u64>` | commitment au moins `confirmed`; conserver l'overload untagged du second paramètre; `end < start` donne `[]`; rejeter localement une différence `end-start > 500_000` |
| `getBlocksWithLimit` | `start`, `limit`, config contextuelle optionnelle | `Vec<u64>` | commitment au moins `confirmed`; `limit <= 500_000`; `limit = 0` est valide et donne `[]` |
| `getBlockTime` | `slot` uniquement | `i64 ou null` | préserver l'absence de timestamp; les cas cleaned/skipped/not available restent des erreurs RPC runtime, pas des valeurs synthétiques |
| `getFirstAvailableBlock` | aucun paramètre | `u64` | requête exacte `params: []`; aucune config |
| `getRecentPerformanceSamples` | `limit?` | tableau de `{slot,numTransactions,numSlots,samplePeriodSecs,numNonVoteTransactions?}` | défaut runtime `720`; maximum `720`; rejeter avant I/O `limit > 720`; préserver `numNonVoteTransactions` nullable/ancien runtime |
| `minimumLedgerSlot` | aucun paramètre | `u64` | requête exacte `params: []`; conserver les erreurs ledger/runtime |
### `getBlock` — stratégie wire
@@ -174,17 +243,17 @@ SolanaWireField<T>
`SolanaConfirmedTransaction` ne doit **pas** être réutilisé tel quel pour un élément de bloc : ce DTO contient `slot` et `blockTime`, qui appartiennent au résultat top-level de `getTransaction` et non à chaque élément `transactions[]` d'un bloc. Un type wire de transaction de bloc dédié peut en revanche composer les primitives ci-dessus et préserver `transaction`, `meta` et `version` sans décodage Program.
Les champs top-level dont la présence dépend de la config (`transactions`, `signatures`, `rewards`, `numRewardPartitions`) doivent utiliser une représentation capable de distinguer une omission d'un `null` lorsqu'une telle distinction existe sur le wire. Les transactions `accounts` ne doivent pas être forcées dans une structure `full` plus riche que le wire réellement retourné.
Les champs top-level dont la présence dépend de la config (`transactions`, `signatures`, `rewards`, `numRewardPartitions`) doivent utiliser une représentation capable de distinguer une omission d'un `null` lorsqu'une telle distinction existe sur le wire. `numRewardPartitions` est explicitement rattaché à SIMD-0118 et doit être couvert en présent/omis. Le reward wire de bloc doit conserver `commission` nullable et `commissionBps` optionnel/omis de SIMD-0291. Les transactions `accounts` ne doivent pas être forcées dans une structure `full` plus riche que le wire réellement retourné. Une version de transaction numérique différente de `0` doit rester représentable afin de ne pas régresser la compatibilité préparée pour SIMD-0385.
## Matrice Economics — 5 wrappers
| Méthode | Requête à couvrir | Résultat à préserver | Contraintes / décisions `KSP-TRANSPORT-007` |
|---|---|---|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `getInflationGovernor` | config commitment optionnelle | `{initial,terminal,taper,foundation,foundationTerm}` en `f64` | réutiliser `SolanaCommitmentConfig`; aucun contexte de réponse |
| `getInflationRate` | aucun paramètre | `{total,validator,foundation,epoch}` | requête exacte `params: []` |
| `getInflationReward` | liste ordonnée d'adresses ; config optionnelle `{epoch,commitment,minContextSlot}` | `Vec<Option<Reward>>` positionnel | ordre/cardinalité identiques aux entrées ; préserver `commission: u8 ou null` **et** `commissionBps: u16` optionnel de Agave `v4.2.1`; aucune limite fixe d'adresses inventée |
| `getStakeMinimumDelegation` | config contextuelle optionnelle `{commitment,minContextSlot}` | `SolanaRpcResponse<u64>` | réutiliser `SolanaContextConfig` / `SolanaRpcResponse<T>` |
| `getSupply` | config optionnelle `{commitment,excludeNonCirculatingAccountsList}` | `SolanaRpcResponse<{total,circulating,nonCirculating,nonCirculatingAccounts}>` | le booléen runtime par défaut est `false`; préserver la liste ordonnée retournée lorsqu'elle est demandée |
| Méthode | Requête à couvrir | Résultat à préserver | Contraintes / décisions `KSP-TRANSPORT-007` |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `getInflationGovernor` | config commitment optionnelle | `{initial,terminal,taper,foundation,foundationTerm}` en `f64` | réutiliser `SolanaCommitmentConfig`; aucun contexte de réponse |
| `getInflationRate` | aucun paramètre | `{total,validator,foundation,epoch}` | requête exacte `params: []` |
| `getInflationReward` | liste ordonnée d'adresses; config optionnelle `{epoch,commitment,minContextSlot}` | `Vec<Option<Reward>>` positionnel | ordre/cardinalité identiques aux entrées; préserver `commission: u8 ou null` et `commissionBps: u16` optionnel/omis de Agave `v4.2.1` conformément à SIMD-0291; aucune limite fixe d'adresses inventée |
| `getStakeMinimumDelegation` | config contextuelle optionnelle `{commitment,minContextSlot}` | `SolanaRpcResponse<u64>` | réutiliser `SolanaContextConfig` / `SolanaRpcResponse<T>`; restituer la valeur runtime en lamports sans minimum codé en dur; surveiller SIMD-0490 |
| `getSupply` | config optionnelle `{commitment,excludeNonCirculatingAccountsList}` | `SolanaRpcResponse<{total,circulating,nonCirculating,nonCirculatingAccounts}>` | le booléen runtime par défaut est `false`; préserver la liste ordonnée retournée lorsqu'elle est demandée |
### Extension runtime `commissionBps`
@@ -194,7 +263,7 @@ La documentation publique actuelle de `getInflationReward` énumère encore uniq
commission_bps: Option<u16>
```
sérialisé en `commissionBps` lorsqu'il est présent. Ce champ correspond à l'évolution SIMD-0291 et doit être conservé dans le DTO KSP pour ne pas perdre une capacité/extension du runtime stable courant.
sérialisé en `commissionBps` lorsqu'il est présent. Ce champ correspond à l'évolution SIMD-0291 et doit être conservé dans le DTO KSP pour ne pas perdre une capacité/extension du runtime stable courant. Le DTO doit préserver séparément `commission` nullable et `commissionBps` optionnel/omis; il ne doit pas convertir les basis points en pourcentage ni dériver l'un des deux champs depuis l'autre.
## Contraintes locales retenues
@@ -238,9 +307,9 @@ Noms définitifs ajustables pendant l'implémentation, responsabilités fixes :
config getBlock moderne + enum transactionDetails
config/range/result getBlockProduction
block commitment result
confirmed block + transaction-in-block + reward wire
confirmed block + transaction-in-block + reward wire, avec `numRewardPartitions` SIMD-0118 et `commissionBps` SIMD-0291
performance sample
inflation governor/rate/reward
inflation governor/rate/reward, avec reward d'inflation distinct et `commissionBps` SIMD-0291
supply result/config
```
@@ -306,12 +375,16 @@ Cas de régression obligatoires spécifiques :
getBlock bare encoding legacy
getBlock transactionDetails full/signatures/none/accounts
getBlock result null
getBlock numRewardPartitions présent/omis (SIMD-0118)
getBlock rewards commission nullable + commissionBps présent/omis (SIMD-0291)
getBlock transaction version numérique non nulle conservée (canary SIMD-0385)
getBlocks [start,config] vs [start,end,config]
getBlocks range > 500_000 rejetée avant I/O
getBlocksWithLimit 0 et > 500_000
getRecentPerformanceSamples défaut/720/>720
getBlockProduction lastSlot < firstSlot rejeté avant I/O
getInflationReward ordre + null positionnels + commissionBps
getInflationReward ordre + null positionnels + commission/commissionBps présent/omis (SIMD-0291)
getStakeMinimumDelegation valeur runtime arbitraire sans minimum codé en dur (watch SIMD-0490)
getSupply excludeNonCirculatingAccountsList true/false/omitted
```
@@ -333,7 +406,7 @@ historical Deprecated/Removed == 14/14
KSP-TRANSPORT-007 audited current == 52/52
```
La compliance `KSP-TRANSPORT-007` des 37 wrappers de `0.2.1``0.2.3` reste acquise par `docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`; la clôture `0.2.4` vérifie qu'aucune régression n'a été introduite et applique la même règle aux 15 nouveaux wrappers.
La compliance `KSP-TRANSPORT-007` des 37 wrappers de `0.2.1``0.2.3` reste acquise par `docs/validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`; la clôture `0.2.4` vérifie qu'aucune régression n'a été introduite et applique la même règle aux 15 nouveaux wrappers. Le réaudit final inclut explicitement l'état des SIMD susceptibles de modifier la surface HTTP ou sa sémantique observable, au minimum SIMD-0180, SIMD-0298, SIMD-0307, SIMD-0385, SIMD-0490, SIMD-0550 et SIMD-0553, afin qu'une évolution devenue stable pendant la session ne soit pas oubliée. Il réaudite aussi l'inventaire officiel lui-même afin de détecter d'éventuels nouveaux endpoints issus de SIMD-0180 ou d'une autre évolution d'interface.
## Smokes live
@@ -347,17 +420,20 @@ Le smoke historique Config -> Transport reste une exception transitoire de compo
```text
pre.001 audit officiel actuel + Agave stable + matrice + wires + contraintes + sizing
pre.002 primitives/configs/results Blocks/Economics partagés + fixtures communes
pre.002 primitives/configs/results Blocks/Economics partagés + reward wires SIMD-0118/0291
+ fixtures communes
pre.003 Blocks simples : getBlockCommitment, getBlockHeight, getBlockTime,
getFirstAvailableBlock, minimumLedgerSlot
pre.004 ranges/performance : getBlocks, getBlocksWithLimit, getRecentPerformanceSamples
pre.005 getBlockProduction + range/identity/result contextualisé
pre.006 getBlock moderne + bare encoding legacy + transactionDetails + wire bloc riche
pre.007 Economics simples : getInflationGovernor, getInflationRate,
pre.006 réaudit SIMD-0298/0307 + getBlock moderne + bare encoding legacy + transactionDetails
+ wire bloc riche + SIMD-0118/0291 + canary version numérique SIMD-0385
pre.007 réaudit SIMD-0490/0550 + Economics simples : getInflationGovernor, getInflationRate,
getStakeMinimumDelegation, getSupply
pre.008 getInflationReward + null positionnels + commissionBps + invariants
pre.009 compliance finale 52/52 + 14/14 + KSP-TRANSPORT-007 + docs + smokes + graphes
+ prompt 0.2.5 — Wallet foundation
pre.008 getInflationReward + null positionnels + commissionBps SIMD-0291 + invariants
pre.009 réaudit SIMD HTTP (0180/0298/0307/0385/0490/0550/0553 minimum)
+ réaudit inventaire officiel + compliance finale 52/52 + 14/14
+ KSP-TRANSPORT-007 + docs + smokes + graphes + prompt 0.2.5 — Wallet foundation
rel.001 publication strictement publicationnelle
```