# Prompt de session — `0.4.3` SPL Memo v1, v3 et v4 ## 1. Mission Reprendre `khadhroony-bot2` après la clôture validée de `0.4.2` et démarrer `0.4.3`. Le jalon doit traiter **complètement** la surface SPL Memo avant de commencer SPL Token : ```text program IDs v1 / v3 / v4 -> décodage maximal -> projection métier explicite -> exécuteur typé pour les générations réellement constructibles -> simulation et validation post-exécution ``` L'objectif n'est pas seulement de reconnaître une chaîne UTF-8. Il faut produire un contrat stable pour l'audit, la recherche, la corrélation de paiements, les annotations de transaction et les futures contraintes Token-2022 MemoTransfer. Le worker d'acquisition historique décrit dans `docs/HISTORICAL_DATA_ACQUISITION_PLAN.md` reste différé et hors périmètre. Ne créer aucune crate historique et ne consommer aucun temps du jalon sur Explorer, Solscan, BigQuery ou Old Faithful. ## 2. Base de travail La base attendue est le commit Git qui clôture `0.4.2` et contient notamment : - `ROADMAP.md` avec `0.4.3 — SPL Memo v1, v3 et v4` ; - `RULES.md` avec la règle de livraison `delta-fix-NNN` ; - `prompts/022_v0_4_3_spl_memo.md` ; - `docs/HISTORICAL_DATA_ACQUISITION_PLAN.md` hors ROADMAP actif. Avant toute modification : 1. lire `RULES.md`, `README.md`, `ROADMAP.md` et `CHANGELOG.md` ; 2. lire `prompts/020_v0_4_1_native_solana_programs.md` et `prompts/021_v0_4_2_executor_solana_core.md` pour préserver les contrats de décodage, matérialisation et exécution ; 3. lire `docs/EXECUTION_MODEL.md`, `docs/SOLANA_INTERFACE_DEPENDENCIES.md` et les audits de clôture `0.4.1`/`0.4.2` ; 4. auditer `kb_decoder_spl_memo`, `kb_executor_spl_memo`, `kb_program_ids`, `kb_decoder_api`, `kb_materializer_api`, les matérialiseurs existants, `kb_execution_api`, `kb_execution_safety`, `kb_execution_solana`, `kb_pipeline`, `kb_rpc`, `kb_store_core`, `kb_store_pg` et `kb_app_demo` ; 5. inspecter les types et conventions réellement présents ; ne pas supposer qu'un helper ou schéma existe ; 6. vérifier la version exacte de `spl-memo-interface` résolue par Cargo et les sources officielles/historiques des trois générations avant d'écrire le wire. ## 3. État validé à préserver La clôture `0.4.2` a été validée avec : ```text kb_program_ids 5 tests kb_decoder_solana_core 116 tests kb_executor_solana_core 88 tests kb_execution_api 22 tests kb_execution_safety 15 tests kb_execution_solana 12 tests kb_rpc 113 tests kb_pipeline 56 tests kb_config 41 tests kb_app_demo 88 tests kb_store_pg 45 tests avec PostgreSQL réel cargo clippy --all-targets propre cargo tauri dev validé avec Vite ``` Le parcours Devnet réel System transfer a été validé avec simulation, signature, envoi, confirmation, insertion canonique, extraction core et decode replay. Les 52 méthodes HTTP et neuf paires WS standards restent couvertes ; les méthodes WS instables restent activables par endpoint et désactivables automatiquement après rejet du nœud. Aucune régression de ces invariants n'est acceptable. ## 4. Sources normatives Utiliser en priorité : - le registre local `kb_program_ids` pour les trois IDs déjà vérifiés ; - le dépôt officiel Memo : ; - la crate `spl-memo-interface` déjà cataloguée dans le workspace ; - les tags et sources historiques officiels pour v1 et v3 ; - le code runtime officiel pour la validation UTF-8 et les comptes signataires ; - des transactions réelles et des fixtures synthétiques contrôlées. Le dépôt officiel publie actuellement une interface `2.1.x` et une génération de programme v4. Ne pas mettre à jour automatiquement une dépendance ou considérer les trois générations identiques sans audit. Si l'interface officielle ne construit que l'ID courant, les instructions historiques ne peuvent être reproduites manuellement qu'après preuve que leur layout exact est le même. ## 5. Program IDs Le jalon couvre exactement : ```text SPL_MEMO_V1_PROGRAM_ID = Memo1UhkJRfHyvLMcVucJwxXeuD728EqVDDwQDxFMNo SPL_MEMO_V3_PROGRAM_ID = MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr SPL_MEMO_V4_PROGRAM_ID = Memo4c2pN8afCj432Lb7RMVKi9PbQnnW7ewFFaV3oAH ``` `MEMO_PROGRAM_ID` reste l'alias historique déjà défini dans `kb_program_ids`; ne pas l'utiliser lorsqu'une génération exacte est nécessaire. ## 6. Contraintes normatives du workspace Respecter strictement : - Rust 2024 ; - async-first pour l'I/O ; - `kb_core::Error` et `kb_core::Result` ; - aucun `anyhow`, `thiserror`, `unwrap`, `expect`, `unsafe`, panic de production ou opérateur `?` dans les nouveaux chemins de production ; - `warn(missing_docs)`, `deny(unreachable_pub)`, `forbid(unsafe_code)` ; - imports de traits uniquement lorsque possible, chemins pleinement qualifiés et `crate::` en intra-crate ; - commentaires/docstrings Rust en anglais, Markdown projet en français ; - header `file:` puis `version:` avec un seul incrément par fichier modifié ; - aucun `bincode` direct ; - aucune logique métier lourde dans `kb_app_demo` ; - `CHANGELOG.md` inchangé avant validation complète du jalon ; - `TRACING_TARGET` canonique dans `src/constants.rs` pour toute crate opérationnelle ; - aucune valeur JSON Tauri exportée en `bigint` lorsqu'elle traverse `invoke`, `emit` ou `JSON.stringify`. ## 7. Audit préalable obligatoire Avant d'implémenter, produire un tableau de vérité pour v1, v3 et v4 : - ID et statut actuel/historique ; - format exact de l'instruction ; - validation UTF-8 ; - comportement du payload vide ; - traitement des comptes ; - obligation `is_signer` ; - prise en compte de l'ordre et des doublons ; - logs runtime ; - différences de limites ou coûts ; - disponibilité d'un builder officiel ; - invocabilité actuelle sur Localnet/Devnet/Mainnet ; - corpus réel disponible. Toute différence entre générations doit apparaître explicitement dans les types, la matrice de couverture et les tests. Ne pas fusionner v1/v3/v4 sous un comportement supposé commun. ## 8. `kb_decoder_spl_memo` ### 8.1 Remplacement du scaffold - remplacer `DecoderSupport::Maybe` par `Yes` pour les trois IDs exacts et `No` pour les autres ; - déplacer la cible tracing legacy vers `src/constants.rs` avec la valeur exacte `kb_decoder_spl_memo` ; - ajouter `tracing` uniquement si des événements runtime réels sont émis ; - ne produire aucun événement pour une observation hors surface. ### 8.2 Événement décodé Définir un contrat stable qui conserve au minimum : - génération Memo v1/v3/v4 ; - Program ID exact ; - texte lorsque le payload est UTF-8 valide ; - longueur exacte en octets ; - SHA-256 du payload ; - préfixe hex borné pour diagnostic/replay ; - liste ordonnée des comptes fournis ; - pour chaque compte : pubkey, signer, writable et position ; - liste des signataires exigés/observés selon le contrat de la génération ; - chemin outer/inner et index stable ; - succès/échec de la transaction ; - `committed` ou intention non commitée ; - statut de validation UTF-8 et de validation des signataires ; - diagnostic borné pour une tentative invalide. Le texte complet peut être conservé si sa taille est intrinsèquement bornée par la transaction Solana et par une limite explicite du décodeur. La limite et la stratégie de troncature éventuelle doivent être testées et documentées. ### 8.3 Transactions échouées Une transaction échouée doit pouvoir produire une intention structurée lorsque le payload et les comptes sont suffisamment lisibles, sans prétendre que le runtime a validé UTF-8, vérifié les signataires ou commit l'annotation. Distinguer clairement : - payload valide et transaction réussie ; - payload valide mais transaction échouée ; - payload UTF-8 invalide ; - compte requis non signer ; - observation tronquée ou mal formée ; - génération/ID inconnu. ### 8.4 Couverture et corpus Créer une matrice machine-readable dédiée, par exemple : ```text docs/SPL_MEMO_MATRIX.json ``` Elle doit être vérifiée par un test Rust et couvrir les trois program IDs, les cas de succès, les erreurs et les différences de génération. Corpus minimal : - payload vide ; - ASCII ; - Unicode multi-octets ; - taille proche de la limite pratique ; - octets UTF-8 invalides ; - zéro, un et plusieurs signataires ; - compte non signer ; - comptes supplémentaires ou dupliqués si acceptés par le runtime ; - outer instruction ; - inner/CPI ; - transaction réussie ; - transaction échouée ; - au moins une signature réelle par génération lorsque disponible. ## 9. Matérialisation Le décodage maximal doit être stabilisé avant la projection. Le domaine attendu est une **annotation de transaction** consultable. Ne pas détourner arbitrairement `metadata`, `admin`, `lifecycle` ou `trades`. Après audit des contrats existants : 1. utiliser un matérialiseur existant seulement si son domaine couvre explicitement les annotations de transaction ; 2. sinon créer une crate dédiée, par exemple `kb_materializer_transaction_annotations`, avec un contrat réutilisable au-delà de Memo ; 3. garder les faits de vérification/audit séparables du texte si plusieurs consommateurs sont nécessaires. Projection minimale : - signature et instruction path ; - génération et Program ID ; - texte ou représentation bornée ; - longueur et hash ; - signataires vérifiés ; - état committed ; - provenance du processor et version ; - clé d'idempotence déterministe. Règles : - aucune projection réussie mutable pour une transaction non commitée ; - replay identique = skip/idempotence ; - changement de version = remplacement déterministe selon le ledger ; - ne pas dupliquer les logs ou données core déjà stockés ; - documenter explicitement toute donnée laissée uniquement dans l'événement décodé. ## 10. `kb_executor_spl_memo` ### 10.1 Contrat typé Remplacer le plan réservé par une voie typée fondée sur `kb_execution_api`. Types candidats : ```text SplMemoGeneration SplMemoOperation::AddMemo SplMemoExecutionIntent SplMemoSigner ``` Le contrat doit permettre : - choix explicite de la génération ; - payload UTF-8 validé avant plan ; - signataires ordonnés et déclarés ; - absence de compte writable inventé ; - limites de taille explicites ; - coût de dépense nul hors frais réseau ; - `Supported`/`Unsupported(reason)` exact par génération. ### 10.2 Builders et wire - utiliser `spl-memo-interface` lorsque son builder et son Program ID correspondent exactement à la génération demandée ; - comparer les instructions produites aux builders officiels ; - pour une génération historique sans builder courant, construire manuellement uniquement après validation du layout depuis les sources officielles ; - le payload Memo est constitué des octets exacts du message, sans préfixe, discriminator, Borsh ou `bincode` inventé ; - chaque compte signer doit apparaître avec les flags officiels exacts ; - rejeter les doublons ou formes anormales seulement si le contrat officiel les rejette réellement. ### 10.3 Politiques - simulation obligatoire ; - dry-run par défaut ; - aucune activation Mainnet par défaut ; - signataires visibles avant signature ; - fee payer déclaré ; - plafond de frais appliqué par l'infrastructure commune ; - aucune clé privée dans les logs, Tauri ou les payloads JSON ; - post-validation par hydratation, core extraction et decode replay Memo. Les générations historiques peuvent rester `Unsupported(reason)` côté exécuteur si leur invocabilité actuelle ou leur builder ne peut pas être prouvé. Elles restent néanmoins obligatoires côté décodeur. ## 11. Pipeline, store et démo - enregistrer le décodeur et le matérialiseur dans le replay commun ; - ajouter les déclarations de couverture et tests de sélection ; - toucher `kb_store_pg` uniquement si une nouvelle projection nécessite réellement un contrat de persistance ; - conserver les écritures atomiques avec le ledger decode/materialize ; - utiliser `demo_decode_replay` pour les corpus et résumés ; - ne créer une nouvelle fenêtre Tauri que si l'exécution Memo Devnet ne peut pas être validée avec les surfaces existantes ; - une démo d'exécution peut rester backend/test opt-in si l'UI n'apporte pas de valeur supplémentaire. ## 12. Validation Devnet Ajouter un test opt-in ou un petit parcours opérateur qui : 1. charge le wallet temporaire Devnet existant ; 2. construit un Memo de la génération courante validée ; 3. simule ; 4. signe et envoie seulement avec autorisation explicite ; 5. confirme ; 6. appelle `getTransaction` ; 7. insère la transaction canonique ; 8. exécute core extraction ; 9. exécute decode replay Memo ; 10. vérifie la projection et l'idempotence. Ne pas exiger l'envoi des générations historiques si elles ne sont plus officiellement déployées ou supportées sur Devnet. ## 13. Documentation attendue Mettre à jour au minimum : ```text kb_decoder_spl_memo/README.md kb_executor_spl_memo/README.md README.md ROADMAP.md docs/SOLANA_INTERFACE_DEPENDENCIES.md docs/SPL_MEMO_MATRIX.json ``` Ajouter le README du matérialiseur créé ou modifié. Documenter : - différences v1/v3/v4 ; - types d'événements ; - projection choisie ; - opérations exécutables ; - limites et refus ; - corpus et signatures réelles utilisées ; - résultats Localnet/Devnet ; - absence volontaire de projection ou d'exécution, le cas échéant. `CHANGELOG.md` ne doit être modifié qu'après validation complète de `0.4.3`. ## 14. Interdictions Ne pas : - commencer SPL Token, ATA, Token-2022, Stake Pool, Pump, Meteora, Raydium, Orca ou Jupiter ; - créer ou commencer W2/historical acquisition ; - fusionner Memo dans `kb_decoder_solana_core` ; - considérer les trois IDs comme identiques sans preuve ; - utiliser les logs RPC comme seule source du texte lorsque l'instruction est disponible ; - inventer un discriminator ou une structure sérialisée ; - exposer un envoi Mainnet par défaut ; - produire une projection committed pour une transaction échouée ; - ajouter du SQL libre à l'UI ; - générer des bindings TypeScript contenant des `bigint` dans les frontières Tauri JSON. ## 15. Validations minimales Selon les fichiers touchés : ```bash cargo test -p kb_program_ids cargo test -p kb_decoder_spl_memo cargo test -p kb_materializer_transaction_annotations # si créée cargo test -p kb_executor_spl_memo cargo test -p kb_execution_api cargo test -p kb_execution_safety cargo test -p kb_execution_solana cargo test -p kb_pipeline cargo test -p kb_rpc cargo test -p kb_app_demo cargo clippy --all-targets ``` Si le store ou la projection est touché : ```bash KB_POSTGRES_TEST_URL='postgres://solana:solana@localhost:5432/solana_test' \ cargo test -p kb_store_pg -- --nocapture ``` Si Tauri est touché : ```bash cargo tauri dev -c kb_app_demo/tauri.conf.json ``` Le serveur Vite lancé par Tauri constitue la validation frontend normale ; ne pas imposer un `npm run build` séparé sans besoin particulier. ## 16. Livraison Livrer des tranches fonctionnelles sous la forme : ```text khadhroony-bot2_v0.4.3-pre.NNN-delta.zip ``` Après la livraison d'un delta `pre.NNN`, tout correctif conserve le même numéro : ```text khadhroony-bot2_v0.4.3-pre.NNN-delta-fix-001.zip khadhroony-bot2_v0.4.3-pre.NNN-delta-fix-002.zip ``` Ne pas incrémenter `NNN` pour réparer une archive déjà livrée. Le numéro suivant est réservé à une nouvelle tranche fonctionnelle. Chaque archive doit contenir : - uniquement les fichiers ajoutés ou modifiés ; - `delta.md` non versionné ; - `manifest.json` ; - les suppressions manuelles explicitement listées ; - les validations exécutées et non exécutées ; - aucune archive complète sauf demande explicite ; - aucune modification de `CHANGELOG.md` avant validation finale du jalon.