Files
khadhroony-bot3/olddocs/archivekbot2/docs/NATIVE_SOLANA_PROGRAMS.md
2026-07-30 17:50:29 +02:00

234 lines
33 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- file: docs/NATIVE_SOLANA_PROGRAMS.md -->
<!-- version: 18 -->
# Inventaire et couverture des programmes Solana natifs
## Périmètre
Le registre `kb_program_ids::native_program_ids()` contient dix-huit surfaces exécutables : programmes runtime natifs, loaders, précompiles et programmes historiques encore observables. Les sysvars et comptes natifs non exécutables restent suivis séparément dans `registry/core_program_id_seed.toml`.
Memo ne fait pas partie de ce périmètre. Les IDs officiels v1 `Memo1U...`, v3 `MemoSq...` et v4 `Memo4c...` sont réservés dans `kb_decoder_spl_memo`.
## État du phasage
| Phase | Contenu | État |
|-------|---------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|
| A | modèle dévénement, lecture bornée, validation des comptes et diagnostics | implémenté dans `0.4.1-pre.001` |
| B | System Program et Compute Budget | implémenté, replay mainnet validé dans `pre.005` |
| C | Address Lookup Table et loaders | implémenté dans `pre.003` puis `pre.006` |
| D | Vote, Stake, Config et programmes historiques | implémenté : Config/Feature `pre.008`, Vote `pre.010` validé dans `pre.011`, Stake `pre.013` validé mainnet |
| E | précompiles et preuves ZK | précompiles signature `pre.014`, ZK ElGamal Proof `pre.015`, ancien ZK Token Proof `pre.016` |
| F | matérialisations justifiées, diagnostics globaux et clôture | nonce System/contextes ZK `pre.017`; Slashing et invariants de couverture `pre.018`; corpus final à valider |
Le processor conserve lidentité `solana_native_classifier@0.4.1` pendant les deltas préparatoires. Les nouveaux décodeurs nécessitent donc un force replay ciblé ou global ; la version ne sera relevée quavec un changement explicite du contrat de processor.
## Sources normatives couvertes
| Surface | Source officielle | Sérialisation retenue | Couverture |
|---------------------------|---------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------|-----------------------------------------|
| System Program | `solana-system-interface 3.2.0`, enum `SystemInstruction` | schéma `wincode` officiel compatible avec le format bincode historique, lecture exacte sans octets suffixes | 14 variantes |
| Compute Budget actuel | `solana-compute-budget-interface 3.0.0` + runtime `solana-compute-budget-instruction 4.1.1` | tag `u8` puis entier little-endian/Borsh ; désérialisation runtime unchecked, suffixe accepté et audité | 5 entrées, dont le tag réservé `Unused` |
| Compute Budget historique | ancien `solana-sdk`, `RequestUnitsDeprecated` | tag `0`, `u32 units`, `u32 additional_fee` | 1 variante historique |
| Address Lookup Table | `solana-address-lookup-table-interface 3.1.0`, enum `ProgramInstruction` | schéma `wincode` officiel, lecture exacte | 5 variantes |
| BPF Loader immuable | `solana-loader-v2-interface 3.0.0`, enum `LoaderInstruction` | tag `u32 LE`, offset `u32`, longueur de vector `u64`, lecture exacte | write, finalize sur deux générations |
| BPF Loader upgradeable | `solana-loader-v3-interface 8.0.1`, enum `UpgradeableLoaderInstruction` | wire format historique compatible bincode, champs booléens suffixes avec valeurs historiques documentées | 8 variantes |
| Loader v4 | `solana-loader-v4-interface 3.1.0`, enum `LoaderV4Instruction` | tag et entiers little-endian, tailles exactes | 7 variantes |
| Config Program | `solana-config-interface 2.0.0` et processor `solana-config-program 2.2.20` | `ConfigKeys` en `solana_short_vec`, clés `(Pubkey, bool)`, puis payload typé opaque pour le décodeur générique | 1 écriture générique `store` |
| Feature Gate | `solana-feature-gate-interface 4.0.0`, `FeatureGateInstruction` | tag `u8` exact `0`, sans suffixe | 1 variante |
| Vote Program | `solana-vote-interface ^6.0`, enum `VoteInstruction` | schéma officiel `wincode`, discriminant historique `u32 LE`, lecture exacte sans octets suffixes | 20 variantes |
| Stake Program | `solana-stake-interface ^4.3`, enum `StakeInstruction` | miroir wire privé `wincode` exact du layout historique ; types sémantiques officiels consommés | 18 variantes |
| ZK ElGamal Proof | `solana-zk-elgamal-proof-interface ^0.1`, `ProofInstruction`, types `Pod`, runtime Agave | tag `u8`; preuve inline de taille officielle ou référence compte `u32 LE` sur instruction exacte de 5 octets | 13 variantes |
| ZK Token Proof historique | miroir wire local audité contre `solana-zk-token-sdk 3.1.14`, Agave `v2.0.0`/`v4.1.1` | tag `u8`; layout historique inline ou offset compte sur 5 octets ; fallback runtime actuel sans effet | 17 variantes + fallback no-op |
| Slashing stateless | Agave `v4.1.1` + `solana-program/slashing@fe8da3a` | tag `u8`; fermeture sur 1 octet ou preuve duplicate block sur 305 octets exacts | 2 variantes |
Les versions de crates sont utilisées comme références reproductibles. Un futur changement dinterface doit entraîner un changement de version du décodeur et un replay ledger/version/hash.
## System Program
Program ID : `11111111111111111111111111111111`.
| Tag historique compatible bincode/wincode `u32 LE` | Entry code | Paramètres structurés | Comptes principaux | État |
|---------------------------------------------------:|--------------------------------|------------------------------------|----------------------------------------|--------|
| 0 | `create_account` | lamports, space, owner | funding, new account | décodé |
| 1 | `assign` | owner | assigned account | décodé |
| 2 | `transfer` | lamports | funding, recipient | décodé |
| 3 | `create_account_with_seed` | base, seed, lamports, space, owner | funding, new account, base optionnelle | décodé |
| 4 | `advance_nonce_account` | aucun | nonce, recent blockhashes, authority | décodé |
| 5 | `withdraw_nonce_account` | lamports | nonce, recipient, sysvars, authority | décodé |
| 6 | `initialize_nonce_account` | authority | nonce, recent blockhashes, rent | décodé |
| 7 | `authorize_nonce_account` | authority | nonce, authority | décodé |
| 8 | `allocate` | space | allocated account | décodé |
| 9 | `allocate_with_seed` | base, seed, space, owner | derived account, base | décodé |
| 10 | `assign_with_seed` | base, seed, owner | derived account, base | décodé |
| 11 | `transfer_with_seed` | lamports, from seed, from owner | funding, base, recipient | décodé |
| 12 | `upgrade_nonce_account` | aucun | nonce account | décodé |
| 13 | `create_account_allow_prefund` | lamports, space, owner | new account, funding conditionnel | décodé |
Le décodeur utilise le schéma `wincode` dérivé directement par `solana-system-interface 3.2.0`. `wincode::deserialize_exact` conserve la compatibilité octet pour octet avec le format historique de cette enum et refuse les octets suffixes. Le crate nutilise aucune dépendance directe à `bincode`.
`pre.017` matérialise les cinq opérations durable nonce sous `durable_nonce_account:<operation>:0`. Initialize, advance, authorize et upgrade conservent leur transition explicite. Withdraw conserve le montant demandé et la règle officielle de fermeture conditionnelle : le compte nest détruit que lorsque la totalité de son solde est retirée. La projection ne prétend pas reconstruire létat final transactionnel du compte et ne duplique pas les deltas SOL du graphe core.
Les flags signer/writable sont conservés sous deux formes : privilèges attendus par le contrat officiel et privilèges réellement résolus depuis core. Ils ne sont pas confondus, car une CPI signée par PDA ne se reflète pas nécessairement comme signer statique de la transaction.
## Compute Budget
Program ID : `ComputeBudget111111111111111111111111111111`.
| Tag `u8` | Entry code | Taille décodée minimale | Paramètres | Statut |
|---------:|---------------------------------------|------------------------:|--------------------------|-----------------------|
| 0 | `unused_reserved` | 1 | aucun | `ignored` |
| 0 | `request_units_deprecated` | 9 | units, additional fee | `decoded`, historique |
| 1 | `request_heap_frame` | 5 | bytes `u32` | `decoded` |
| 2 | `set_compute_unit_limit` | 5 | compute unit limit `u32` | `decoded` |
| 3 | `set_compute_unit_price` | 9 | micro-lamports `u64` | `decoded` |
| 4 | `set_loaded_accounts_data_size_limit` | 5 | bytes `u32` | `decoded` |
Le runtime Agave traite les variantes modernes avec `solana_borsh::v1::try_from_slice_unchecked`. Les octets suffixes sont donc acceptés après les 5 ou 9 octets utiles. Le décodeur reproduit cette règle et conserve `trailingDataByteLength`, `trailingDataSha256`, `trailingDataPrefixHex` et `trailingDataSemantics = ignored_by_runtime_borsh_unchecked`. Les payloads trop courts restent `failed`. Le tag `0` demeure dispatché par taille afin de distinguer le tag réservé actuel de la variante historique à neuf octets ; toute autre taille pour ce tag reste `failed`. Un tag inconnu est `unsupported` avec diagnostic borné et hash du payload disponible pour un replay futur.
## Address Lookup Table
Program ID : `AddressLookupTab1e1111111111111111111111111`.
| Tag `u32 LE` | Entry code | Paramètres | Comptes | État |
|-------------:|---------------------------|------------------------------------------------------------------|--------------------------------------------------|--------|
| 0 | `create_lookup_table` | recent slot, bump seed, politique historique du signer authority | table, authority, payer, System Program | décodé |
| 1 | `freeze_lookup_table` | aucun | table, authority | décodé |
| 2 | `extend_lookup_table` | adresses ajoutées, count, présence du financement | table, authority, paire optionnelle payer/System | décodé |
| 3 | `deactivate_lookup_table` | aucun | table, authority | décodé |
| 4 | `close_lookup_table` | aucun | table, authority, recipient | décodé |
Le décodeur refuse une paire optionnelle dextension incomplète et les octets suffixes. La création conserve `expectedSigner = null` pour lautorité, car lencodeur officiel actuel ne la marque plus signer tandis que les runtimes historiques antérieurs à v1.12 lexigeaient.
La projection `solana_native_lifecycle` produit une sortie `address_lookup_table:<operation>:0` uniquement si lobservation est exacte, réussie et commitée. Les intentions issues de transactions échouées restent dans decode et sont refusées avant matérialisation.
## Programmes runtime natifs principaux
| Code canonique | Program ID | État au début de `pre.018` |
|--------------------|-----------------------------------------------|--------------------------------------------------------------------------------|
| `vote` | `Vote111111111111111111111111111111111111111` | 20 variantes décodées ; 500 `tower_sync` validés mainnet |
| `stake` | `Stake11111111111111111111111111111111111111` | 18 variantes décodées ; 339 instructions mainnet sur neuf entry codes observés |
| `config` | `Config1111111111111111111111111111111111111` | écriture générique `store` décodée ; corpus ciblé à inventorier |
| `zk_elgamal_proof` | `ZkE1Gama1Proof11111111111111111111111111111` | 13 variantes ; 151 instructions mainnet et 139 contextes matérialisés |
## Loaders
| Surface | Program ID | Variantes | Statut `pre.006` |
|------------------------|-----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|
| Native Loader | `NativeLoader1111111111111111111111111111111` | invocation directe opaque | `ignored`, historique, aucun faux événement |
| BPF Loader deprecated | `BPFLoader1111111111111111111111111111111111` | write, finalize | décodé |
| BPF Loader v2 | `BPFLoader2111111111111111111111111111111111` | write, finalize | décodé |
| BPF Loader upgradeable | `BPFLoaderUpgradeab1e11111111111111111111111` | initialize buffer, write, deploy with max data length, upgrade, set authority, close, extend program, set authority checked | décodé |
| Loader v4 | `LoaderV411111111111111111111111111111111111` | write, copy, set program length, deploy, retract, transfer authority, finalize | décodé |
Les payloads `write` ne recopient pas le bytecode dans lévénement : ils conservent offset, longueur et SHA-256. Les tailles de vectors, booléens, octets suffixes et paires de comptes optionnelles sont validés avant toute lecture. Les anciennes formes upgradeable sans le booléen suffixe sont acceptées avec la valeur par défaut officielle et marquées comme telles.
La projection lifecycle produit `program_loader:<surface>:<operation>:0` pour les mutations réussies et commitées : finalize immuable, initialize/deploy/upgrade/close/extend upgradeable, puis set length/deploy/retract/finalize v4. Les écritures, copies et changements dautorité restent des événements decode de familles Audit ou Admin.
## Slashing Program stateless
Program ID : `S1ashing11111111111111111111111111111111111`.
Agave `v4.1.1` le déclare comme stateless builtin derrière `enshrine_slashing_program`, avec un hash de build vérifié correspondant à la release officielle `solana-program/slashing@fe8da3a`.
| Tag `u8` | Entry code | Taille exacte | Effet runtime observé |
|---------:|--------------------------|--------------:|------------------------------------------------------------------------|
| 0 | `close_violation_report` | 1 | ferme le rapport après au moins trois epochs et transfère ses lamports |
| 1 | `duplicate_block_proof` | 305 | vérifie une preuve externe puis stocke un rapport de violation |
La preuve duplicate block est lue depuis un compte externe à loffset `u64` de linstruction. Le replay transactionnel ne possède pas le contenu historique de ce compte. Le décodeur conserve loffset, le slot, les clés, racines et signatures intégrées à linstruction, résume linstruction Ed25519 précédente et ne prétend ni relire le compte ni recalculer les signatures.
Une transaction réussie prouve seulement lacceptation runtime, lassignation/allocation du PDA préfinancé et lécriture du rapport. Le programme ne brûle ni ne retire lui-même du stake : la projection `slashing_violation_report` conserve donc `penaltyAppliedByProgram = false` et décrit un signal destiné à une application de pénalité externe au programme.
## Précompiles de signature `pre.014`
| Code canonique | Program ID | Format | État `pre.014` |
|----------------|-----------------------------------------------|---------------------------------------------------------------------------|-----------------------------------------------------------------------------|
| `ed25519` | `Ed25519SigVerify111111111111111111111111111` | header 2 octets, offsets 14 octets, clé 32, signature 64 | décodé, zéro signature accepté seulement sur 2 octets |
| `secp256k1` | `KeccakSecp256k11111111111111111111111111111` | header 1 octet, offsets 11 octets, adresse 20, signature 64 + recovery ID | décodé, index `u8` explicites, zéro signature accepté seulement sur 1 octet |
| `secp256r1` | `Secp256r1SigVerify1111111111111111111111111` | header 2 octets, offsets 14 octets, clé compressée 33, signature 64 | décodé, zéro signature refusé, maximum 8 |
Le contrat core `2` fournit les payloads de toutes les instructions outer. Ed25519 et secp256r1 interprètent `u16::MAX` comme la cible ; secp256k1 résout toujours un index explicite. Les références aux inner instructions ne sont pas autorisées. Les offsets et longueurs utilisent des additions vérifiées avant chaque slice.
Chaque observation conserve les index bruts et résolus, la provenance, les longueurs, SHA-256 et préfixes bornés des composants, ainsi que `runtimeVerification`. Aucun message complet nest recopié, aucune signature nest recalculée et aucune sortie métier nest matérialisée. Une transaction échouée reste `decoded` si le layout est valide, mais porte `not_asserted_transaction_failed` et reste non commitée.
## Surfaces historiques ou complémentaires
| Code canonique | Program ID | État après `pre.008` |
|------------------|-----------------------------------------------|-----------------------------------------------------------------------------------------------------|
| `feature` | `Feature111111111111111111111111111111111111` | `revoke_pending_activation` décodé et lifecycle matérialisable |
| `zk_token_proof` | `ZkTokenProof1111111111111111111111111111111` | 17 layouts historiques décodés + fallback `current_runtime_noop_invocation`; validation synthétique |
### Ancien ZK Token Proof Program
`pre.016` couvre les discriminants `0..16` de linterface historique : fermeture du contexte, zero balance, withdraw, égalités de ciphertext/commitment, transfer, transfer with fee, validité de pubkey, range proofs simples et batchés, validité de grouped ciphertext à deux ou trois handles et fee sigma. Les tailles de preuve et de contexte sont maintenant conservées dans une table locale auditée contre les types `Pod` de `solana-zk-token-sdk 3.1.14`, sans dépendre de cette crate dépréciée.
Le runtime historique Agave `v2.0.0` distinguait une preuve inline dune preuve stockée dans le premier compte lorsque linstruction faisait exactement cinq octets. Il imposait des arités distinctes pour le contexte, refusait les vérifications comme inner instructions et plaçait certains chemins derrière `enable_zk_proof_from_account` ou `enable_zk_transfer_with_fee`. Le runtime Agave `v4.1.1` est au contraire un stub qui retourne succès sans mutation. Le décodeur conserve ces deux références sans prétendre connaître la version runtime dune transaction donnée.
Aucune signature mainnet na été trouvée pour ce program ID lors du jalon. La surface est donc validée par fixtures synthétiques et sources officielles, sans critère de backfill. Les preuves inline sont seulement mesurées, hashées et préfixées de façon bornée ; les preuves externes conservent loffset et la taille attendue. Aucune preuve nest recalculée et aucune sortie nest matérialisée.
### Stake Program
`pre.013` couvre les dix-huit variantes de `StakeInstruction`, tags `u32 LE` `0..17` : initialize, authorize, delegate, split, withdraw, deactivate, set lockup, merge, autorisations avec seed, variantes checked, minimum delegation, deactivate delinquent, `redelegate`, move stake et move lamports. `Redelegate` reste déclaré historique : le processor actuel renvoie `InvalidInstructionData` avant tout traitement de comptes ; une occurrence réelle doit donc provenir dune transaction échouée et reste non commitée.
Lenum officielle de `solana-stake-interface ^4.3` conserve le contrat Serde/Bincode historique, mais nimplémente pas directement `SchemaRead`/`SchemaWrite`. Pour respecter linterdiction workspace de dépendre de `bincode`, le décodeur utilise un miroir wire privé, ordonné exactement comme lenum officielle, décodé par `wincode::deserialize_exact`. Les tests vérifient manuellement les tags, pubkeys, entiers, enums imbriquées et longueurs de chaînes du layout historique. Les types sémantiques et le program ID officiels restent consommés depuis linterface.
Le processor BPF actuel supporte deux familles de comptes. Les layouts historiques sont détectés par la première sysvar héritée, généralement Clock ou Rent ; les layouts modernes retirent ces sysvars et placent directement les autorités aux positions attendues. `Split`, `SetLockup` et `SetLockupChecked` conservent volontairement les contraintes historiques plus souples du runtime. Le décodeur expose `accountLayout`, conserve les comptes additionnels et les privilèges attendus/observés, mais ne prétend pas rejouer les vérifications dépendant de létat du stake account, du lockup, de la délégation ou des sysvars courantes. Aucune matérialisation Stake nest ajoutée dans ce delta.
### Compte Stake Config historique
`StakeConfig11111111111111111111111111111111` nest pas un programme exécutable. Linterface Stake officielle le déclare comme identifiant déprécié du compte de configuration historique du Stake Program. Il reste dans `kb_program_ids` comme `STAKE_CONFIG_ACCOUNT_ID` et dans le registre core avec `identifier_kind = well_known_account`, mais il est exclu des surfaces du décodeur et de lexécuteur.
### Config Program
Le Config Program ne possède pas un enum dinstructions discriminé comparable à System ou Stake. Chaque invocation stocke un préfixe `ConfigKeys` sérialisé avec `solana_short_vec`, suivi dun payload spécifique au type de configuration. Le décodeur valide la longueur compacte, les clés, les booléens signataires et lordre des comptes signataires, puis conserve le reste par taille, préfixe borné et SHA-256 avec la sémantique explicite `opaque_program_specific`.
### Vote Program
`pre.010` utilise `solana-vote-interface ^6.0` avec les features `serde` et `wincode`. Le discriminant wire historique reste un `u32` little-endian compris entre `0` et `19`, et `wincode::deserialize_exact` rejette les octets résiduels. `VoteInitV2` contient les autorités, la clé BLS, sa preuve de possession et les deux commissions en points de base ; les collecteurs Inflation Rewards et Block Revenue sont les comptes dinstruction 2 et 3.
La couverture comprend : initialisations V1/V2, autorisations simples/checked/seed, vote et vote switch, mises à jour détat normales/compactes, tower sync, retrait, identité, commissions historiques et en points de base, collecteurs différenciés et dépôt de récompenses délégateurs. Les tableaux BLS V2 sont conservés en hexadécimal exact. Les sysvars Rent, Clock et Slot Hashes sont vérifiées aux positions imposées par linterface. Les privilèges attendus et observés restent distincts afin de ne pas confondre les signataires statiques et les signatures PDA de CPI.
Aucune projection matérialisée spécifique à Vote nest ajoutée dans ce delta : la mutation réelle dépend de létat du vote account et du runtime. Une transaction échouée produit uniquement une observation non commitée.
## ZK ElGamal Proof `pre.015`
Program ID : `ZkE1Gama1Proof11111111111111111111111111111`.
Le décodeur consomme `solana-zk-elgamal-proof-interface ^0.1` pour lenum `ProofInstruction` et les tailles exactes des types `Pod`. Il couvre `CloseContextState` et les douze preuves : zero ciphertext, égalités ciphertext/ciphertext et ciphertext/commitment, validité de clé publique, percentage with cap, range proofs 64/128/256 bits et validités grouped/batched à deux ou trois handles.
Deux modes de transport sont distingués conformément au runtime :
- instruction de cinq octets : tag puis offset `u32 LE` vers un compte contenant la preuve ;
- autre taille exacte : preuve inline immédiatement après le tag, avec taille égale au type `ProofData` officiel.
Pour une preuve inline, les blocs contexte et preuve sont séparés par leurs tailles `Pod`, puis conservés uniquement sous forme de longueur, SHA-256 et préfixe hexadécimal borné. Le décodeur ne recalcule aucune preuve cryptographique. Pour une transaction réussie, il indique seulement que linstruction a été acceptée par le runtime. Pour une transaction échouée, aucune validité nest affirmée et lobservation reste non commitée.
Le mode référencé par compte a une limite historique structurelle : le graphe core de transaction ne contient pas le contenu du compte à linstant dexécution. Lévénement conserve donc le compte source, loffset, le type et la taille attendue, mais marque les octets de preuve comme indisponibles. Il ne tente ni lecture RPC actuelle, qui pourrait être divergente, ni reconstruction.
Les comptes optionnels de contexte sont résolus selon le mode : positions 0/1 pour une preuve inline et 1/2 après le compte de preuve pour une preuve externe. La fermeture du contexte conserve le contexte, la destination des lamports et lautorité signataire, accepte les octets suffixes comme le runtime et refuse que contexte et destination désignent le même compte.
`pre.017` matérialise le lifecycle du compte de contexte sous `zk_proof_context:<operation>:0`. Une vérification nest éligible que lorsque `contextStateRequested = true`, que la transaction a réussi et que lobservation est commitée. La sortie conserve le compte, lautorité et le type de preuve, mais jamais la preuve elle-même. La fermeture réussie décrit la récupération des lamports, la remise à zéro des données et le retour de lowner au System Program. Les preuves sans contexte restent en decode/audit.
## Statuts et politique déchec
- `decoded` signifie que le format complet a été validé et quune observation structurée a été produite.
- `ignored` est réservé à une entrée comprise mais sans événement utile, comme le tag Compute Budget `Unused`.
- `unsupported` conserve une variante inconnue ou une surface non encore implémentée sans faux événement.
- `failed` indique un payload absent, invalide, tronqué, non canonique ou des comptes incohérents.
- `unmatched` reste un défaut de dispatch et ne doit pas apparaître pour une sélection bornée aux surfaces déclarées.
Une transaction on-chain échouée reste décodable comme intention. Lobservation porte `transactionSucceeded = false` et `observation_committed = false`. Le matérialiseur `solana_native_lifecycle` est actif pour ALT, les mutations loader listées, Feature Gate, les durable nonce accounts System et les comptes de contexte ZK ElGamal. Il accepte les familles `Lifecycle`, `Admin` et `Audit` uniquement au niveau exact surface/entrée/paramètres, puis applique `SuccessfulCommittedOnly`. Une observation non commitée est refusée et une preuve ZK sans contexte est exclue avant ledger et politique.
## Validation mainnet `pre.005`
Les correctifs de `pre.005` ont été validés par les tests ciblés, `cargo clippy --all-targets` et deux campagnes Tauri. Le force replay ciblé a décodé 3/3 inputs sans échec. Le replay global a sélectionné, démarré et terminé 476 inputs : 476 décodés, zéro `failed`, `unsupported`, `unmatched` et zéro faux `materializationRefused`. Aucun output nétait attendu, car le corpus ne contenait pas dopération ALT éligible.
## Validation `pre.006`, `pre.008`, Vote mainnet et anomalie Compute Budget
Les tests `pre.006`, Clippy et le replay Tauri global ont été validés : 476 inputs sélectionnés, 476 décodés, aucun échec, `unsupported`, `unmatched` ou refus de matérialisation. Les validations utilisateur de `pre.008` couvrent 256 tests ciblés, PostgreSQL réel, Clippy et un démarrage/replay Tauri propre. Le corpus initial ne contenait que System et Compute Budget : loaders, Config et Feature restent en attente dun corpus réel.
Le backfill Vote de 500 signatures a inséré 500 transactions et lextraction core a terminé 500/500 sans échec. Le replay global suivant contient 500 instructions Vote réelles, toutes reconnues et décodées comme `tower_sync`, sans échec Vote. Lunique `failed` de la campagne provient dun `set_compute_unit_limit` de 12 octets : le runtime laccepte grâce à la désérialisation Borsh unchecked, alors que le décodeur strict exigeait encore 5 octets exacts. `pre.011` corrige cet écart. Le processor reste `solana_native_classifier@0.4.1` : un force replay est requis pour remplacer le résultat `failed` déjà enregistré.