# kb_pipeline Ce crate orchestre les étapes d'ingestion, extraction, observation, décodage, matérialisation et validation. ## Lectures stateful Token-2022 et ElGamal Registry `read_token_2022_stateful_snapshot` effectue un `getAccountInfo` complet avec commitment `confirmed`, `minContextSlot` optionnel et limite de données explicite comprise entre 1 et 65 536 octets. La réponse est refusée avant parsing si le compte est absent, exécutable, détenu par un autre programme, plus grand que la limite ou si les données décodées ne couvrent pas exactement `space`. Le buffer validé est ensuite parsé comme Mint, Account ou Multisig et routé vers les matérialiseurs propriétaires token accounts, metadata/group, fees et admin. `read_elgamal_registry_stateful_snapshot` applique le même contrat avec une taille exacte de 64 octets, le Program ID propre du registre et la validation du PDA dérivé du propriétaire stocké. Ces fonctions n'effectuent ni déchiffrement ni validation rétroactive des preuves cryptographiques. Les variantes pures `materialize_token_2022_account_info_result` et `materialize_elgamal_registry_account_info_result` permettent de tester ou réutiliser la validation d'une réponse RPC déjà obtenue. ## Token-2022 state snapshots `materialize_token_2022_stateful_snapshot` validates the Token-2022 owner boundary, parses one bounded Mint, Account, or Multisig buffer, checks embedded Token Metadata and Token Group mint identities against the carrying account, and routes outputs to their unique materializers. The function does not perform RPC reads itself; callers retain control over endpoint selection, account-data bounds, commitment, and post-execution timing. ## Rôle dans l'écosystème Ce module fait partie du découpage strict de Khadhroony Bot2. Il doit conserver des dépendances limitées et ne pas contourner les interfaces communes du workspace. ## Règles locales - Les commentaires de code restent en anglais. - La documentation Markdown reste en français. - Les exports publics sont contrôlés depuis `lib.rs` lorsque le crate expose une bibliothèque. - Les binaires utilisent `main.rs` avec les attributs Rust obligatoires. ## Backfill HTTP 0.3.3 Le crate expose `execute_http_backfill`, `BackfillRequest`, `BackfillSource` et `BackfillObserver`. Le moteur prend en charge les signatures explicites et les historiques programme/token/pool. Une recherche `Before` sans ancre commence sur les signatures les plus récentes et utilise un `filter_code` `program_latest`, `token_latest` ou `pool_latest`; une recherche `After` conserve une ancre obligatoire. Il applique les limites des rôles `kb_rpc`, normalise avec `getTransaction`, écrit le store canonique et produit une observation légère par tentative. ## Replay decode `0.4.0` `execute_decode_replay` sélectionne des instructions core contextualisées par signatures, états, slots, program IDs et instruction paths. Il applique un dispatch déterministe, une concurrence bornée, l’arrêt coopératif, le skip processor/version/hash, un force replay obligatoirement borné par signatures ou par autorisation « toutes les signatures », et la persistance atomique via `DecodePipelineStore`. Depuis `0.4.1-pre.014`, le contrat core `2` ajoute les instructions outer ordonnées au calcul de `decoder_api_decoder_api_contextual_input_hash`. `DECODE_PIPELINE_VERSION` reste `1` : le changement de contrat est déjà versionné et force naturellement un nouveau hash. Après application du delta, un force replay est nécessaire pour remplacer les résultats calculés avec le contrat `1`. Les transactions, rollbacks et clés d’idempotence du pipeline restent inchangés. La matérialisation reste optionnelle, exige au moins un matérialiseur enregistré et n’est appelée qu’après la persistance réussie du décodage. Depuis `0.4.1-pre.005`, la sélection vérifie d’abord l’applicabilité exacte surface/entrée ; les observations de même famille mais hors périmètre ne créent plus de faux refus. Le résumé distingue les statuts par processor, les skips, les sorties matérialisées et les refus de politique. ## Tracing opérationnel `kb_pipeline` utilise le target canonique `kb_pipeline`. Les champs `action`, `campaign_id`, `capture_session_id`, `signature`, `instruction_path`, processor et statut remplacent les anciens targets suffixés par module. Le backfill journalise sa validation, la sélection du client, la découverte des candidats, les erreurs terminales et le résumé. Le replay decode émet un événement `error` pour tout input sélectionné mais unmatched, tout résultat `failed`/`unsupported`, tout résultat de matérialisation `failed` et toute erreur de persistance. Une annulation coopérative reste un `warn`, et une transaction on-chain échouée mais correctement décodée n’est pas une erreur logicielle. ## Orchestration Devnet `0.4.2-pre.009` `execute_devnet_system_transfer` relie les briques déjà stabilisées sans les fusionner. L’appel vérifie le genesis hash Devnet, charge ou crée le wallet temporaire persistant du profil, contrôle si le destinataire existe et impose le minimum rent-exempt retourné par le RPC pour une adresse neuve, contrôle le solde et l’airdrop éventuel, construit un plan System transfer, estime les frais, simule le message exact, puis signe et envoie uniquement lorsque `submit` et la confirmation opérateur sont explicites. Après confirmation, l’orchestrateur réutilise successivement : ```text execute_http_backfill -> execute_core_extraction -> execute_decode_replay ``` La signature exacte est l’unique sélection de chaque campagne. Le résumé conserve séparément le plan, le blockhash, les frais, la simulation, l’envoi, la confirmation, le backfill, l’extraction, le replay et le diagnostic agrégé. Le mode simulation seule retourne avant signature et ne crée pas de faux diagnostic post-exécution. Après signature, les erreurs d’envoi, de confirmation ou de replay restent attachées à la signature dans le résumé au lieu de masquer une transaction potentiellement diffusée. `SolanaExecutionObserver` compose les observers existants du backfill, de l’extraction et du replay avec les événements propres à l’exécution. Cette API reste utilisable par une CLI, un worker ou une application distincte de `kb_app_demo`. Le test réseau réel reste opt-in via `KB_DEVNET_EXECUTION_TEST=1`; il n’est jamais lancé par la suite de tests standard. Il a été validé avec un wallet préfinancé et un transfert de 1 000 000 lamports vers une adresse neuve. Une simulation refusée conserve son erreur runtime et un extrait borné des logs afin de distinguer un défaut de transaction d’un défaut de transport. ## Orchestration Memo v4 Devnet `0.4.3-pre.004` `execute_devnet_memo` est le parcours opérateur Devnet de l’exécuteur SPL Memo universel. La restriction à v4 et Devnet appartient uniquement à cette démonstration : `kb_executor_spl_memo` reste capable de construire v1, v3 et v4 pour tous les clusters, sous le contrôle de la politique commune et de la simulation effective du programme demandé. `DevnetMemoExecutionRequest::new` produit un dry-run. Le champ `submit` n’autorise la signature et l’envoi qu’avec un profil Devnet mutable et la confirmation opérateur requise. Le wallet temporaire persistant du profil paie uniquement les frais réseau ; le plan annonce une dépense d’instruction nulle. Le wallet peut également être fourni comme compte signer readonly du Memo afin de valider le contrat runtime v4 sans exposer une seconde clé. Après une simulation réussie et un envoi explicitement autorisé, le parcours confirme la signature puis enchaîne l’hydratation canonique, l’extraction core, le decode replay Memo avec matérialisation, une lecture bornée de la projection `transaction_annotation` et un second replay non forcé. Le résumé conserve les lignes d’annotation exactes et le résultat du second replay ; celui-ci doit rester sans échec, sans nouvelle sortie matérialisée et sans refus pour établir l’idempotence. La première tranche n’ajoute aucune commande ni fenêtre Tauri. Elle stabilise le contrat backend avant l’exposition dans `kb_app_demo`. Le wallet Devnet doit déjà disposer du solde nécessaire au plafond de frais configuré ; aucun airdrop implicite n’est déclenché par le parcours Memo. Le test réseau est opt-in avec `KB_DEVNET_MEMO_EXECUTION_TEST=1` et exige `KB_POSTGRES_TEST_URL`. Il reste en simulation seule par défaut. L’envoi réel demande en plus `KB_DEVNET_MEMO_SUBMIT=1`, ce qui constitue l’autorisation explicite de dépenser les frais Devnet et d’exécuter toute la post-validation. `KB_DEVNET_WALLET_DIR` permet de sélectionner le wallet persistant déjà financé. Le parcours a été validé réellement le 15 juillet 2026 : une simulation seule, puis trois envois v4 confirmés. Les trois transactions ont été insérées, extraites, décodées et matérialisées ; leurs seconds replays ont chacun compté un skip, zéro échec, zéro refus et zéro nouvelle sortie matérialisée. ## Préflight stateful Solana Core `inspect_solana_core_stateful_readiness(pool, request)` lit de manière bornée les comptes et l’époque nécessaires avant simulation. La requête contient un rôle HTTP, le cluster attendu Localnet/Devnet et un `SolanaCoreOperation`. Le résultat contient `Ready`, `Blocked` ou `NotRequired`, un slot de contexte, des contrôles ordonnés et des faits mesurés. La fonction couvre ALT, Config, Feature, Slashing et les contextes ZK ElGamal. Elle vérifie le genesis hash, mais ne construit pas le plan, ne signe pas, ne simule pas et n’envoie pas. Les erreurs de transport ou de forme RPC restent des `kb_core::Error`; une précondition métier non satisfaite produit un rapport `Blocked` exploitable par les CLI, workers et interfaces. ## Préflight stateful SPL Token classique `0.4.4-pre.005` `inspect_spl_token_stateful_readiness` conserve l’exécuteur déterministe et sans I/O. Le pipeline vérifie le genesis Localnet/Devnet puis lit au maximum 128 comptes complets, chacun borné à la taille officielle maximale du multisig classique. Les parseurs locaux reproduisent exactement les layouts `Mint` de 82 octets, `Account` de 165 octets et `Multisig` de 355 octets, sans activer `bincode` et sans accepter de suffixe. Le rapport `Ready` ou `Blocked` expose owner programme, existence, layout, initialisation, mint, decimals, état frozen, solde brut, réserve native, delegate et allowance, autorités mint/freeze/owner/close, ainsi que `M/N` et les membres effectivement fournis. Les comptes à initialiser sont également comparés au minimum rent-exempt renvoyé par le cluster. `Batch` conserve l’ordre de ses enfants et mutualise les lectures de comptes. Les tests standards restent entièrement offline. Le test `optional_devnet_checked_transfer_readiness_from_env` est activé uniquement par `KB_DEVNET_SPL_TOKEN_PREFLIGHT_TEST=1`; il exige les variables `KB_DEVNET_SPL_TOKEN_SOURCE`, `KB_DEVNET_SPL_TOKEN_MINT`, `KB_DEVNET_SPL_TOKEN_DESTINATION` et `KB_DEVNET_SPL_TOKEN_AUTHORITY`. `KB_DEVNET_SPL_TOKEN_DECIMALS` et `KB_DEVNET_SPL_TOKEN_AMOUNT` sont optionnels. Ce test lit et vérifie un `TransferChecked`, mais ne signe, ne simule et n’envoie rien. Le parcours complet de création contrôlée, simulation, envoi et post-validation reste une étape d’orchestration distincte. ## Orchestration SPL Token Devnet `0.4.4-pre.005-delta-fix-001` `simulate_devnet_spl_token` accepte une opération typée universelle mais impose Devnet dans ce parcours opérateur. Il exécute le préflight stateful, charge le wallet persistant du profil comme fee payer, construit le plan officiel, applique la safety commune, estime les frais et simule la transaction exacte avec une preuve liée au hash du message. Cette API ne dépend d’aucun store, ne signe pas et exige `submit=false`. `execute_devnet_spl_token` réutilise exactement la même préparation. L’envoi demande `submit=true`, la confirmation opérateur configurée et un wallet capable de résoudre tous les signataires du message ; une autorité externe ou un multisig non disponible est refusé avant signature. Après confirmation, l’orchestrateur hydrate la transaction canonique, exécute core extraction, rejoue uniquement le programme Token classique, lit les matérialisations de la signature et lance un second replay pour vérifier l’absence de nouvelle sortie. Le test réseau `optional_devnet_checked_transfer_simulation_and_submission_from_env` utilise les mêmes variables que le préflight, avec `KB_DEVNET_SPL_TOKEN_EXECUTION_TEST=1`. Il reste en simulation seule par défaut. `KB_DEVNET_SPL_TOKEN_SUBMIT=1` autorise l’envoi et exige alors `KB_POSTGRES_TEST_URL`; le wallet sélectionné par `KB_DEVNET_WALLET_DIR` doit correspondre à l’autorité Token fournie. La simulation puis l’envoi réel ont réussi sur Devnet le 15 juillet 2026 avec deux comptes Token auxiliaires classiques. Le test soumis vérifie désormais explicitement la soumission, la confirmation, le premier replay sans échec ni refus, la présence d’une matérialisation et le second replay sans nouvelle sortie ; avec `--nocapture`, il imprime la signature, le statut et le nombre de matérialisations. Le probe `optional_devnet_recent_instruction_probe_from_env`, activé par `KB_DEVNET_SPL_TOKEN_RECENT_PROBE_TEST=1`, audite séparément les deux tags récents sans envoi. Son `Batch` contient un `TransferChecked` de montant brut nul sur les comptes classiques déjà contrôlés. `UnwrapLamports` utilise un compte wrapped SOL auxiliaire classique fourni par `KB_DEVNET_SPL_TOKEN_NATIVE_ACCOUNT` et simule le retrait d'un lamport vers l'autorité. Le compte natif doit être initialisé, possédé par le programme Token classique, contenir au moins un lamport wrapped et avoir `KB_DEVNET_SPL_TOKEN_AUTHORITY` comme owner ou close authority. Le test n'impose pas le succès runtime : il imprime pour chaque tag `success`, l'erreur, les compute units et les logs afin qu'un rejet de déploiement reste une preuve d'audit exploitable. Il échoue en revanche lorsque le préflight, la configuration ou le transport RPC ne permettent pas d'atteindre la simulation. Il ne signe et n'envoie aucune transaction. Le probe exécuté le 16 juillet 2026 sur le programme classique Devnet a réussi pour les deux tags : `Batch` a consommé 270 compute units et `UnwrapLamports` 140, sans erreur runtime. Cette preuve simulation-only établit le déploiement Devnet observé, mais ne vaut ni soumission ni validation de déploiement Localnet, Testnet ou Mainnet. ## Lifecycle SPL Token Devnet `0.4.4-pre.006` `prepare_devnet_spl_token_lifecycle_accounts` remplace la commande CLI historique `solana create-account`, absente de Solana CLI 4. Il génère trois keypairs éphémères, mesure le rent exact, construit trois `SystemCreateAccount` avec les tailles 82/165/165 et le propriétaire Token classique, simule, signe avec le payeur et le nouveau compte, confirme puis vérifie les données entièrement nulles. Cette préparation dépense du rent et exige donc `submit=true` et confirmation opérateur explicite. `execute_devnet_spl_token_lifecycle` accepte ensuite le mint et les deux comptes Token frais, rent-exempt, non initialisés et possédés par le programme classique. Il refuse les alias de comptes, les montants non canoniques, une délégation vers l'autorité elle-même et toute exécution sans `submit=true` et confirmation opérateur explicite. Le lifecycle conserve les montants bruts en chaînes et enchaîne onze appels à l'orchestrateur unitaire : `InitializeMint2`, deux `InitializeAccount3`, `MintToChecked`, `TransferChecked`, `ApproveChecked`, `Revoke`, deux `BurnChecked` et deux `CloseAccount`. Le montant minté est exactement réparti entre les deux burns. Chaque étape doit produire une signature confirmée, une matérialisation et un second replay sans nouvelle sortie avant le début de la suivante. Une séquence partiellement réussie n'est jamais présentée comme atomique ni automatiquement compensée. Le test opt-in prépare et consomme automatiquement des comptes frais avec `KB_DEVNET_SPL_TOKEN_LIFECYCLE_PREPARE=1`. Les variables manuelles `MINT`, `SOURCE`, `DESTINATION`, `DELEGATE` et `AUTHORITY` restent acceptées lorsque la préparation automatique est désactivée. Une reprise utilise `KB_DEVNET_SPL_TOKEN_LIFECYCLE_FIRST_STEP_INDEX` et exige `KB_DEVNET_SPL_TOKEN_LIFECYCLE_RESUME_PREDECESSOR_SIGNATURE`. La signature n'est pas un simple acquittement opérateur : elle doit produire la transaction canonique réussie et exactement l'opération matérialisée attendue pour l'étape précédente. `KB_DEVNET_SPL_TOKEN_LIFECYCLE_INTER_STEP_DELAY_MS`, borné à 30 secondes, espace les étapes ; le test imprime chaque signature dès la récupération ou la validation correspondante. ## Orchestration ATA Devnet `0.4.5-pre.006` Le test opt-in `optional_devnet_operation_from_env` appelle le même orchestrateur que Tauri. Il reste en simulation seule par défaut et demande `KB_DEVNET_SPL_ATA_EXECUTION_TEST=1`. Le mode `create_idempotent`, utilisé par défaut, reçoit `KB_DEVNET_SPL_ATA_MINT`. Le mode `recover_nested` exige en plus : ```text KB_DEVNET_SPL_ATA_OPERATION=recover_nested KB_DEVNET_SPL_ATA_OWNER_MINT= KB_DEVNET_SPL_ATA_NESTED_MINT= KB_DEVNET_SPL_ATA_TOKEN_PROGRAM=classic|token_2022 ``` La fixture doit exister avant le test : les deux mints sont initialisés sous le Token Program sélectionné ; l'ATA owner du wallet, le nested ATA dérivé avec cet ATA comme owner et l'ATA de destination du wallet sont initialisés et cohérents. Un solde positif du nested mint rend le transfert observable. `KB_DEVNET_SPL_ATA_SUBMIT=1` autorise ensuite explicitement la récupération destructive. Le wallet persistant du profil doit être le wallet owner et signer ; aucun autre signataire n'est résolu silencieusement. Après confirmation, le test exige la fermeture du nested ATA, la cohérence des deux comptes restants, la projection lifecycle `nested_ata_recovered`, le fait distinct `nested_ata_anti_pattern_recovered` sans score et un second replay sans nouvelle sortie. Les CPI Token classiques restent la propriété des matérialiseurs Token ; les CPI Token-2022 ne commencent pas le décodage général réservé à `0.4.6`. Le scénario classique contrôlé a été validé sur Devnet le 16 juillet 2026. La signature `37LG6GdMRp5ECG8qf1RSYxmriJk75UtCwqwzXZWpArebkKo6BQvGhYEnbDh2A6KWiUaHK28Zy1gGGZ5zihvrHskM` a déplacé 1 000 000 000 unités brutes vers l'ATA du wallet, fermé le nested ATA et produit exactement deux matérialisations parent ATA. L'owner ATA est resté initialisé et le second replay n'a créé aucune nouvelle sortie. ## Validation de clôture `0.4.5` La régression finale du 16 juillet 2026 confirme 90 tests pipeline, dont les préflights et postconditions ATA offline, ainsi que le test Devnet `RecoverNested` soumis. Les régressions associées confirment 10 tests décodeur ATA, 10 tests exécuteur ATA, 113 tests RPC, 41 tests configuration, 111 tests application, 46 tests PostgreSQL réels et Clippy global propre. ## Validation finale `0.4.2` La suite finale compte 56 tests. Le test réseau opt-in `optional_devnet_system_transfer_from_env` a réussi avec un wallet Devnet persistant préfinancé, un transfert de 1 000 000 lamports et PostgreSQL réel. Il valide le parcours commun jusqu’à l’insertion canonique, l’extraction core et le decode replay ciblé. Cette preuve ne contourne pas les préflights propres aux opérations administratives. Une opération ALT, Config, Feature, Slashing, ZK, Stake, Vote ou Loader doit encore produire un rapport stateful admissible et une preuve cluster dédiée avant toute exposition mutable supplémentaire. ### Préflight stateful Token-2022 borné `inspect_token_2022_preflight` compose les lectures RPC validées de `pre.040` avant simulation. La requête impose un plafond de comptes distincts, un budget cumulé de données, des rôles non vides et des exigences exactes par compte (`Mint`, `Account` ou `Multisig`). Les doublons strictement identiques sont dédupliqués dans l'ordre de première apparition ; les doublons contradictoires sont refusés. Le préflight peut vérifier le mint et le propriétaire attendus d'un Token Account, les decimals d'un Mint, les extensions requises et, lorsque nécessaire, un registre ElGamal lu et validé par son PDA officiel. Il retourne le slot contextuel maximal observé et ne simule ni n'envoie aucune transaction. ### Corrélation instruction/snapshot Token-2022 `correlate_token_2022_instruction_with_snapshot` compare un fait instructionnel matérialisé avec l’inventaire d’extensions d’un snapshot final déjà validé. Le résultat est explicitement `Confirmed`, `Contradicted` ou `NotApplicable`; il ne produit ni score, ni violation, ni persistance implicite. ## Préflight cryptographique Token-2022 `inspect_token_2022_cryptographic_preflight` valide avant simulation les comptes `ProofContextState` déjà vérifiés utilisés par les builders confidentiels. La lecture est bornée à huit comptes distincts. Chaque compte doit appartenir au programme natif ZK ElGamal Proof, être non exécutable, avoir la taille exacte du type de preuve attendu et conserver le discriminant officiel correspondant. Une autorité de fermeture attendue peut être exigée. Les doublons exacts sont dédupliqués ; les exigences contradictoires échouent avant tout appel RPC. Cette API ne génère, ne vérifie et ne déchiffre aucune preuve. Les preuves inline restent validées par leurs offsets et par la simulation du message exact ; les comptes context-state sont vérifiés ici avant cette simulation. ### Orchestration des preuves Token-2022 `orchestrate_token_2022_proofs` relie les références de preuve des intents confidentiels au rapport de préflight ZK. Le contrat conserve l'ordre des preuves, refuse les kinds, offsets ou comptes context-state dupliqués, exige l'Instructions Sysvar seulement en présence d'au moins une preuve inline, impose simulation et plafonds non nuls, et refuse toute soumission non confirmée. Il ne génère aucune preuve et ne signe aucune transaction. ### Orchestration d’exécution Token-2022 `validate_token_2022_execution_readiness` relie le plan exact de l’exécuteur, le hash du message compilé, la preuve de simulation, les préflights Token-2022 et ZK, l’orchestration ordonnée des preuves et la résolution complète des signataires. Une soumission est refusée si le message simulé diffère, si un signataire manque, si le plan reste en dry-run ou si la confirmation opérateur est absente. Les postconditions utilisent exclusivement `confirmed`, `contradicted` et `not_applicable`. Une postcondition non implémentée ne peut jamais être transformée en succès. ## Validation de clôture Token-2022 Le module `solana_token_2022_validation` impose un vocabulaire de statut explicite et un inventaire borné des preuves de validation. Un scénario end-to-end ne peut être marqué `confirmed` que si les preuves d’hydratation canonique, extraction core, replay, matérialisation et second replay sont toutes présentes. Les scénarios non exécutés ou indisponibles restent explicitement `not_run` ou `unavailable`. ### Matrice de validation Token-2022 `load_token_2022_validation_matrix` charge `docs/SPL_TOKEN_2022_VALIDATION_MATRIX.json` et impose l'inventaire exact des neuf scénarios, le vocabulaire des statuts et toutes les preuves requises avant un statut `confirmed`. Une preuve observée ne peut pas être attachée à un scénario `not_run` ou `unavailable`.