v0.1.0-pre.073

This commit is contained in:
2026-07-31 19:34:00 +02:00
parent 3b1ded6909
commit 5e1ad759d8
148 changed files with 14056 additions and 18 deletions

View File

@@ -0,0 +1,193 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.47_1FE5_CONTINUATION_V2.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.47-1FE5`
Reprise du projet `khadhroony-bobobot`.
## Archive de départ
Utiliser comme base de travail :
```text
kb_lib-v0.7.47-1FE5-full.zip
```
Joindre aussi les docs mises à jour :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
```
## Décision de planification
Ne plus tenter “tous les events de tous les decoders” dans une seule session. Lobjectif reste de couvrir tous les decoders disponibles dans Carbon et les sources Git/IDL, mais par tranches DEX/version.
Ordre cible :
```text
raydium_cpmm
raydium_clmm
pump_swap
pump_fun
meteora_dbc
meteora_dlmm
meteora_damm_v1
meteora_damm_v2
phoenix_v1
openbook_v2
orca_whirlpools
launch surfaces
DEX historiques / candidats
```
## Sources upstream obligatoires
Ces sources sont des indices de décodage, pas des preuves de validation locale :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders
https://github.com/0xfnzero/solana-streamer
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
https://github.com/pinax-network/substreams-solana-idls/tree/main/src
https://github.com/hodlwarden/solana-tx-parser/tree/main/src
https://github.com/openbook-dex/openbook-v2
https://github.com/all-in-one-blockchain/phoenix-onchain-mm
https://docs.vybenetwork.com/docs/available-dexs-amms
```
## État validé
Dernier état validé côté `kb_lib` :
```text
cargo test -p kb_lib
371 passed
```
Clippy doit être relancé à chaque tranche :
```bash
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## 0.7.47 acquis
- Upstream Git Registry ajouté.
- Demo3 étendu : multi-target, multi-source, pagination, orderbook targets, burn/mint/transfer/wrap/unwrap/stake.
- Demo2 backfill signature fonctionnel.
- Replay local avec ledger.
- OpenBook v2 decoder audit-only.
- Phoenix v1 decoder audit-only.
- Les decoders audit-only ne produisent aucun trade/candle.
## OpenBook v2
Program id :
```text
opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb
```
État :
```text
audit-only local decoder
upstream_git fallback cleaned
Program data mapped:
- FillLog
- OpenOrdersPositionLog
- TotalOrderFillEvent
- SettleFundsLog
trade_count = 0
```
Ne pas activer de trade/candle tant que maker/taker/base/quote et les lots ne sont pas validés.
## Phoenix v1
Program id :
```text
PhoeNiXZ8ByJGLkxNfZRnkUfjvmuYqLR89jjFHGqdXY
```
État :
```text
audit-only local decoder
log instruction strict 0x0f
events observed:
- Reduce
- Place
- TimeInForce
currentInstructionTag mappings:
- 0x09 CancelUpToWithFreeFunds
- 0x0c WithdrawFunds
- 0x10 PlaceMultiplePostOnlyOrders
trade_count = 0
```
Prochaine action préférée : finir Phoenix v1 avec tous les events disponibles dans les sources Git/IDL, mais rester audit-only jusquà validation économique.
## Contraintes
- Rust 2024.
- Pas de `mod.rs`.
- Fichiers Rust avec entête `// file: ...`.
- Exposition centralisée via `lib.rs`.
- `#![deny(unreachable_pub)]`, `#![warn(missing_docs)]`.
- Pas de `anyhow`.
- Pas de `thiserror`.
- Pas de `?`, `unwrap`, `expect` dans le code applicatif.
- Utiliser `match`, `if let Err`, `let Err = ... else`.
- Si une requête DB est ajoutée/modifiée, mettre à jour `kb_lib/src/db.rs`, puis `kb_lib/src/lib.rs` si nécessaire.
## Méthode par DEX/version
Pour chaque DEX/version :
1. inspecter Carbon + autres sources Git/IDL ;
2. lister tous les discriminants instructions/events ;
3. compléter `upstream_registry` / matrice si nécessaire ;
4. utiliser Demo3 pour corpus ;
5. backfill Demo2 ;
6. replay forcé ;
7. valider SQL ;
8. ajouter decoder audit-only ou materialized selon preuve ;
9. supprimer les doublons `upstream_git.instruction_match` si decoder spécialisé ;
10. ne jamais produire trade/candle sans montants exploitables et sens économique validé.
## Requêtes de sécurité audit-only
```sql
SELECT
de.protocol_name,
de.event_kind,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name IN ('openbook_v2', 'phoenix_v1')
GROUP BY de.protocol_name, de.event_kind
ORDER BY trade_count DESC;
```
Attendu :
```text
trade_count = 0
```
## Livrable attendu
Pour chaque tranche :
- fichiers ajoutés/modifiés seulement ;
- archive zip ;
- commandes de test ;
- requêtes SQL ;
- notes sur ce qui reste non vérifié ;
- ne pas prétendre quun event ou program id est vérifié sans corpus local.

View File

@@ -0,0 +1,157 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.47_EVENT_COVERAGE_V3.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.47-1FE5` / Event coverage
Reprise du projet `khadhroony-bobobot`.
## Archive de départ
Utiliser :
```text
khadhroony-bobobot-v0.7.47-1FE5-full.zip
```
Et les docs :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
```
## Décision de reprise
Ne pas essayer de “faire tous les events de tous les DEX” dans une seule session.
La stratégie est maintenant :
```text
un DEX/version = une tranche
tous les events listés = audit coverage
matérialisation seulement après corpus + SQL + invariants
```
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
## Objectif événementiel
Décoder le maximum devents, pas seulement les swaps.
Inclure explicitement :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Raison : burn, perte de liquidité, changements admin/config, vault withdraw, migration, mint anormal, close account, etc. peuvent influencer une décision de trading même si ce ne sont pas des trades.
## Base de données
La base actuelle suffit pour audit-only via `k_sol_dex_decoded_events`, mais elle nest pas suffisante pour tout exploiter en requêtes métier.
À considérer avant ou pendant `0.7.48` :
```text
k_sol_dex_event_coverage_entries
k_sol_token_transfer_events
k_sol_token_account_events
k_sol_orderbook_events
k_sol_vault_events
k_sol_launch_events
k_sol_liquidity_lock_events
```
Priorité minimale :
```text
1. k_sol_dex_event_coverage_entries
2. k_sol_token_transfer_events
3. k_sol_orderbook_events
```
## Ordre des versions
```text
0.7.48-pre event coverage + DB model checkpoint
0.7.48 raydium_cpmm
0.7.49 raydium_clmm
0.7.50 pump_swap
0.7.51 pump_fun
0.7.52 meteora_dbc
0.7.53 meteora_dlmm
0.7.54 meteora_damm_v1
0.7.55 meteora_damm_v2
0.7.56 phoenix_v1
0.7.57 openbook_v2
0.7.58 orca_whirlpools
0.7.59 launch surfaces
0.7.60 DEX historiques/candidats
0.7.61 validation consolidée
```
## Règles fixes
- Un event non-trade ne produit jamais trade/candle.
- Une transaction failed reste audit, jamais trade/candle.
- Un discriminator upstream nest pas une preuve métier.
- Un program id upstream nest pas vérifié sans corpus local.
- Chaque decoder spécialisé doit remplacer le fallback `upstream_git.instruction_match` pour éviter les doublons.
- Tout event connu mais non observé reste `upstream_git_mapped_unverified`.
- Tout event observé mais non matérialisé reste audit-only ou decoded, pas materialized.
## Prochaine tâche recommandée
Commencer par :
```text
0.7.48-pre — event coverage + DB model checkpoint
```
Livrables attendus :
1. ajouter/documenter une table de couverture event/discriminator ;
2. générer un rapport de couverture par DEX/version ;
3. préparer `raydium_cpmm` avec la liste complète des events depuis Carbon/fnzero/IDL ;
4. ne pas changer encore la matérialisation trade/candle.

View File

@@ -0,0 +1,251 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.47_UPSTREAM_REGISTRY.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.47`
Reprise du projet `khadhroony-bobobot`.
## Contexte
Le workspace contient principalement :
- `kb_lib` : logique métier Solana/DEX, clients HTTP/WS, décodage, détection, SQLite, replay, validation, diagnostics, metadata, candles, signaux ;
- `kb_demo_app` : application Tauri V2 de démo/inspection. Elle doit rester une façade UI et ne pas contenir de logique métier DEX profonde.
La version `0.7.46` est clôturée sur `meteora_damm_v1`.
## État validé à la fin de `0.7.46`
- `cargo test -p kb_lib` : vert.
- `cargo clippy -p kb_lib --all-targets -- -D warnings` : vert.
- Demo2 et Demo3 fonctionnent bien pour backfill et discovery.
- Demo3 supporte :
- multi-target ;
- multi-source ;
- pagination `before` / `until` ;
- `max_pages` ;
- `newest_first` / `oldest_first`.
- Le replay local supporte le ledger de décodage/replay et les options `skipDexDecode` / `forceDexDecode`.
- `meteora_damm_v1` couvre les surfaces observées localement :
- `swap` ;
- `claim_fee` ;
- `create_lock_escrow` ;
- `lock_liquidity` ;
- `remove_liquidity` ;
- `add_liquidity` ;
- `create_pool`.
- Les statuts/payloads ne doivent plus utiliser une terminologie spécifique à un dépôt externe particulier.
- Les statuts génériques attendus sont :
- `upstream_git_unverified` ;
- `upstream_git_mapped_unverified` ;
- `upstream_git_local_corpus_observed` ;
- `upstream_git_local_corpus_materialized` ;
- `upstream_git_layout_unverified` si le layout est connu depuis une source Git mais pas encore validé localement.
## Décision base de données pour `0.7.47`
La version `0.7.46` est considérée finalisée. Ne pas demander ni proposer de replay forcé de lancienne base `0.7.46` pour clôturer cette version, sauf demande explicite.
Pour `0.7.47`, le développement et la validation doivent se faire de préférence sur une **nouvelle base SQLite dédiée**. Cette base servira à constituer un corpus propre avec Demo3 et Demo2 sur plusieurs paires, pools ou programmes de DEX différents.
Règles pratiques :
- lancienne base `0.7.46` peut servir de référence historique ou de comparaison, mais elle ne doit pas être migrée ou redécodée automatiquement ;
- si une validation DB est nécessaire en `0.7.47`, elle doit cibler la nouvelle base de travail `0.7.47` ;
- les backfills `0.7.47` doivent être construits à partir de Demo3 discovery puis Demo2 signature/pool backfill ;
- le replay local reste utile, mais seulement après constitution du corpus `0.7.47`, pas comme étape de finalisation de `0.7.46` ;
- les entrées du registre upstream Git restent des indices tant quelles ne sont pas observées sur cette nouvelle base ou sur un corpus explicitement indiqué.
## Objectif de `0.7.47`
`0.7.47` est dédiée à :
```text
Upstream Git Registry / DEX discovery preparation
```
Lobjectif nest pas de valider directement un DEX unique. Lobjectif est de créer un registre générique permettant dindexer les `program_id`, discriminants dinstructions, discriminants devents, noms dinstructions, familles de programmes et types de surfaces issus de dépôts Git externes de decoders Solana.
Ces entrées sont des **indices de découverte**, pas des preuves métier. Elles doivent rester non vérifiées tant quelles ne sont pas confirmées par :
1. Demo3 discovery ;
2. backfill signature/pool via Demo2 ;
3. replay local sur la base de travail `0.7.47` ;
4. requêtes SQL de validation sur cette même base ;
5. invariants métier : pas de faux trade, pas de fausse candle, pas de promotion de `program_id` sans corpus.
## Noms recommandés
Modules possibles :
```text
kb_lib/src/upstream_registry.rs
kb_lib/src/upstream_registry_types.rs
kb_lib/src/upstream_registry_match.rs
kb_lib/src/upstream_registry_generated.rs
```
Nom fonctionnel :
```text
Upstream Git Registry
```
Ne pas utiliser de nom de dépôt externe spécifique dans les noms publics, les statuts, les tables ou les payloads métier.
## Première tranche attendue
Créer une première version statique du registre dans `kb_lib`, sans modifier la DB si ce nest pas nécessaire.
Chaque entrée de registre devrait contenir au minimum :
```text
source_repo
source_path
decoder_code
program_id
program_family
surface_kind
entry_kind = instruction | event | account | program
entry_name
discriminator_hex
discriminator_len
proof_status
notes
```
Les entrées de registre doivent être exposées à `kb_demo_app` via une commande Demo3 ou une commande dédiée, mais la logique reste dans `kb_lib`.
## Familles à indexer en priorité
DEX / AMM / CLMM / orderbook :
```text
meteora_damm_v2
meteora_dbc
meteora_dlmm
meteora_vault
raydium_amm_v4
raydium_clmm
raydium_cpmm
raydium_launchpad
raydium_liquidity_locking
raydium_stable_swap
orca_whirlpools
fluxbeam
lifinity_v2
phoenix_v1
openbook_v2
stabble_stable_swap
stabble_weighted_swap
bonkswap
boop
moonshot
heaven
okx_dex
pancake_swap
vertigo
virtuals
wavebreak
onchain_labs_dex_v1
onchain_labs_dex_v2
```
Agrégateurs / ordres / perps / lending :
```text
jupiter_swap
jupiter_dca
jupiter_limit_order
jupiter_limit_order_2
jupiter_perpetuals
jupiter_lend
kamino_lending
kamino_vault
kamino_farms
kamino_limit_order
drift_v2
marginfi_v2
dflow_aggregator_v4
zeta
```
Contexte transactionnel non DEX :
```text
system_program
token_program
token_2022
associated_token_account
address_lookup_table
memo_program
stake_program
mpl_token_metadata
mpl_core
bubblegum
name_service
marinade_finance
solayer_restaking_program
swig
sharky
circle_message_transmitter_v2
circle_token_messenger_v2
```
## Règles de validation
- Une entrée upstream Git reste `upstream_git_unverified` tant quelle na pas été vue localement.
- Une entrée branchée dans un decoder mais jamais vue localement reste `upstream_git_mapped_unverified`.
- Une entrée vue après Demo3/backfill/replay peut devenir `upstream_git_local_corpus_observed`.
- Une entrée qui alimente correctement une table métier dédiée peut devenir `upstream_git_local_corpus_materialized`.
- Aucun `program_id`, event ou discriminator ne doit être déclaré vérifié uniquement parce quil existe dans un dépôt Git externe.
- Aucun event non-trade ne doit produire trade, metric ou candle.
## Contraintes de code
- Rust 2024.
- Pas de `mod.rs`.
- Fichiers Rust avec entête `// file: ...`.
- Fichiers `.toml` avec entête `# file: ...`.
- Exposition centralisée via `lib.rs`.
- `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]`.
- Pas de `anyhow`.
- Pas de `thiserror`.
- Pas de `?`, `unwrap`, `expect` dans le code applicatif.
- Utiliser `match`, `if let Err`, `let Err = ... else`.
- Tests verts à chaque étape.
- Si une requête DB est ajoutée/modifiée, mettre à jour les re-exports dans `kb_lib/src/db.rs`, puis `kb_lib/src/lib.rs` si nécessaire.
## Format de livraison attendu
Pour chaque tranche :
1. expliquer brièvement les fichiers touchés ;
2. fournir une archive des fichiers ajoutés/modifiés seulement, avec larborescence du projet ;
3. indiquer les commandes de test à lancer ;
4. indiquer les requêtes SQL utiles si validation DB nécessaire ;
5. ne jamais prétendre quun `program_id` ou un event est vérifié sans preuve/corpus.
dexlab
bags / letsbonk / bonk_fun
believe
moonit
launchbeam
metadao / metaDAO
printr
zora
aldrin
aldrin_v2
crema
cropper
cropper_legacy
guacswap
invariant
lifinity_v1
openbook_v1 / serum-style legacy
orca_v1
orca_v2
saber
saros
serum_v3
token_swap

View File

@@ -0,0 +1,329 @@
<!-- file: docs/prompts/NEXT_SESSION_PROMPT_0.7.49_RAYDIUM_CLMM.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.49` / Raydium CLMM event coverage
Reprise du projet `khadhroony-bobobot` après clôture fonctionnelle de `0.7.48 raydium_cpmm`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.48-raydium-cpmm-final
```
Docs à fournir aussi :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_48.sql
```
## État validé avant reprise
`0.7.48` a clôturé la tranche `raydium_cpmm` :
```text
k_sol_dex_event_coverage_entries synchronisée en snake_case local
k_sol_instruction_observations ajoutée comme table technique d'index instruction/discriminator
Demo3 enrichie avec recherche instruction/discriminator
Solscan instruction=<discriminator> utilisé comme accélérateur de recherche de signatures
raydium_cpmm Program data décodé pour lp_change_event / swap_event
raydium_cpmm deposit / withdraw / lp_change_event matérialisés liquidity
raydium_cpmm initialize / initialize_with_permission matérialisés lifecycle-only
raydium_cpmm collect_*_fee matérialisés fee
raydium_cpmm create_amm_config / create_permission_pda / update_amm_config matérialisés admin/config
raydium_cpmm swap_event conservé audit-only
close_permission_pda et update_pool_status conservés upstream_git_mapped_unverified faute de corpus local
instruction inconnue 40f4bc78a7e9690a conservée raydium_cpmm.instruction_audit
```
Validation locale finale observée :
```text
cargo test -p kb_lib: ok, 386 passed
cargo clippy -p kb_lib --all-targets -- -D warnings: ok
replay local: 1124 replayed, 561 trades, 50 liquidity, 9 lifecycle, 2224 candle upserts
```
Couverture finale `raydium_cpmm` :
```text
lp_change_event 25/25 liquidity, 0 trade
swap_event 529 decoded-only, 0 trade
deposit 11/11 liquidity, 0 trade
withdraw 14/14 liquidity, 0 trade
initialize 5/5 lifecycle, 0 admin, 0 trade
initialize_with_permission 4/4 lifecycle, 0 admin, 0 trade
collect_creator_fee 4/4 fee, 0 trade
collect_fund_fee 7/7 fee, 0 trade
collect_protocol_fee 15/15 fee, 0 trade
create_amm_config 6/6 admin, 0 trade
create_permission_pda 4/4 admin, 0 trade
update_amm_config 13/13 admin, 0 trade
swap_base_input 750 decoded, 482 trades
swap_base_output 25 decoded, 17 trades
close_permission_pda upstream_git_mapped_unverified
update_pool_status upstream_git_mapped_unverified
```
Invariants maintenus :
```text
non-trade event = jamais trade/candle
failed transaction = audit-only
upstream Git/IDL/Solscan = indice, pas preuve métier
program_id upstream non promu sans corpus local
chaque decoder spécialisé remplace le fallback upstream_git.instruction_match
side effects SPL Token / Token-2022 restent transversaux, pas raydium_cpmm.* directs
pas de nouvelle table métier transversale sans preuve multi-DEX
```
## Décision de reprise
Commencer `0.7.49` par `raydium_clmm`, avant Pump/Meteora.
Ordre courant :
```text
0.7.49 raydium_clmm
0.7.50 pump_swap
0.7.51 pump_fun
0.7.52 meteora_dbc
0.7.53 meteora_dlmm upstream parity
0.7.54 meteora_damm_v1 upstream parity
0.7.55 meteora_damm_v2
0.7.56 phoenix_v1 audit-only completion
0.7.57 openbook_v2 audit-only completion
0.7.58 orca_whirlpools
0.7.59+ launch surfaces, candidats/historiques, validation consolidée
```
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
Pour `0.7.49 raydium_clmm`, utiliser aussi explicitement :
```text
https://solscan.io/account/CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK#programIdl
```
et les filtres Solscan de type :
```text
https://solscan.io/account/CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Solscan doit servir à trouver vite des signatures à backfiller, jamais comme preuve métier finale.
## Objectif `0.7.49` — `raydium_clmm`
Objectif : reprendre `raydium_clmm` comme deuxième tranche Raydium/version après CPMM.
À faire :
1. lire le code local `raydium_clmm` et les matérialisations existantes ;
2. lister toutes les instructions/events CLMM depuis Carbon/fnzero/IDL/Raydium/Solscan Program IDL ;
3. synchroniser/remplir `k_sol_dex_event_coverage_entries` pour `raydium_clmm` ;
4. utiliser `k_sol_instruction_observations` pour inspecter les discriminants réellement observés localement ;
5. ajouter à Demo3 les filtres instruction/discriminant CLMM si un binding/UI manque encore ;
6. chercher des signatures ciblées via Solscan `instruction=<discriminator>` ;
7. backfiller les signatures utiles dans Demo Pipeline 2 ;
8. rejouer localement `forceDexDecode=yes` ;
9. comparer listed/decoded/observed/materialized/trade_count via SQL coverage ;
10. compléter le decoder spécialisé `raydium_clmm` seulement pour les events confirmables ;
11. remplacer/nettoyer le fallback `upstream_git.instruction_match` quand un decoder local spécialisé couvre l'entrée ;
12. garder les events connus mais non observés en `upstream_git_mapped_unverified` ;
13. garder les events observés mais non matérialisés en audit-only/decoded ;
14. ne matérialiser que les non-trades prouvés par corpus et compatibles avec les tables existantes ;
15. ne pas modifier les règles trade/candle sauf bug de faux positif prouvé.
## Familles à couvrir explicitement
Ne pas se limiter aux swaps.
Inclure dans l'audit coverage CLMM :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Pour `raydium_clmm`, certaines familles sont probablement non applicables ou seulement observées comme side effects SPL Token/Token-2022. Elles doivent être explicitement justifiées dans la coverage matrix.
## Points d'attention hérités de CPMM
- `decoder_code` local doit rester en `snake_case` : `raydium_clmm`, pas `raydium-clmm`.
- Les slugs/chemins upstream peuvent garder les tirets : `raydium-clmm-decoder`.
- Les events side effects SPL Token (`burn`, `transfer`, `transferChecked`, `closeAccount`) ne doivent pas devenir `raydium_clmm.*` sans preuve qu'ils sont des instructions directes du programme CLMM.
- `k_sol_instruction_observations` est technique et peut être enrichie ; ne pas la confondre avec une table métier.
- `initialize_*` / création de pool doit rester lifecycle-only si c'est bien une création, pas admin.
- Les positions CLMM sont potentiellement des tables/catégories existantes ou à auditer : ne pas forcer liquidity simple si l'event représente une position NFT/tick.
- Les rewards/fees CLMM peuvent nécessiter un mapping plus fin que CPMM.
## Requêtes SQL utiles
Coverage CLMM :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_clmm'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Instruction observations CLMM :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_clmm'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC;
```
Non-trade safety :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(le.id) AS liquidity_count,
COUNT(fe.id) AS fee_count,
COUNT(pa.id) AS admin_count,
COUNT(ple.id) AS lifecycle_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events pa
ON pa.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events ple
ON ple.decoded_event_id = de.id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_clmm'
GROUP BY de.event_kind
ORDER BY de.event_kind;
```
Fallback upstream CLMM :
```sql
SELECT
json_extract(payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(payload_json, '$.entryName') AS entry_name,
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS fallback_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'upstream_git'
AND event_kind = 'upstream_git.instruction_match'
AND json_extract(payload_json, '$.upstreamDecoderCode') = 'raydium_clmm'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex
ORDER BY fallback_count DESC, entry_name;
```
Failed transaction safety :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_clmm'
AND tx.err_json IS NOT NULL
AND tx.err_json <> ''
GROUP BY de.event_kind
ORDER BY trade_count DESC, decoded_count DESC;
```
## Contraintes de code
Conserver les règles du workspace :
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Livrables attendus pour `0.7.49`
1. delta archive avec uniquement les fichiers ajoutés/modifiés ;
2. mise à jour `README.md`, `ROADMAP.md`, `CHANGELOG.md` si la tranche avance ;
3. rapport de couverture `raydium_clmm` ;
4. SQL de validation ;
5. tests verts :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```

View File

@@ -0,0 +1,150 @@
<!-- file: docs/prompts/PROMPT_0_7_53_PUMP_SWAP.md -->
# Prompt de reprise — `0.7.53 pump_swap`
Nous reprenons le workspace Rust/Tauri `khadhroony-bobobot` après le commit final `0.7.52 raydium_stable_swap`.
## Objectif de tranche
Version cible : `0.7.53`
Surface cible unique : `pump_swap`
Program id cible unique :
```text
pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA
```
Règle de phasage validée : **une version = un `program_id`**.
`raydium_pool_v4.json` est explicitement repoussé vers la fin du phasage. Il ne doit pas bloquer `0.7.53`.
## Contexte validé avant reprise
Raydium est clos sur les surfaces suivantes :
- `raydium_cpmm``CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C` ;
- `raydium_clmm``CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK` ;
- `raydium_launchpad``LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj` ;
- `raydium_amm_v4``675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` ;
- `raydium_stable_swap``5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h`.
`0.7.52 raydium_stable_swap` est clos avec :
- `cargo test -p kb_lib` : `407 passed`, `0 failed` ;
- `cargo clippy -p kb_lib --all-targets -- -D warnings` : OK ;
- swaps matérialisés uniquement depuis `amountSource=stable_swap_vault_balance_delta` ;
- failed transactions conservées decoded-only ;
- aucun successful swap non expliqué.
## Sources à utiliser pour `pump_swap`
Sources obligatoires à vérifier avant de patcher :
- `kb_lib/src/constants.rs` et `SOLSCAN_ACCOUNT_SOURCES` ;
- sources upstream Git déjà intégrées dans le registre : Carbon, fnzero, Pinax, HODL Warden si disponibles ;
- IDL Solscan du programme `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` si disponible ;
- corpus local Demo3 + backfill signature/pool ;
- `k_sol_dex_event_coverage_entries` après replay.
Les sources Git/IDL/Solscan sont des indices. La preuve métier exige corpus local, replay et SQL.
## Tâches attendues
1. Inspecter le support local existant de `pump_swap`.
2. Lister toutes les instructions/events/discriminators disponibles depuis les sources upstream/IDL.
3. Comparer avec les events localement couverts.
4. Compléter le decoder `pump_swap` pour couvrir au minimum :
- `buy` ;
- `sell` ;
- fees / creator fees / protocol fees si présents ;
- admin/config si présents ;
- events auxiliaires tels que cashback, volume accumulator ou équivalents si présents dans les sources.
5. Matérialiser en `k_sol_trade_events` et `k_sol_pair_candles` uniquement si les montants exacts et le sens économique sont prouvés.
6. Conserver les failed transactions comme decoded-only avec `failed_transaction`.
7. Matérialiser les non-trade uniquement vers les tables adaptées : liquidity, fee, admin, lifecycle, reward, orderbook ou decoded-only selon le cas.
8. Nettoyer les fallbacks `upstream_git.instruction_match` uniquement quand un decoder local spécialisé couvre vraiment lentrée.
9. Mettre à jour la coverage DB et la matrice documentaire.
10. Ajouter ou mettre à jour le SQL de validation dédié : `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql`.
## Invariants obligatoires
- Aucun non-swap ne doit créer de trade/candle.
- Aucune transaction failed ne doit créer de trade/candle.
- Aucun trade/candle ne doit être créé depuis des bornes dinstruction ou des montants incomplets.
- Aucun router/aggregator ne doit créer un doublon si le DEX effectif matérialise déjà le trade.
- Aucun `program_id` ne doit être inventé.
- Aucun compte non-programme de `SOLSCAN_ACCOUNT_SOURCES` ne doit être promu en decoder autonome.
- `kb_demo_app` ne doit pas contenir de logique métier DEX profonde.
## Contraintes de code
Respecter les contraintes du projet :
- Rust 2024 ;
- aucun fichier `mod.rs` ;
- pas de `pub mod` ; utiliser `mod` + `pub use` ;
- pas de `anyhow`, pas de `thiserror` ;
- pas de `?`, `unwrap`, `expect` dans le code applicatif `kb_lib` ;
- gestion derreurs explicite via `match`, `if let Err`, `let Err = ... else` ;
- rustdoc publique ;
- `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]` ;
- tracing obligatoire ;
- tests offline ;
- si une requête DB est ajoutée ou modifiée, mettre à jour les re-exports dans `kb_lib/src/db.rs`, puis dans `kb_lib/src/lib.rs`.
## Validation attendue
Commandes locales à exécuter après patch :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
Replay attendu sur une base dédiée `0.7.53 pump_swap` :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
SQL de clôture attendu :
- coverage par entrée `pump_swap` ;
- instruction observations ;
- absence daudit résiduel local non expliqué ;
- absence de fallback upstream pour les entrées couvertes localement ;
- failed tx -> zéro trade ;
- non-swap -> zéro trade ;
- decoded without coverage -> vide ;
- successful non-materialized inexpliqués -> vide ;
- multi-target materialization -> vide ;
- résumé matérialisation par event_kind.
## Livrables documentaires
Mettre à jour au minimum :
- `ROADMAP.md` ;
- `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/PUMP_SWAP_EVENT_COVERAGE_REPORT.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql`.
## Décision attendue en fin de tranche
`0.7.53 pump_swap` est clôturable uniquement si :
```text
- tous les events/instructions disponibles ont un statut explicite ;
- les swaps réussis exploitables produisent trades/candles ;
- les failed transactions restent decoded-only ;
- les non-trade sont matérialisés dans les bonnes tables ou restent decoded-only expliqués ;
- la coverage DB ne contient pas de gap local inexpliqué ;
- cargo test et clippy sont OK.
```

View File

@@ -0,0 +1,272 @@
<!-- file: docs/prompts/PROMPT_0_7_54_PUMP_FUN.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.54 — pump_fun
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture documentaire et fonctionnelle de `0.7.53 pump_swap`.
## 1. Fichiers à utiliser comme base
Je fournis larchive la plus récente du workspace, intégrant normalement les deltas de clôture `0.7.53`.
À considérer comme sources locales de savoir :
- le code Rust du workspace ;
- les fichiers Markdown (`README.md`, `ROADMAP.md`, `CHANGELOG.md`, `docs/**`) ;
- les SQL de validation dans `validation_sql/**` ;
- le répertoire `idls/**`, ajouté au projet, contenant des IDL JSON téléchargés depuis Solscan ;
- les liens Git/upstream déjà documentés dans les docs ;
- les résultats SQL/logs que je colle dans la conversation.
Ne pas supposer que les docs sont parfaites : les vérifier contre le code et contre les IDL locales.
## 2. État validé avant cette version
La version `0.7.53` a fermé `pump_swap` côté transaction/log decoder :
- `cargo test -p kb_lib` : `421 passed`;
- `cargo clippy -p kb_lib --all-targets -- -D warnings` : OK ;
- `pump_swap.buy`, `pump_swap.sell`, `pump_swap.buy_exact_quote_in` matérialisent correctement les trades ;
- `buy_exact_quote_in` utilise `pump_swap_anchor_buy_event` quand lAnchor `BuyEvent` exact est disponible ;
- les `*_event` Anchor PumpSwap sont décodés en audit-only sauf exception métier explicite ;
- `claim_token_incentives_event` est prêt à matérialiser `k_sol_reward_events` si un event réussi apparaît ;
- `pump_swap` ne présente plus de decoded event sans coverage, ni fallback upstream résiduel, ni trade candidate réussi non matérialisé ;
- les surfaces Raydium déjà travaillées (`raydium_amm_v4`, `raydium_clmm`, `raydium_cpmm`) ne doivent pas être rouvertes sauf bug prouvé ;
- les petits gaps Meteora sont volontairement différés.
Ne pas modifier PumpSwap ou Raydium sauf preuve SQL/code claire dune régression.
## 3. Objectif de la version 0.7.54
Objectif principal : ouvrir et avancer une tranche `pump_fun`.
Cette tranche doit traiter la surface launch/mint Pump.fun, qui est logiquement prioritaire avant `pump_fees`.
Le backlog global montre des entrées `pump_fun` encore en fallback upstream, notamment :
- `pump_fun.collect_creator_fee` / discriminator `1416567bc61cdb84` ;
- `pump_fun.migrate_bonding_curve_creator` / `577c34bf3426d6e8` ;
- `pump_fun.distribute_creator_fees` / `a572670079cef751` ;
- `pump_fun.admin_set_creator` / `4519ab8e39ef0d04` ;
- `pump_fun.extend_account` / `ea66c2cb96483ee5` ;
- `pump_fun.set_creator` / `fe94ff70cf8eaaa5` ;
- `pump_fun.migrate` / `9beae792ec9ea21e` ;
- `pump_fun.claim_cashback` / `253a237ebe35e4c5` ;
- `pump_fun.sell` / `33e685a4017f83ad` ;
- autres discriminators `pump_fun` observés dans `k_sol_instruction_observations`.
Lobjectif nest pas seulement de faire disparaître un fallback : il faut couvrir proprement la surface `pump_fun` :
- registry/coverage ;
- decoder local ou statut local explicitement decoded-only/audit-only ;
- matérialisation métier si les données sont fiables ;
- tests unitaires ;
- SQL de validation ;
- documentation.
## 4. Périmètre
### Inclus
- `pump_fun` launch/mint/bonding-curve surface ;
- instructions/events liés à création/migration/configuration/creator fees/cashback si présents dans IDL ou corpus ;
- intégration coverage ;
- matérialisation vers tables métier seulement si fiable.
### Hors périmètre sauf nécessité démontrée
- `pump_swap`, déjà fermé en `0.7.53` ;
- `raydium_*`, sauf régression prouvée ;
- `meteora_*`, volontairement différé ;
- `jupiter_swap`, `dflow_aggregator_v4`, `onchain_labs_dex_v2`, `orca_whirlpools`, backlog futur ;
- `pump_fees`, qui doit venir après `pump_fun`, probablement en `0.7.55`.
## 5. Méthode obligatoire
### 5.1 Nouvelle base SQLite
Créer une nouvelle DB dédiée à `0.7.54`, ne pas travailler sur lancienne DB de validation PumpSwap.
Démarrage attendu :
- catalog initial propre ou connu ;
- backfills ciblés ;
- replay forcé ;
- validation SQL.
### 5.2 Backfill de corpus
Construire un corpus local à partir de :
1. filtres Solscan.io quand disponibles ;
2. Demo3 discovery quand nécessaire ;
3. batch backfill de groupes de signatures ;
4. program/signature backfill si pertinent ;
5. signatures issues des requêtes SQL `sample_signature`.
Utiliser dabord les signatures fortes observées dans le backlog :
- `pump_fun.collect_creator_fee`;
- `pump_fun.migrate_bonding_curve_creator`;
- `pump_fun.distribute_creator_fees`;
- `pump_fun.admin_set_creator`;
- `pump_fun.extend_account`;
- `pump_fun.set_creator`;
- `pump_fun.migrate`;
- `pump_fun.claim_cashback`;
- puis autres discriminators observés.
Après chaque groupe de backfill :
- replay local avec `skipDexDecode=no`;
- utiliser `forceDexDecode=yes` quand le decoder/coverage change ;
- `deferInstructionObservations=yes` ;
- rafraîchir catalog ;
- relancer les SQL de surveillance.
### 5.3 Sources
Utiliser en priorité :
- `idls/**` local ;
- code existant ;
- docs existantes ;
- `upstream_registry_generated.rs` ;
- sources Git déjà référencées dans les docs ;
- Solscan signatures/logs ;
- payloads locaux DB.
Si une IDL locale contredit une source Git, signaler la divergence et ne pas inventer.
## 6. Contraintes de code Rust
Respecter strictement les conventions du projet :
- Rust 2024 ;
- pas de `?` ;
- pas de `unwrap()` / `expect()` en code applicatif ;
- pas de `anyhow` / `thiserror` ;
- `match` / `if let Err` explicites ;
- async-first ;
- `tracing` obligatoire ;
- pas de `mod.rs` ;
- pas de `pub mod` ; utiliser `mod` + `pub use` ;
- imports limités, types appelés de façon qualifiée quand cest la convention locale ;
- tests offline ;
- ne pas casser `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]`.
Si des requêtes DB sont ajoutées ou déplacées, penser aux re-exports :
- `kb_lib/src/db.rs` ;
- `kb_lib/src/lib.rs`.
## 7. Matérialisation attendue
Pour `pump_fun`, ne pas forcer une matérialisation si les montants/acteurs/comptes ne sont pas prouvés.
Classer explicitement chaque entrée :
- `k_sol_launch_events` pour les événements de launch/mint/migration ;
- `k_sol_fee_events` si linstruction représente réellement des frais exploitables ;
- `k_sol_pool_admin_events` si cest de la configuration/admin/creator ;
- `k_sol_reward_events` uniquement si cest réellement une récompense/incitation/cashback fiable ;
- `k_sol_dex_decoded_events_only` si audit-only ou données insuffisantes ;
- `k_sol_trade_events` seulement si cest un swap/trade fiable ;
- `skip*Reason` explicite quand non matérialisable.
Ne jamais matérialiser une transaction failed comme business event.
## 8. SQL de validation à utiliser
Utiliser et adapter :
- `validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql`;
- les SQL de validation PumpSwap comme modèle ;
- une nouvelle validation dédiée à `pump_fun`, par exemple :
- `validation_sql/SQL_VALIDATION_PUMP_FUN_0_7_54.sql`.
Requêtes minimales attendues :
1. coverage `pump_fun` ;
2. instruction observations `pump_fun` ;
3. decoded events `pump_fun` sans coverage ;
4. fallback upstream `pump_fun` résiduel ;
5. successful non-materialized events sans skip reason ;
6. failed tx materialization safety ;
7. multi-target materialization safety ;
8. materialization summary ;
9. comparaison entre `k_sol_instruction_observations` et `k_sol_dex_event_coverage_entries` ;
10. global watchlist après replay.
## 9. Invariants de validation
Après correction, viser :
- pas de `pump_fun` decoded event local sans coverage ;
- pas de fallback `upstream_git` résiduel pour les entrées `pump_fun` couvertes localement ;
- pas de materialized business event sur failed transaction ;
- pas de multi-target incohérent ;
- tous les events/instructions observés ont :
- un decoder local,
- ou un statut audit-only,
- ou un skip reason explicite,
- ou une justification documentée sils restent upstream-only.
## 10. Documentation à mettre à jour
À la fin de la tranche, mettre à jour :
- `CHANGELOG.md` : une ligne ;
- `README.md` : état courant, nouvelle version, validation ;
- `ROADMAP.md` : phasage et clôture/état de `pump_fun`, puis annonce de `pump_fees` en version suivante ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- éventuellement un rapport :
- `docs/reports/PUMP_FUN_EVENT_COVERAGE_REPORT.md`.
Ne pas gonfler les docs inutilement : noter les faits validés, les limites, et les prochaines tranches.
## 11. Format de livraison attendu
Ne pas fournir une archive complète du workspace sauf demande explicite.
Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
`khadhroony-bobobot-v0.7.54-pump_fun-delta-N-files.zip`
Chaque réponse de livraison doit inclure :
- résumé des changements ;
- liste exacte des fichiers modifiés ;
- commandes à lancer :
- `cargo fmt`
- `cargo test -p kb_lib`
- `cargo clippy -p kb_lib --all-targets -- -D warnings`
- replay recommandé ;
- SQL à exécuter ;
- ce qui est attendu dans les résultats.
## 12. Priorités si plusieurs gaps apparaissent
Ordre de priorité :
1. `pump_fun` ;
2. `pump_fees` seulement si strictement nécessaire pour comprendre un flux `pump_fun` ;
3. ne pas traiter Meteora dans cette version ;
4. ne pas rouvrir Raydium sauf régression démontrée ;
5. ne pas ouvrir Jupiter/dFlow/onchain_labs dans cette tranche sauf pour les classer en backlog.
## 13. Première tâche demandée
Commencer par analyser larchive fournie :
1. identifier les fichiers existants liés à `pump_fun`, `pump_fees`, upstream registry, coverage, materialization ;
2. chercher dans `idls/**` sil existe une IDL Solscan liée à `pump_fun` ;
3. produire un état des lieux court :
- entrées upstream disponibles ;
- entrées observées dans SQL/logs fournis ;
- fichiers à modifier ;
- hypothèse de classification par entry ;
- SQL initial de backfill/validation ;
4. proposer puis produire le premier delta archive minimal.

View File

@@ -0,0 +1,347 @@
<!-- file: docs/prompts/PROMPT_0_7_55_PUMP_FEES.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.55 — pump_fees
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture technique de `0.7.54 pump_fun`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après clôture `0.7.54 pump_fun`.
À considérer comme sources locales de savoir :
- code Rust du workspace ;
- `README.md`, `ROADMAP.md`, `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/PUMP_FUN_EVENT_COVERAGE_REPORT.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_FUN_0_7_54.sql` ;
- `validation_sql/SQL_VALIDATION_PUMP_FUN_MATERIALIZATION_0_7_54.sql` ;
- `idls/**`, en particulier `idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json` ;
- les logs/requêtes SQL collés pendant la session.
Ne pas supposer que la documentation est parfaite : vérifier contre le code, l'IDL locale et le corpus SQLite.
## 2. État validé avant cette version
`0.7.54 pump_fun` est clos.
Replay final rapporté :
```text
1679 replayed
0 decode skipped
1679 ledger upserts
145 unsafe ledger rows
89 trades
0 liquidity
10 lifecycle
0 tokenAccount
348 candle upserts
instructionObservations = 13905
resetDeleted = 1112
catalog = 52 tokens / 50 pools / 50 pairs
```
Checks de fermeture Pump.fun :
- upstream fallback Pump.fun : vide ;
- decoded Pump.fun sans coverage : vide ;
- successful non-materialized sans skip reason : vide ;
- failed transaction materialization safety : vide ;
- multi-target materialization safety : vide ;
- trade candidates Pump.fun sans matérialisation ni skip : vide ;
- watchlist globale : plus aucun `pump_fun`.
Décisions Pump.fun à préserver :
- `buy`, `sell`, `buy_exact_sol_in` sont matérialisés directement quand les montants sont fiables ;
- `buy_v2`, `sell_v2`, `buy_exact_quote_in_v2` ne sont pas matérialisés directement ;
- `trade_event` est la source canonique des montants exécutés v2/exact ;
- aucun double-count entre instruction trade et event Anchor ;
- transactions failed audit-only.
Ne pas rouvrir `pump_fun`, `pump_swap` ou Raydium sauf bug prouvé par SQL/code.
## 3. Objectif de `0.7.55 pump_fees`
Ouvrir et clôturer la surface `pump_fees`.
Program id cible :
```text
pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ
```
IDL locale :
```text
idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json
```
exemple de code:
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/pump-fees-decoder
L'IDL locale contient au minimum :
- `29` instructions ;
- `20` events ;
- `9` accounts ;
- `34` types.
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite.
Le programme `pump_fees` est a priori un programme de fee/config/accounting. Aucun trade/candle direct n'est attendu sauf preuve transactionnelle très forte d'un swap économique autonome.
## 4. Backlog initial observé
La watchlist globale après `0.7.54 pump_fun` montre notamment :
```text
pump_fees get_fees e7257e55cf5b3f34 173 decoded / 171 tx
pump_fees create_fee_sharing_config c34e564c6f34fbd5 21 decoded / 21 tx
pump_fees update_fee_shares bd0d8863bba4ed23 14 decoded / 14 tx
```
Ces trois entrées doivent être les premières sources de corpus/backfill.
## 5. Périmètre fonctionnel
### Inclus
- décodage de toutes les instructions `pump_fees` connues par l'IDL locale ;
- décodage de tous les events Anchor `pump_fees` connus par l'IDL locale ;
- décodage Borsh des arguments et payloads quand les layouts sont définis ;
- classification coverage par famille : fee, reward, admin/config, buyback, social fee, donation fee, fee sharing, account lifecycle ;
- matérialisation vers les tables métier existantes quand les données sont fiables :
- `k_sol_fee_events` ;
- `k_sol_reward_events` si cashback/social/donation/claim représente une récompense exploitable ;
- `k_sol_pool_admin_events` pour config/admin/authority/tier/update ;
- `k_sol_pool_lifecycle_events` si création/initialisation de compte/config est pertinente ;
- `k_sol_dex_decoded_events_only` pour les vues/calculs/audit-only ;
- SQL de validation dédié ;
- documentation finale et rapport.
### Hors périmètre sauf preuve stricte
- nouveau trade/candle direct ;
- réouverture Pump.fun/PumpSwap ;
- Raydium/Meteora/Jupiter/dFlow ;
- refactor réseau ou UI non nécessaire.
## 6. Méthode obligatoire : nouvelle base SQLite
Créer une nouvelle DB dédiée à `0.7.55 pump_fees`.
Ne pas réutiliser l'ancienne DB de validation Pump.fun sauf pour lire des signatures de départ.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis :
- refresh catalog ;
- replay local ;
- relancer SQL de validation ;
- noter les compteurs replay.
## 7. Corpus et backfills
Construire le corpus local à partir de :
1. signatures `sample_signature` de la watchlist globale ;
2. filtres Solscan.io par program id + instruction/discriminator quand disponibles ;
3. Demo3 discovery multi-source/multi-target ;
4. batch backfill par groupes de signatures ;
5. program/signature backfill ciblé si nécessaire ;
6. signatures issues des requêtes SQL `instruction_observations`, fallback upstream et decoded-only résiduels.
Démarrer par :
- `get_fees` / `e7257e55cf5b3f34` ;
- `create_fee_sharing_config` / `c34e564c6f34fbd5` ;
- `update_fee_shares` / `bd0d8863bba4ed23`.
Ensuite couvrir les autres instructions/events de l'IDL locale, même non observés, par tests synthétiques lorsque le layout est connu.
## 8. Instructions IDL locales à inventorier
Inventorier et classifier au minimum :
- `claim_social_fee_pda` ;
- `claim_social_fee_pda_v2` ;
- `crank_donation_fee_pda` ;
- `create_donation_fee_pda` ;
- `create_fee_sharing_config` ;
- `create_social_fee_pda` ;
- `extend_fee_config` ;
- `get_fees` ;
- `initialize_buyback` ;
- `initialize_fee_config` ;
- `initialize_fee_program_global` ;
- `reset_fee_sharing_config` ;
- `reset_fee_sharing_config_v2` ;
- `revoke_fee_sharing_authority` ;
- `set_authority` ;
- `set_claim_rate_limit` ;
- `set_disable_flags` ;
- `set_social_claim_authority` ;
- `sweep_buyback` ;
- `transfer_fee_sharing_authority` ;
- `update_admin` ;
- `update_buyback_authority` ;
- `update_buyback_claim_rate_limit` ;
- `update_fee_config` ;
- `update_fee_shares` ;
- `update_fee_shares_v2` ;
- `update_stable_fee_config` ;
- `upsert_fee_tiers` ;
- `upsert_stable_fee_tiers`.
Events Anchor à inventorier :
- `CreateFeeSharingConfigEvent` ;
- `DonationFeePdaCranked` ;
- `DonationFeePdaCreated` ;
- `ExtendFeeConfigEvent` ;
- `InitializeFeeConfigEvent` ;
- `InitializeFeeProgramGlobalEvent` ;
- `ResetFeeSharingConfigEvent` ;
- `SetAuthorityEvent` ;
- `SetClaimRateLimitEvent` ;
- `SetDisableFlagsEvent` ;
- `SetSocialClaimAuthorityEvent` ;
- `SocialFeePdaClaimed` ;
- `SocialFeePdaCreated` ;
- `SweepBuybackEvent` ;
- `UpdateAdminEvent` ;
- `UpdateFeeConfigEvent` ;
- `UpdateFeeSharesEvent` ;
- `UpdateStableFeeConfigEvent` ;
- `UpsertFeeTiersEvent` ;
- `UpsertStableFeeTiersEvent`.
## 9. Contraintes de code Rust
Respecter strictement les conventions du projet :
- Rust 2024 ;
- pas de `?` ;
- pas de `unwrap()` / `expect()` en code applicatif ;
- pas de `anyhow` / `thiserror` ;
- `match` / `if let Err` explicites ;
- async-first ;
- `tracing` obligatoire ;
- pas de `mod.rs` ;
- pas de `pub mod` ; utiliser `mod` + `pub use` ;
- imports limités, types appelés de façon qualifiée quand c'est la convention locale ;
- tests offline ;
- ne pas casser `#![deny(unreachable_pub)]` et `#![warn(missing_docs)]`.
Si des requêtes DB sont ajoutées ou déplacées, penser aux re-exports :
- `kb_lib/src/db.rs` ;
- `kb_lib/src/lib.rs`.
## 10. Matérialisation attendue
Ne pas se contenter de decoded-only si une matérialisation fiable est possible.
Classification cible :
- `get_fees` : probablement decoded-only ou fee calculation audit ; ne pas matérialiser comme fee payé sans transfert/montant réalisé ;
- fee sharing config : `k_sol_pool_admin_events` ou lifecycle/config si comptes exploitables ;
- social/donation fee PDA create/claim/crank : `k_sol_fee_events`, `k_sol_reward_events` ou admin/lifecycle selon le sens exact des flux ;
- buyback init/sweep/update : fee/admin/buyback selon comptes et montants ;
- authority/config/tier updates : `k_sol_pool_admin_events` ;
- Anchor events : matérialiser s'ils portent le montant/acteur/compte fiable ; sinon audit-only avec skip reason ;
- transactions failed : decoded-only/audit-only, jamais business matérialisé.
Aucun `pump_fees` ne doit créer de `k_sol_trade_events` ni de candle sauf preuve irréfutable d'un trade économique autonome et non doublonné.
## 11. SQL de validation attendu
Créer :
```text
validation_sql/SQL_VALIDATION_PUMP_FEES_0_7_55.sql
```
Requêtes minimales :
1. upstream fallback samples `pump_fees` ;
2. local instruction observations `pump_fees` ;
3. coverage `pump_fees` ;
4. decoded events `pump_fees` sans coverage ;
5. residual upstream fallback pour entrées couvertes ;
6. successful non-materialized sans skip reason ;
7. failed transaction materialization safety ;
8. multi-target materialization safety ;
9. materialization summary par table ;
10. instruction observation versus coverage ;
11. contrôle anti-trade/candle direct `pump_fees` ;
12. global watchlist après replay.
## 12. Invariants de fermeture
La tranche `0.7.55` ne doit être considérée close que si :
- aucun fallback `upstream_git` `pump_fees` ne reste pour les entrées couvertes localement ;
- aucun decoded event `pump_fees` local sans coverage ;
- aucune transaction failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ;
- aucun trade/candle `pump_fees` artificiel ;
- toutes les instructions/events de l'IDL locale sont soit décodés/matérialisés, soit audit-only, soit non observés mais couverts par tests synthétiques ;
- la watchlist globale ne contient plus de `pump_fees` comme backlog dominant.
## 13. Documentation à mettre à jour en fin de tranche
Mettre à jour :
- `CHANGELOG.md` ;
- `README.md` ;
- `ROADMAP.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- créer `docs/reports/PUMP_FEES_EVENT_COVERAGE_REPORT.md` ;
- créer ou mettre à jour le SQL de validation dédié.
## 14. Format de livraison attendu
Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
```text
khadhroony-bobobot-v0.7.55-pump_fees-delta-N-files.zip
```
Chaque livraison doit inclure :
- résumé des changements ;
- liste exacte des fichiers modifiés ;
- commandes à lancer :
- `cargo fmt` ;
- `cargo test -p kb_lib` ;
- `cargo clippy -p kb_lib --all-targets -- -D warnings` ;
- replay recommandé ;
- SQL à exécuter ;
- résultats attendus.
## 15. Première tâche demandée
1. Inspecter le code et l'IDL `pump_fees` locale.
2. Comparer `upstream_registry_generated.rs`, `idls/pump_fees...json` et le corpus SQL.
3. Créer une base SQLite neuve `0.7.55`.
4. Backfiller les signatures `get_fees`, `create_fee_sharing_config`, `update_fee_shares`.
5. Ajouter le decoder local maximal `pump_fees` : instructions + events + tests synthétiques.
6. Ajouter coverage/materialization/validation SQL.
7. Rejouer et fermer seulement si tous les invariants sont propres.

View File

@@ -0,0 +1,218 @@
<!-- file: docs/prompts/PROMPT_0_7_56_METEORA_DBC.md -->
# Prompt de reprise — khadhroony-bobobot 0.7.56 — meteora_dbc
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture technique de `0.7.55 pump_fees`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après clôture `0.7.55 pump_fees`.
À considérer comme sources locales de savoir :
- code Rust du workspace ;
- `README.md`, `ROADMAP.md`, `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/PUMP_FEES_EVENT_COVERAGE_REPORT.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_FEES_0_7_55.sql` ;
- `idls/**`, en particulier `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json` ;
- les logs/requêtes SQL collés pendant la session.
Ne pas supposer que la documentation est parfaite : vérifier contre le code, l'IDL locale, les sources Git et le corpus SQLite.
## 2. État validé avant cette version
`0.7.55 pump_fees` est clos.
Replay final rapporté :
```text
127 replayed
0 decode skipped
150 ledger upserts
125 unsafe ledger rows
4 trades
0 liquidity
115 lifecycle
0 tokenAccount
16 candle upserts
instructionObservations = 2234
resetDeleted = 1644
catalog = 11 tokens / 10 pools / 10 pairs
```
Validation build :
```text
cargo test -p kb_lib -> 431 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Checks de fermeture Pump Fees :
- fallback `upstream_git` `pump_fees` : vide ;
- `instruction_name` vide : vide ;
- `event_family = unknown` ou vide pour instruction/event : vide ;
- decoded `pump_fees` sans coverage : vide ;
- successful non-materialized sans skip/policy : vide ;
- failed transaction materialization safety : vide ;
- multi-target materialization safety : vide ;
- anti-trade/candle direct `pump_fees` : vide ;
- watchlist globale : plus aucun `pump_fees`, seulement `jupiter_swap.route_v2` ponctuel.
Décisions Pump Fees à préserver :
- `get_fees` est decoded-only ;
- claims social fee vers `k_sol_reward_events` seulement si succès et montant fiable ;
- donation/buyback vers `k_sol_fee_events` seulement si succès et montant fiable ;
- config/authority/tier/update vers `k_sol_pool_admin_events` ;
- create/init/extend vers `k_sol_pool_lifecycle_events` ;
- aucun trade/candle direct ;
- failed tx audit-only ;
- les discriminators Solscan `revoke_fee_sharing_authority_event` et `transfer_fee_sharing_authority_event` restent conservés comme futures surfaces non observées.
Ne pas rouvrir `pump_fees`, `pump_fun`, `pump_swap` ou Raydium sauf bug prouvé par SQL/code.
## 3. Objectif de `0.7.56 meteora_dbc`
Ouvrir et clôturer la surface `meteora_dbc`.
Program id cible :
```text
dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN
```
IDL locale prioritaire :
```text
idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json
```
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite.
La surface DBC doit couvrir launch/bonding curve, pool/config lifecycle, swaps exploitables, migration, fees/admin/config, et events Anchor associés.
## 4. Méthode obligatoire : nouvelle base SQLite
Créer une nouvelle DB dédiée à `0.7.56 meteora_dbc`.
Ne pas réutiliser l'ancienne DB de validation Pump Fees sauf pour lire des signatures de départ.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis :
- refresh catalog ;
- replay local ;
- relancer SQL de validation ;
- noter les compteurs replay.
## 5. Corpus et backfills
Construire le corpus local à partir de :
1. signatures `sample_signature` de la watchlist globale et des coverage gaps ;
2. filtres Solscan.io par program id + instruction/discriminator quand disponibles ;
3. Demo3 discovery multi-source/multi-target ;
4. batch backfill par groupes de signatures ;
5. program/signature backfill ciblé si nécessaire ;
6. signatures issues des requêtes SQL `instruction_observations`, fallback upstream et decoded-only résiduels.
Inclure explicitement les transactions failed dans le corpus d'audit, mais ne jamais les matérialiser métier.
## 6. Sources à comparer
Comparer au minimum :
- `idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json` ;
- Carbon `meteora-dbc-decoder` ;
- Pinax/Substreams Solana IDLs si disponibles ;
- Solana Streamer / sol-parser-sdk si des layouts Meteora DBC y apparaissent ;
- code local existant `kb_lib/src/dex/*meteora*` ;
- `upstream_registry_generated.rs` ;
- corpus SQLite neuf.
## 7. Matérialisation attendue
Ne pas se contenter de decoded-only si une matérialisation fiable est possible.
Cibles probables :
- swaps exploitables -> `k_sol_trade_events` + candles si montants, sens, mint base/quote et pool/pair sont fiables ;
- pool/config/create -> `k_sol_pool_lifecycle_events` et catalog/pool/pair si comptes fiables ;
- liquidity/deposit/withdraw -> `k_sol_liquidity_events` si montants et pool fiables ;
- migration -> lifecycle/admin selon sémantique exacte ;
- fees/creator fees/admin/config -> `k_sol_fee_events` ou `k_sol_pool_admin_events` ;
- events sans contexte suffisant -> decoded-only/audit-only avec skip reason.
Transactions failed : decoded-only/audit-only, jamais business matérialisées.
## 8. SQL de validation attendu
Créer :
```text
validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql
```
Requêtes minimales :
1. upstream fallback samples `meteora_dbc` ;
2. local instruction observations `meteora_dbc` ;
3. coverage `meteora_dbc` ;
4. decoded events `meteora_dbc` sans coverage ;
5. residual upstream fallback pour entrées couvertes ;
6. successful non-materialized sans skip reason ;
7. failed transaction materialization safety ;
8. multi-target materialization safety ;
9. materialization summary par table, avec colonnes successful/failed ;
10. instruction observation versus coverage ;
11. anti-faux trade/candle pour events non swap ;
12. global watchlist après replay.
## 9. Invariants de fermeture
La tranche `0.7.56` ne doit être considérée close que si :
- aucun fallback `upstream_git` `meteora_dbc` ne reste pour les entrées couvertes localement ;
- aucun decoded event `meteora_dbc` local sans coverage ;
- aucune transaction failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ;
- aucun faux trade/candle sur event non swap ;
- toutes les instructions/events de l'IDL locale sont soit décodés/matérialisés, soit audit-only, soit non observés mais couverts par tests synthétiques ;
- la watchlist globale ne contient plus de `meteora_dbc` comme backlog dominant.
## 10. Documentation à mettre à jour en fin de tranche
Mettre à jour :
- `CHANGELOG.md` ;
- `README.md` ;
- `ROADMAP.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- créer `docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md` ;
- créer `validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql`.
## 11. Format de livraison attendu
Fournir un delta zip contenant uniquement les fichiers modifiés/ajoutés.
Nom recommandé :
```text
khadhroony-bobobot-v0.7.56-meteora_dbc-delta-pre.xxx.zip
```
Inclure dans chaque livraison : résumé des changements, liste exacte des fichiers modifiés, commandes `cargo fmt`, `cargo test -p kb_lib`, `cargo clippy -p kb_lib --all-targets -- -D warnings`, replay recommandé, SQL à exécuter et résultats attendus.

View File

@@ -0,0 +1,457 @@
<!-- file: docs/prompts/PROMPT_0_7_57_METEORA_DLMM_FULL_DECODE_MATERIALIZATION.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.57` — `meteora_dlmm` full decode / full materialization
Tu reprends le workspace Rust/Tauri `khadhroony-bobobot` après clôture de `0.7.56 meteora_dbc`.
## 1. Archive et fichiers à fournir
Utiliser l'archive la plus récente après application des docs `0.7.56 final`.
Fichiers à lire en priorité :
- `README.md` ;
- `ROADMAP.md` ;
- `CHANGELOG.md` ;
- `docs/DEX_DECODER_MATRIX.md` ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` ;
- `docs/reports/METEORA_DBC_EVENT_COVERAGE_REPORT.md` ;
- `docs/reports/FEE_EVENT_AMOUNTS_MODEL_NOTE_0_7_56.md` ;
- `docs/VALIDATION_STATUS_0_7_56_FINAL.md` ;
- `validation_sql/SQL_VALIDATION_METEORA_DBC_0_7_56.sql` ;
- `validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql` ;
- `idls/**`, en particulier `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` ;
- `kb_lib/src/dex/meteora_dlmm.rs` ;
- `kb_lib/src/non_trade_event_materialization.rs` ;
- `kb_lib/src/db/queries/fee_event_amount.rs`.
Ne pas supposer que l'ancien support `0.7.45 meteora_dlmm` est suffisant : il était partiel. `0.7.57` doit viser la parité IDL/corpus complète.
## 2. État validé avant cette version
`0.7.56 meteora_dbc` est clos.
Build final :
```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```
Replay final DBC :
```text
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
1056 candle upserts
instructionObservations = 7167
catalog = 86 tokens / 60 pools / 60 pairs
```
Socle fee final :
```text
k_sol_fee_events meteora_dbc = 89 parents
k_sol_fee_event_amounts meteora_dbc = 96 legs
parent scalar without leg = empty
orphan fee amount legs = empty
```
Règles fee à préserver :
- parent fee scalaire -> leg `k_sol_fee_event_amounts` automatique ;
- fee multi-leg/multi-mint -> parent sans agrégation artificielle, legs explicites ;
- pas de montant depuis `maxAmount`, `u64::MAX`, bornes ou limites de claim ;
- recovery CPI SPL générique uniquement si policy/allowlist explicite ;
- aucun futur decoder ne doit hériter de `allowlisted_inner_spl_transfer` par défaut.
## 3. Objectif de `0.7.57 meteora_dlmm`
Program id cible :
```text
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
```
IDL locale prioritaire :
```text
idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json
```
Nom IDL : `lb_clmm`.
Surface IDL :
```text
76 instructions
30 events Anchor
12 accounts
```
Objectif : **full decode + full materialization**.
Règle forte :
> Tout ce qui peut être décodé doit être décodé. Tout ce qui peut être matérialisé de façon fiable doit être matérialisé. Ce qui ne peut pas être matérialisé doit rester decoded-only/audit-only avec `skip*Reason` explicite. les instructions/events/anchors/discriminator non observés aprés backfill sur une base de donnée vierge devront avoir des tests syntetiques.
## 4. Méthode obligatoire
Créer une nouvelle DB dédiée à `0.7.57 meteora_dlmm`.
Après chaque backfill ou patch decoder :
```text
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
Puis : refresh catalog, replay local, SQL validation, note des compteurs.
Ne pas rouvrir `meteora_dbc`, Pump ou Raydium sauf bug prouvé par SQL.
## 5. Sources à comparer
Comparer au minimum :
- IDL locale `idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json` ;
- Carbon Meteora DLMM decoder ;
- Pinax/Substreams Solana IDLs ;
- Solana Streamer / sol-parser-sdk si DLMM y apparaît ;
- code local historique `kb_lib/src/dex/meteora_dlmm.rs` ;
- coverage existante `k_sol_dex_event_coverage_entries` ;
- corpus SQLite neuf ;
- anciens rapports `0.7.45` et matrices pour comprendre ce qui était déjà validé.
## 6. Checklist d'instructions IDL à inventorier
| Instruction | Discriminator hex |
|---|---|
| `add_liquidity` | `b59d59438fb63448` |
| `add_liquidity2` | `e4a24e1c46db7473` |
| `add_liquidity_by_strategy` | `0703967f94283dc8` |
| `add_liquidity_by_strategy2` | `03dd95da6f8d76d5` |
| `add_liquidity_by_strategy_one_side` | `2905eeaf64e106cd` |
| `add_liquidity_by_weight` | `1c8cee63e7a21595` |
| `add_liquidity_by_weight2` | `d13b3f5b6fc899e4` |
| `add_liquidity_one_side` | `5e9b6797465fdca5` |
| `add_liquidity_one_side_precise` | `a1c26754ab47fa9a` |
| `add_liquidity_one_side_precise2` | `2133a3c975627de7` |
| `cancel_limit_order` | `849c841f4328e861` |
| `claim_fee` | `a9204f8988e84689` |
| `claim_fee2` | `70bf65ab1c907fbb` |
| `claim_reward` | `955fb5f25e5a9ea2` |
| `claim_reward2` | `be037f77b2579db7` |
| `close_bin_array` | `44ae5850b5cc13e0` |
| `close_claim_fee_operator_account` | `b8d5581fb3658224` |
| `close_limit_order_if_empty` | `397c249b7ef95dab` |
| `close_operator_account` | `ab09d54a7817031d` |
| `close_position` | `7b86510031446262` |
| `close_position2` | `ae5a2373ba2893e2` |
| `close_position_if_empty` | `3b7cd4765b986e9d` |
| `close_preset_parameter` | `04949164861ab53d` |
| `close_preset_parameter2` | `27195f6b7411731c` |
| `close_token_badge` | `6c92566eb3fe0a68` |
| `create_operator_account` | `dd40f695f099e5a3` |
| `decrease_position_length` | `c2db882019606925` |
| `for_idl_type_generation_do_not_call` | `b46945505f32496c` |
| `fund_reward` | `bc32f9a55d97263f` |
| `go_to_a_bin` | `9248aee028fd54ae` |
| `increase_oracle_length` | `be3d7d57674f9ead` |
| `increase_position_length` | `505375d3420d2195` |
| `increase_position_length2` | `ffd2cc477389e171` |
| `initialize_bin_array` | `235613b94ed44bd3` |
| `initialize_bin_array_bitmap_extension` | `2f9de2b40cf02147` |
| `initialize_customizable_permissionless_lb_pair` | `2e2729876fb7c840` |
| `initialize_customizable_permissionless_lb_pair2` | `f349817e3313f16b` |
| `initialize_lb_pair` | `2d9aedd2dd0fa65c` |
| `initialize_lb_pair2` | `493b2478ed536cc6` |
| `initialize_permission_lb_pair` | `6c66d555fb033515` |
| `initialize_position` | `dbc0ea47bebf6650` |
| `initialize_position2` | `8f13f291d50f6873` |
| `initialize_position_by_operator` | `fbbdbef475fe2394` |
| `initialize_position_pda` | `2e527d92558de499` |
| `initialize_preset_parameter` | `42bc47d3626d0eba` |
| `initialize_reward` | `5f87c0c4f281e644` |
| `initialize_token_badge` | `fd4dcd5f1be059df` |
| `place_limit_order` | `6cb021ba92e501c5` |
| `rebalance_liquidity` | `5c04b0c177b95309` |
| `remove_all_liquidity` | `0a333d2370691855` |
| `remove_liquidity` | `5055d14818ceb16c` |
| `remove_liquidity2` | `e6d7527ff165e392` |
| `remove_liquidity_by_range` | `1a526698f04a691a` |
| `remove_liquidity_by_range2` | `cc02c391359191cd` |
| `set_activation_point` | `5bf90fa51a81fe7d` |
| `set_pair_status` | `43f8e7899a95d9ae` |
| `set_pair_status_permissionless` | `4e3b98d346b72ed0` |
| `set_permissionless_operation_bits` | `543acb8ba351beba` |
| `set_pre_activation_duration` | `a53dc9f4829f1664` |
| `set_pre_activation_swap_address` | `398b2f7bd850df0a` |
| `swap` | `f8c69e91e17587c8` |
| `swap2` | `414b3f4ceb5b5b88` |
| `swap_exact_out` | `fa49652126cf4bb8` |
| `swap_exact_out2` | `2bd7f784893cf351` |
| `swap_with_price_impact` | `38ade6d0ade49ccd` |
| `swap_with_price_impact2` | `4a62c0d6b1334b33` |
| `update_base_fee_parameters` | `4ba8dfa110c3032f` |
| `update_dynamic_fee_parameters` | `5ca12ef6ffbd1616` |
| `update_fees_and_reward2` | `208eb89a6741b858` |
| `update_fees_and_rewards` | `9ae6fa0decd14bdf` |
| `update_position_operator` | `cab8678fb4bf74d9` |
| `update_reward_duration` | `8aaec4a9d5ebfe6b` |
| `update_reward_funder` | `d31c3020d7a02317` |
| `withdraw_ineligible_reward` | `94ce2ac3f7316708` |
| `withdraw_protocol_fee` | `9ec99ebd215da267` |
| `zap_protocol_fee` | `d59bbb2238b65bf0` |
## 7. Checklist d'events Anchor IDL à inventorier
| Event | Discriminator hex |
|---|---|
| `AddLiquidity` | `1f5e7d5ae3343dba` |
| `CancelLimitOrderEvt` | `83eac285090ebdd1` |
| `ClaimFee` | `4b7a9a308c4a7ba3` |
| `ClaimFee2` | `e8abf2613a4d232d` |
| `ClaimReward` | `947486cc16ab555f` |
| `ClaimReward2` | `1b8ff421502b6e92` |
| `CloseLimitOrderEvt` | `8e87084c5c3f7653` |
| `CompositionFee` | `80977b6a1166718e` |
| `DecreasePositionLength` | `3476eb55aca90f80` |
| `DynamicFeeParameterUpdate` | `5858b287c2925bf3` |
| `FeeParameterUpdate` | `304cf17590d7f22c` |
| `FundReward` | `f6e43a8291aa4fcc` |
| `GoToABin` | `3b8a4c448a83b043` |
| `IncreaseObservation` | `63f91179a69ccfd7` |
| `IncreasePositionLength` | `9def2acc1e38df2e` |
| `InitializeReward` | `d399583e953cb146` |
| `LbPairCreate` | `b94afc7d1bd7bc6f` |
| `PlaceLimitOrderEvt` | `2b4f1ba9f41ce13f` |
| `PositionClose` | `ffc4106b1cca3580` |
| `PositionCreate` | `908efc549d352579` |
| `Rebalancing` | `006d75b33d5bc7c8` |
| `RemoveLiquidity` | `74f461e8671f983a` |
| `SetPositionPermissionlessOperationBitsEvt` | `c3e593f51d7d30a8` |
| `Swap` | `516ce3becdd00ac4` |
| `Swap2Evt` | `2e7452d7941b544d` |
| `UpdatePositionLockReleasePoint` | `85d642e0400c07bf` |
| `UpdatePositionOperator` | `277330ccf62f4239` |
| `UpdateRewardDuration` | `dff5e099311da3ac` |
| `UpdateRewardFunder` | `e0b2ae4afca555b4` |
| `WithdrawIneligibleReward` | `e7bd419566d79af4` |
## 8. Matérialisation attendue
### Swaps
Cibles :
```text
swap
swap2
swap_exact_out
swap_exact_out2
swap_with_price_impact
swap_with_price_impact2
Swap
Swap2Evt
```
Décision :
- `k_sol_trade_events` + candles uniquement si montants exécutés, sens, pool, token X/Y et mints sont fiables ;
- les events Anchor swap ne doivent pas double-compter une instruction swap déjà matérialisée ;
- exact-out et price-impact ne doivent pas utiliser des bornes comme montants exécutés ;
- si le contexte n'est pas fiable : `skipTradeReason` + `skipCandleReason`.
### Liquidity / bins / positions
Cibles :
```text
add_liquidity*
remove_liquidity*
remove_all_liquidity
rebalance_liquidity
initialize_position*
close_position*
position create/close/update events
initialize_bin_array*
close_bin_array
```
Décision :
- `k_sol_liquidity_events` quand les montants token X/Y, pool, position et acteur sont fiables ;
- lifecycle pour création/fermeture position/bin/pair ;
- skip reason explicite pour position/bin sans montants exploitables.
### Pools / catalog
Cibles :
```text
initialize_lb_pair
initialize_lb_pair2
initialize_permission_lb_pair
initialize_customizable_permissionless_lb_pair
initialize_customizable_permissionless_lb_pair2
LbPairCreate
```
Décision : lifecycle/catalog/pool/pair si mints X/Y, pool, config/preset et comptes vault sont fiables.
### Fees
Cibles :
```text
claim_fee
claim_fee2
withdraw_protocol_fee
zap_protocol_fee
ClaimFee
ClaimFee2
CompositionFee
```
Décision :
- `k_sol_fee_events` + `k_sol_fee_event_amounts` obligatoires si montant/mint fiable ;
- utiliser parent scalaire + leg automatique pour mono-fee ;
- utiliser multi-leg sans agrégation parent si plusieurs mints/composants ;
- ne pas confondre composition fee inclus dans swap/liquidity avec claim fee matérialisable ;
- déclarer explicitement toute policy de recovery ; ne pas ajouter DLMM à l'allowlist générique sans preuve et tests.
### Rewards
Cibles :
```text
initialize_reward
fund_reward
claim_reward
claim_reward2
withdraw_ineligible_reward
ClaimReward
ClaimReward2
FundReward
InitializeReward
WithdrawIneligibleReward
```
Décision : `k_sol_reward_events` si montant/mint/reward index fiables ; decoded-only sinon.
### Admin/config/status/operator/token badge
Cibles :
```text
update_base_fee_parameters
update_dynamic_fee_parameters
update_fees_and_rewards
update_fees_and_reward2
set_pair_status
set_pair_status_permissionless
set_activation_point
set_pre_activation_duration
set_pre_activation_swap_address
set_permissionless_operation_bits
create_operator_account
close_operator_account
close_claim_fee_operator_account
initialize_token_badge
close_token_badge
initialize_preset_parameter
close_preset_parameter
close_preset_parameter2
```
Décision : `k_sol_pool_admin_events` si acteur/cible fiables ; decoded-only avec raison sinon.
### Limit orders / orderbook-like events
Cibles :
```text
place_limit_order
cancel_limit_order
close_limit_order_if_empty
PlaceLimitOrderEvt
CancelLimitOrderEvt
CloseLimitOrderEvt
```
Décision : `k_sol_orderbook_events` si sémantique fiable ; pas de trade/candle sans fill exact.
## 9. SQL de validation attendu
Créer/mettre à jour :
```text
validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql
```
Le fichier doit vérifier au minimum :
1. fallback upstream DLMM ;
2. instruction observations DLMM ;
3. coverage DLMM ;
4. decoded DLMM sans coverage ;
5. successful non-materialized sans skip reason ;
6. failed tx materialization ;
7. multi-target materialization ;
8. trade/candle sur non-swap ;
9. fee parent/legs ;
10. orphan fee legs ;
11. reward/fee separation ;
12. orderbook/limit-order sans double-count ;
13. watchlist globale.
## 10. Invariants de fermeture
`0.7.57 meteora_dlmm` ne peut être clôturé que si :
- les `76` instructions et `30` events Anchor IDL sont dans la coverage ou explicitement non observés avec tests synthétiques ;
- aucun fallback upstream DLMM ne reste pour les entrées couvertes localement ;
- aucun decoded DLMM local sans coverage ;
- aucune tx failed n'alimente une table métier ;
- aucun event multi-target incohérent ;
- aucune ligne successful non-materialized sans `skip*Reason` ou policy explicite ;
- aucun non-swap ne produit trade/candle ;
- aucun fee parent scalaire sans leg ;
- aucun leg fee orphelin ;
- aucun reward n'est classé fee par défaut ;
- aucun limit/order event ne produit une candle sans fill exact ;
- la watchlist globale ne contient plus de backlog dominant `meteora_dlmm`.
## 11. Contraintes de code à respecter
- Rust 2024 ;
- async-first ;
- tracing obligatoire ;
- pas de `?`, pas de `unwrap/expect` en production ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod` : utiliser `mod` + `pub use` ;
- imports seulement pour les traits ;
- `#![deny(unreachable_pub)]`, `#![warn(missing_docs)]` ;
- tests offline ;
- pas de macro DB/coverage ;
- après modification DB : re-exports `kb_lib/src/db.rs` et `kb_lib/src/lib.rs` ;
- après modification decoder : vérifier `kb_lib/src/dex.rs`, `kb_lib/src/lib.rs`, coverage et tests synthétiques.
## 12. Format de livraison attendu
Livrer des deltas successifs :
```text
khadhroony-bobobot-v0.7.57-meteora_dlmm-delta-pre.xxx.zip
```
Chaque réponse doit indiquer : fichiers modifiés, raisons, tests à lancer, SQL à exécuter, résultat attendu, et risques éventuels.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_58_demo4_program_surface_discovery.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.58`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md
```

View File

@@ -0,0 +1,447 @@
<!-- file: docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md -->
# Prompt — 0.7.58 Binaire de fusion de bases SQLite transactionnelles + validation anti-régression inter-DEX
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.57-pre.015..023 -> nettoyage PumpSwap / guard PumpFees après régression cross-surface
```
Décision de planification mise à jour :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Le binaire de fusion passe avant `demo4`, car il devient un outil de non-régression indispensable pour les futurs décodeurs/materializers.
## Objectif principal
Créer un outil binaire de fusion de bases SQLite transactionnelles permettant de construire une base consolidée de corpus, par exemple `final.db`, à partir :
```text
final.db existante
+ base dédiée pump_swap.db
+ base dédiée pump_fun.db
+ base dédiée pump_fees.db
+ base dédiée raydium_*.db
+ base dédiée meteora_*.db
```
Le binaire doit fusionner les transactions/instructions déjà backfillées sans RPC, sans redécoder et sans matérialiser pendant le merge.
Ensuite, la base consolidée doit être rejouable localement avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
But : détecter les régressions inter-DEX comme celle observée où un décodage `pump_fees` tronqué interrompait la matérialisation `pump_swap.buy_exact_quote_in` dans la même transaction.
## Règle de workflow future
Pour chaque nouveau DEX ou nouvelle surface :
1. Créer une base vide dédiée au DEX en cours.
2. Backfiller uniquement les signatures/pools nécessaires pour ce DEX.
3. Développer le decoder/materializer sur cette base dédiée.
4. Clore avec les SQL propres du DEX.
5. Fusionner la base dédiée dans `final.db` ou dans une copie `final.next.db`.
6. Rejouer `final.next.db` avec `forceDexDecode=yes`.
7. Lancer les validations globales anti-régression sur Pump/Raydium/Meteora et sur les surfaces closes.
8. Promouvoir `final.next.db` en `final.db` seulement si les gates sont propres.
Commande conceptuelle :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/pump_swap.db --input ./corpus/pump_fees.db --mode raw-corpus --dry-run
```
Puis, après validation dry-run :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/new_dex.db --mode raw-corpus --replace-output
```
## Emplacement recommandé
Créer un package outil séparé :
```text
kb_tools/
Cargo.toml
src/bin/kb_db_merge.rs
```
Ajouter `kb_tools` dans le workspace principal.
Alternative acceptable si la structure workspace rend cela plus simple :
```text
kb_lib/src/bin/kb_db_merge.rs
```
Mais privilégier `kb_tools` pour éviter de mélanger outil CLI et librairie métier.
## Contraintes de code
Respecter les contraintes projet :
- Rust 2024 ;
- async-first si accès DB async ;
- tracing obligatoire ;
- pas de `?` dans le code applicatif ;
- pas de `unwrap` / `expect` hors tests ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod`, utiliser `mod` + `pub use` ;
- imports directs seulement pour les traits ;
- tests offline ;
- types DB sous `kb_lib/src/db/entities/` et `kb_lib/src/db/dtos/`, pas sous `queries/` ;
- si des requêtes DB sont ajoutées/modifiées : mettre à jour les re-exports dans `kb_lib/src/db.rs` puis `kb_lib/src/lib.rs`.
## Modes CLI
Modes initiaux :
```text
raw-corpus
signatures-only
full-copy-safe
```
Le mode par défaut doit être :
```text
raw-corpus
```
### `raw-corpus`
Copier uniquement les données nécessaires à un replay local fiable :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
Ne pas copier les tables matérialisées par défaut :
```text
k_sol_dex_decoded_events
k_sol_trade_events
k_sol_liquidity_events
k_sol_pool_lifecycle_events
k_sol_pair_candles
k_sol_fee_events
k_sol_reward_events
k_sol_pool_admin_events
k_sol_orderbook_events
k_sol_token_account_events
k_sol_instruction_observations
k_sol_dex_event_coverage_entries
```
Raison : ces tables dépendent de la version de decoder/materializer et doivent être reconstruites par replay local.
### `signatures-only`
Créer une table de staging de signatures/slots/source, sans copier les transactions complètes. Ce mode est utile pour audit ou pour préparer des backfills contrôlés.
### `full-copy-safe`
Mode optionnel, non prioritaire.
Copier aussi des lignes décodées/matérialisées uniquement si :
- le schema version est compatible ;
- la version logique de decoder est identique ;
- toutes les foreign keys peuvent être remappées ;
- le mode est explicitement demandé.
Ne jamais en faire le mode par défaut.
## Options CLI minimales
```text
--output <path>
--input <path> répétable
--mode <raw-corpus|signatures-only|full-copy-safe>
--dry-run
--replace-output
--source-label <label> répétable ou inféré depuis le fichier
--limit <n> optionnel pour tests
--batch-size <n> optionnel
```
Options utiles pour `final.db` :
```text
--allow-existing-output
--merge-into-copy-of <path>
--conflict-policy <record|prefer-complete|fail>
```
Par défaut : ne pas écraser loutput existant sans `--replace-output` ou `--merge-into-copy-of`.
## Politique de déduplication
Identité canonique :
```text
signature
```
Règles :
- Une signature déjà présente dans loutput ne doit pas être dupliquée.
- Si `slot`, `err_json`, `transaction_json`, `meta_json` ou les instructions diffèrent, enregistrer un conflit.
- Ne pas écraser silencieusement.
- Si une version est plus complète, ne la préférer que si la politique `prefer-complete` est demandée et que le conflit est journalisé.
- Garder une provenance complète source -> output.
Tables suggérées :
```text
k_sol_db_merge_sources
k_sol_db_merge_transactions
k_sol_db_merge_conflicts
```
Champs source suggérés :
```text
source_id
source_path
source_label
source_schema_version
source_created_at
input_transaction_count
copied_transaction_count
skipped_duplicate_count
conflict_count
```
Champs transaction de merge suggérés :
```text
signature
slot
source_id
source_transaction_id
output_transaction_id
copy_status
conflict_status
copied_at
```
## Compatibilité de schéma
Le binaire doit inspecter chaque input via :
```sql
SELECT name, sql FROM sqlite_master WHERE type = 'table';
PRAGMA table_info(k_sol_chain_transactions);
PRAGMA table_info(k_sol_chain_instructions);
```
Pour `raw-corpus`, refuser proprement une DB qui ne contient pas :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
ou les colonnes nécessaires au replay local.
Le message derreur doit indiquer :
```text
source DB
missing table
missing column
mode demandé
```
## Stratégie de copie
Algorithme recommandé :
1. Créer ou initialiser loutput avec le schéma courant `kb_lib`.
2. Enregistrer chaque input dans `k_sol_db_merge_sources`.
3. Lire les transactions source par slot/signature.
4. Pour chaque transaction :
- si signature absente de loutput : insérer transaction + instructions enfants ;
- si signature présente : comparer les champs canoniques ;
- si identique : enregistrer duplicate skipped ;
- si différent : enregistrer conflit.
5. Remapper `source_transaction_id -> output_transaction_id` pour les instructions.
6. Commit par batch.
7. Imprimer un résumé final.
## Validation anti-régression intégrée à 0.7.58
Ajouter une documentation et, si possible, un script SQL :
```text
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
```
Checks merge minimaux :
```sql
-- duplicate signatures in output should be empty
SELECT signature, COUNT(*)
FROM k_sol_chain_transactions
GROUP BY signature
HAVING COUNT(*) > 1;
-- orphan instructions should be empty
SELECT ins.id
FROM k_sol_chain_instructions ins
LEFT JOIN k_sol_chain_transactions tx ON tx.id = ins.transaction_id
WHERE tx.id IS NULL;
-- conflicts summary
SELECT *
FROM k_sol_db_merge_conflicts
ORDER BY id DESC
LIMIT 100;
```
Checks anti-régression DEX après replay de `final.next.db` :
```sql
-- successful decoded events without any materialized target
SELECT
de.protocol_name,
de.event_kind,
json_extract(de.payload_json, '$.eventActionability') AS event_actionability,
json_extract(de.payload_json, '$.skipTradeReason') AS skip_trade_reason,
COUNT(*) AS missing_count,
MIN(tx.signature) AS sample_signature
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events lie ON lie.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events ple ON ple.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fee ON fee.decoded_event_id = de.id
LEFT JOIN k_sol_reward_events rew ON rew.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events adm ON adm.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events obe ON obe.decoded_event_id = de.id
LEFT JOIN k_sol_token_account_events tae ON tae.decoded_event_id = de.id
WHERE (tx.err_json IS NULL OR tx.err_json = '' OR tx.err_json = 'null')
AND te.id IS NULL
AND lie.id IS NULL
AND ple.id IS NULL
AND fee.id IS NULL
AND rew.id IS NULL
AND adm.id IS NULL
AND obe.id IS NULL
AND tae.id IS NULL
GROUP BY de.protocol_name, de.event_kind, event_actionability, skip_trade_reason
ORDER BY missing_count DESC, de.protocol_name, de.event_kind;
```
Cette requête ne doit pas forcément être vide, mais tout résidu doit être explicitement classé : failed-only, decoded-only justifié, non_actionable prouvé, ou nouveau bug.
## Vérification/correction Pump/Raydium incluse dans 0.7.58
La tranche `0.7.58` doit inclure un passage de non-régression sur les surfaces déjà closes, au minimum :
```text
pump_swap
pump_fun
pump_fees
raydium_cpmm
raydium_clmm
raydium_amm_v4
raydium_stable_swap
raydium_launchpad
meteora_dbc
meteora_dlmm
```
Objectif : détecter et corriger les régressions cross-surface, par exemple :
```text
un decoder A ne doit pas faire échouer la matérialisation dun decoder B dans la même transaction.
```
Règle de decoder :
- un payload tronqué/incompatible sur une surface secondaire ne doit pas aborter toute la transaction si lentrée peut être ignorée proprement ;
- préférer `Ok(None)` + observation/debug contrôlé pour les payloads tronqués connus ;
- conserver `Err` pour corruption critique, violation de schéma interne ou incohérence qui rend la transaction non fiable ;
- ajouter des tests synthétiques pour chaque guard.
## Tests attendus
Ajouter tests unitaires/offline pour :
1. merge dune DB vers output vide ;
2. merge de deux DBs disjointes ;
3. duplicate signature identique ;
4. duplicate signature conflictuelle ;
5. conflit instruction enfant ;
6. dry-run sans écriture ;
7. output existant refusé sans option explicite ;
8. source provenance enregistrée ;
9. replay final DB possible après merge raw-corpus ;
10. non-régression PumpSwap/PumpFees : payload PumpFees tronqué nempêche pas PumpSwap de matérialiser un trade exact.
## Livrables attendus
```text
kb_tools/Cargo.toml
kb_tools/src/bin/kb_db_merge.rs
kb_lib/src/db/entities/db_merge_source.rs
kb_lib/src/db/entities/db_merge_transaction.rs
kb_lib/src/db/entities/db_merge_conflict.rs
kb_lib/src/db/dtos/db_merge_*.rs
kb_lib/src/db/queries/db_merge_*.rs
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
docs/reports/SQLITE_DB_TRANSACTION_MERGER_0_7_58.md
```
Mettre à jour :
```text
Cargo.toml
kb_lib/src/db.rs
kb_lib/src/lib.rs
README.md
ROADMAP.md
CHANGELOG.md
```
## Critères de clôture 0.7.58
- `cargo test -p kb_lib` OK ;
- `cargo test -p kb_tools` OK si package séparé ;
- clippy `-D warnings` OK ;
- dry-run merge lisible ;
- merge réel de plusieurs bases OK ;
- pas de duplicate signatures ;
- pas dinstructions orphelines ;
- conflits journalisés ;
- replay local de `final.next.db` OK ;
- validation anti-régression Pump/Raydium/Meteora exécutée et documentée.
## Note finale
Le merger ne remplace pas `demo3` ni `demo4`.
Il sert à construire un corpus consolidé de non-régression à partir des bases dédiées. `demo4`, déplacé en `0.7.59`, servira ensuite à explorer les surfaces encore inconnues dans cette base consolidée.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_58_demo4_program_surface_discovery.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.58`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md
```

View File

@@ -0,0 +1,447 @@
<!-- file: docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md -->
# Prompt — 0.7.58 Binaire de fusion de bases SQLite transactionnelles + validation anti-régression inter-DEX
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.57-pre.015..023 -> nettoyage PumpSwap / guard PumpFees après régression cross-surface
```
Décision de planification mise à jour :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Le binaire de fusion passe avant `demo4`, car il devient un outil de non-régression indispensable pour les futurs décodeurs/materializers.
## Objectif principal
Créer un outil binaire de fusion de bases SQLite transactionnelles permettant de construire une base consolidée de corpus, par exemple `final.db`, à partir :
```text
final.db existante
+ base dédiée pump_swap.db
+ base dédiée pump_fun.db
+ base dédiée pump_fees.db
+ base dédiée raydium_*.db
+ base dédiée meteora_*.db
```
Le binaire doit fusionner les transactions/instructions déjà backfillées sans RPC, sans redécoder et sans matérialiser pendant le merge.
Ensuite, la base consolidée doit être rejouable localement avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
But : détecter les régressions inter-DEX comme celle observée où un décodage `pump_fees` tronqué interrompait la matérialisation `pump_swap.buy_exact_quote_in` dans la même transaction.
## Règle de workflow future
Pour chaque nouveau DEX ou nouvelle surface :
1. Créer une base vide dédiée au DEX en cours.
2. Backfiller uniquement les signatures/pools nécessaires pour ce DEX.
3. Développer le decoder/materializer sur cette base dédiée.
4. Clore avec les SQL propres du DEX.
5. Fusionner la base dédiée dans `final.db` ou dans une copie `final.next.db`.
6. Rejouer `final.next.db` avec `forceDexDecode=yes`.
7. Lancer les validations globales anti-régression sur Pump/Raydium/Meteora et sur les surfaces closes.
8. Promouvoir `final.next.db` en `final.db` seulement si les gates sont propres.
Commande conceptuelle :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/pump_swap.db --input ./corpus/pump_fees.db --mode raw-corpus --dry-run
```
Puis, après validation dry-run :
```bash
cargo run -p kb_tools --bin kb_db_merge -- --output ./final.next.db --input ./final.db --input ./corpus/new_dex.db --mode raw-corpus --replace-output
```
## Emplacement recommandé
Créer un package outil séparé :
```text
kb_tools/
Cargo.toml
src/bin/kb_db_merge.rs
```
Ajouter `kb_tools` dans le workspace principal.
Alternative acceptable si la structure workspace rend cela plus simple :
```text
kb_lib/src/bin/kb_db_merge.rs
```
Mais privilégier `kb_tools` pour éviter de mélanger outil CLI et librairie métier.
## Contraintes de code
Respecter les contraintes projet :
- Rust 2024 ;
- async-first si accès DB async ;
- tracing obligatoire ;
- pas de `?` dans le code applicatif ;
- pas de `unwrap` / `expect` hors tests ;
- pas de `anyhow` / `thiserror` ;
- pas de `mod.rs` ;
- pas de `pub mod`, utiliser `mod` + `pub use` ;
- imports directs seulement pour les traits ;
- tests offline ;
- types DB sous `kb_lib/src/db/entities/` et `kb_lib/src/db/dtos/`, pas sous `queries/` ;
- si des requêtes DB sont ajoutées/modifiées : mettre à jour les re-exports dans `kb_lib/src/db.rs` puis `kb_lib/src/lib.rs`.
## Modes CLI
Modes initiaux :
```text
raw-corpus
signatures-only
full-copy-safe
```
Le mode par défaut doit être :
```text
raw-corpus
```
### `raw-corpus`
Copier uniquement les données nécessaires à un replay local fiable :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
Ne pas copier les tables matérialisées par défaut :
```text
k_sol_dex_decoded_events
k_sol_trade_events
k_sol_liquidity_events
k_sol_pool_lifecycle_events
k_sol_pair_candles
k_sol_fee_events
k_sol_reward_events
k_sol_pool_admin_events
k_sol_orderbook_events
k_sol_token_account_events
k_sol_instruction_observations
k_sol_dex_event_coverage_entries
```
Raison : ces tables dépendent de la version de decoder/materializer et doivent être reconstruites par replay local.
### `signatures-only`
Créer une table de staging de signatures/slots/source, sans copier les transactions complètes. Ce mode est utile pour audit ou pour préparer des backfills contrôlés.
### `full-copy-safe`
Mode optionnel, non prioritaire.
Copier aussi des lignes décodées/matérialisées uniquement si :
- le schema version est compatible ;
- la version logique de decoder est identique ;
- toutes les foreign keys peuvent être remappées ;
- le mode est explicitement demandé.
Ne jamais en faire le mode par défaut.
## Options CLI minimales
```text
--output <path>
--input <path> répétable
--mode <raw-corpus|signatures-only|full-copy-safe>
--dry-run
--replace-output
--source-label <label> répétable ou inféré depuis le fichier
--limit <n> optionnel pour tests
--batch-size <n> optionnel
```
Options utiles pour `final.db` :
```text
--allow-existing-output
--merge-into-copy-of <path>
--conflict-policy <record|prefer-complete|fail>
```
Par défaut : ne pas écraser loutput existant sans `--replace-output` ou `--merge-into-copy-of`.
## Politique de déduplication
Identité canonique :
```text
signature
```
Règles :
- Une signature déjà présente dans loutput ne doit pas être dupliquée.
- Si `slot`, `err_json`, `transaction_json`, `meta_json` ou les instructions diffèrent, enregistrer un conflit.
- Ne pas écraser silencieusement.
- Si une version est plus complète, ne la préférer que si la politique `prefer-complete` est demandée et que le conflit est journalisé.
- Garder une provenance complète source -> output.
Tables suggérées :
```text
k_sol_db_merge_sources
k_sol_db_merge_transactions
k_sol_db_merge_conflicts
```
Champs source suggérés :
```text
source_id
source_path
source_label
source_schema_version
source_created_at
input_transaction_count
copied_transaction_count
skipped_duplicate_count
conflict_count
```
Champs transaction de merge suggérés :
```text
signature
slot
source_id
source_transaction_id
output_transaction_id
copy_status
conflict_status
copied_at
```
## Compatibilité de schéma
Le binaire doit inspecter chaque input via :
```sql
SELECT name, sql FROM sqlite_master WHERE type = 'table';
PRAGMA table_info(k_sol_chain_transactions);
PRAGMA table_info(k_sol_chain_instructions);
```
Pour `raw-corpus`, refuser proprement une DB qui ne contient pas :
```text
k_sol_chain_transactions
k_sol_chain_instructions
```
ou les colonnes nécessaires au replay local.
Le message derreur doit indiquer :
```text
source DB
missing table
missing column
mode demandé
```
## Stratégie de copie
Algorithme recommandé :
1. Créer ou initialiser loutput avec le schéma courant `kb_lib`.
2. Enregistrer chaque input dans `k_sol_db_merge_sources`.
3. Lire les transactions source par slot/signature.
4. Pour chaque transaction :
- si signature absente de loutput : insérer transaction + instructions enfants ;
- si signature présente : comparer les champs canoniques ;
- si identique : enregistrer duplicate skipped ;
- si différent : enregistrer conflit.
5. Remapper `source_transaction_id -> output_transaction_id` pour les instructions.
6. Commit par batch.
7. Imprimer un résumé final.
## Validation anti-régression intégrée à 0.7.58
Ajouter une documentation et, si possible, un script SQL :
```text
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
```
Checks merge minimaux :
```sql
-- duplicate signatures in output should be empty
SELECT signature, COUNT(*)
FROM k_sol_chain_transactions
GROUP BY signature
HAVING COUNT(*) > 1;
-- orphan instructions should be empty
SELECT ins.id
FROM k_sol_chain_instructions ins
LEFT JOIN k_sol_chain_transactions tx ON tx.id = ins.transaction_id
WHERE tx.id IS NULL;
-- conflicts summary
SELECT *
FROM k_sol_db_merge_conflicts
ORDER BY id DESC
LIMIT 100;
```
Checks anti-régression DEX après replay de `final.next.db` :
```sql
-- successful decoded events without any materialized target
SELECT
de.protocol_name,
de.event_kind,
json_extract(de.payload_json, '$.eventActionability') AS event_actionability,
json_extract(de.payload_json, '$.skipTradeReason') AS skip_trade_reason,
COUNT(*) AS missing_count,
MIN(tx.signature) AS sample_signature
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events lie ON lie.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events ple ON ple.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fee ON fee.decoded_event_id = de.id
LEFT JOIN k_sol_reward_events rew ON rew.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events adm ON adm.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events obe ON obe.decoded_event_id = de.id
LEFT JOIN k_sol_token_account_events tae ON tae.decoded_event_id = de.id
WHERE (tx.err_json IS NULL OR tx.err_json = '' OR tx.err_json = 'null')
AND te.id IS NULL
AND lie.id IS NULL
AND ple.id IS NULL
AND fee.id IS NULL
AND rew.id IS NULL
AND adm.id IS NULL
AND obe.id IS NULL
AND tae.id IS NULL
GROUP BY de.protocol_name, de.event_kind, event_actionability, skip_trade_reason
ORDER BY missing_count DESC, de.protocol_name, de.event_kind;
```
Cette requête ne doit pas forcément être vide, mais tout résidu doit être explicitement classé : failed-only, decoded-only justifié, non_actionable prouvé, ou nouveau bug.
## Vérification/correction Pump/Raydium incluse dans 0.7.58
La tranche `0.7.58` doit inclure un passage de non-régression sur les surfaces déjà closes, au minimum :
```text
pump_swap
pump_fun
pump_fees
raydium_cpmm
raydium_clmm
raydium_amm_v4
raydium_stable_swap
raydium_launchpad
meteora_dbc
meteora_dlmm
```
Objectif : détecter et corriger les régressions cross-surface, par exemple :
```text
un decoder A ne doit pas faire échouer la matérialisation dun decoder B dans la même transaction.
```
Règle de decoder :
- un payload tronqué/incompatible sur une surface secondaire ne doit pas aborter toute la transaction si lentrée peut être ignorée proprement ;
- préférer `Ok(None)` + observation/debug contrôlé pour les payloads tronqués connus ;
- conserver `Err` pour corruption critique, violation de schéma interne ou incohérence qui rend la transaction non fiable ;
- ajouter des tests synthétiques pour chaque guard.
## Tests attendus
Ajouter tests unitaires/offline pour :
1. merge dune DB vers output vide ;
2. merge de deux DBs disjointes ;
3. duplicate signature identique ;
4. duplicate signature conflictuelle ;
5. conflit instruction enfant ;
6. dry-run sans écriture ;
7. output existant refusé sans option explicite ;
8. source provenance enregistrée ;
9. replay final DB possible après merge raw-corpus ;
10. non-régression PumpSwap/PumpFees : payload PumpFees tronqué nempêche pas PumpSwap de matérialiser un trade exact.
## Livrables attendus
```text
kb_tools/Cargo.toml
kb_tools/src/bin/kb_db_merge.rs
kb_lib/src/db/entities/db_merge_source.rs
kb_lib/src/db/entities/db_merge_transaction.rs
kb_lib/src/db/entities/db_merge_conflict.rs
kb_lib/src/db/dtos/db_merge_*.rs
kb_lib/src/db/queries/db_merge_*.rs
validation_sql/SQL_VALIDATION_DB_MERGE_0_7_58.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_0_7_58.sql
docs/reports/SQLITE_DB_TRANSACTION_MERGER_0_7_58.md
```
Mettre à jour :
```text
Cargo.toml
kb_lib/src/db.rs
kb_lib/src/lib.rs
README.md
ROADMAP.md
CHANGELOG.md
```
## Critères de clôture 0.7.58
- `cargo test -p kb_lib` OK ;
- `cargo test -p kb_tools` OK si package séparé ;
- clippy `-D warnings` OK ;
- dry-run merge lisible ;
- merge réel de plusieurs bases OK ;
- pas de duplicate signatures ;
- pas dinstructions orphelines ;
- conflits journalisés ;
- replay local de `final.next.db` OK ;
- validation anti-régression Pump/Raydium/Meteora exécutée et documentée.
## Note finale
Le merger ne remplace pas `demo3` ni `demo4`.
Il sert à construire un corpus consolidé de non-régression à partir des bases dédiées. `demo4`, déplacé en `0.7.59`, servira ensuite à explorer les surfaces encore inconnues dans cette base consolidée.

View File

@@ -0,0 +1,330 @@
<!-- file: docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md -->
# Prompt — 0.7.59 Demo4 Program Surface Discovery
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
```
Décision de planification : `demo4_program_surface_discovery` est déplacé de `0.7.58` vers `0.7.59` afin de permettre dabord la création dune base consolidée `final.db`.
Cette base consolidée doit permettre à Demo4 dexplorer :
```text
program_id inconnus
program_id connus avec discriminants non mappés
Anchor logs Instruction non mappés
Program data events non mappés
upstream fallbacks
layouts répétitifs daccounts/data
success/failed split
```
## Objectif principal
Ajouter une fenêtre `Demo4` dans `kb_demo_app` et les requêtes `kb_lib` associées pour afficher les surfaces non prises en compte sans les promouvoir automatiquement.
Demo4 est un outil dobservation, de tri et de préparation de futures tranches de decoder. Il ne doit pas créer de trade, candle, pool, pair, fee, reward, admin ou lifecycle métier.
## Règles strictes
Demo4 doit être read-only par défaut.
Interdictions :
- ne pas matérialiser automatiquement ;
- ne pas ajouter automatiquement de coverage comme supportée ;
- ne pas marquer automatiquement un `program_id` comme connu ;
- ne pas générer de decoder métier ;
- ne pas promouvoir un upstream fallback vers un decoder local sans intervention humaine ;
- ne pas masquer les failed transactions ;
- ne pas supprimer les observations existantes.
Actions autorisées :
- lister ;
- grouper ;
- scorer ;
- exporter Markdown/CSV/JSON ;
- marquer manuellement un candidat comme `reviewed`, `ignored`, `accepted_for_future_decoder`, si table de statut ajoutée ;
- ouvrir une signature dans Demo Pipeline 2 ou Demo3.
## Sources de données prioritaires
Demo4 doit exploiter la base consolidée construite par `0.7.58`, par exemple :
```text
final.db
final.next.db
```
Cette base est issue de merges raw-corpus de bases dédiées :
```text
pump_swap.db
pump_fun.db
pump_fees.db
raydium_*.db
meteora_*.db
```
Le bénéfice attendu : détecter les surfaces inconnues et les régressions qui napparaissent pas dans une base DEX isolée.
## Surfaces à afficher
### 1. Program IDs non routés
Afficher les `program_id` présents dans `k_sol_chain_instructions` qui ne correspondent pas à une surface supportée ou connue.
Colonnes utiles :
```text
program_id
instruction_count
tx_count
success_count
failed_count
first_slot
last_slot
sample_signature
sample_data_prefix
sample_account_count
```
### 2. Discriminators non mappés sur program id connu
Pour un `program_id` déjà supporté, afficher les discriminants inconnus ou encore en `instruction_audit`.
Colonnes utiles :
```text
protocol_guess
program_id
discriminator_hex
data_prefix
instruction_count
tx_count
success_count
failed_count
sample_signature
known_anchor_log_name si disponible
upstream_match_status si disponible
```
### 3. Anchor logs `Instruction: ...`
Extraire depuis `meta_json.logMessages` :
```text
Program log: Instruction: <Name>
```
Normaliser le nom :
```text
InitializePresetParameterV2 -> initialize_preset_parameter_v2
```
Calculer si possible :
```text
sha256("global:<snake_case_name>")[0..8]
```
Comparer au discriminator observé.
### 4. Program data / Anchor events non mappés
Lister les `Program data:` ou events Anchor observés mais non classés localement.
Colonnes utiles :
```text
program_id
anchor_event_discriminator_hex
payload_size
tx_count
success_count
failed_count
sample_signature
possible_event_name
upstream_match_status
```
### 5. Upstream fallbacks
Afficher les événements qui viennent encore de :
```text
upstream_git.instruction_match
upstream_git.event_match
instruction_audit
```
Demo4 doit aider à décider si lentrée doit devenir :
```text
local decoder
coverage 0/0 conservée
decoded-only justifié
materialized admin/lifecycle/fee/reward/liquidity/orderbook
ignored
```
## UI attendue
Fichiers probables :
```text
kb_demo_app/src/demo4.html
kb_demo_app/src/demo4.ts
kb_demo_app/src/main.ts
kb_demo_app/src/shared/api.ts
kb_demo_app/src/shared/types.ts
```
Ajouter une fenêtre Tauri si nécessaire dans :
```text
kb_demo_app/src-tauri/src/main.rs
kb_demo_app/tauri.conf.json
```
Organisation UI suggérée :
```text
Filters:
- program_id
- protocol_guess
- success/failed/all
- minimum tx_count
- known/unknown program
- audit/upstream/unknown discriminator
- date/slot range si disponible
Tabs:
1. Unknown programs
2. Known program unknown discriminators
3. Anchor instruction logs
4. Program data events
5. Upstream fallbacks
6. Regression suspects
```
## API / services kb_lib suggérés
Créer des DTOs sous :
```text
kb_lib/src/db/dtos/program_surface_candidate_summary.rs
kb_lib/src/db/dtos/program_surface_candidate_sample.rs
```
Créer des requêtes sous :
```text
kb_lib/src/db/queries/program_surface_discovery.rs
```
Créer éventuellement une façade :
```text
kb_lib/src/program_surface_discovery.rs
```
Rappel : si des requêtes DB sont ajoutées, mettre à jour les re-exports dans :
```text
kb_lib/src/db.rs
kb_lib/src/lib.rs
```
## Table de statut optionnelle
Si utile, ajouter :
```text
k_sol_program_surface_candidates
```
Statuts possibles :
```text
new
reviewed
accepted_for_future_decoder
ignored
promoted_manually
rejected
```
Ne jamais passer automatiquement à `promoted_manually`.
## Intégration avec 0.7.58
Demo4 doit intégrer explicitement la notion de source DB/merge si les tables `k_sol_db_merge_*` existent.
Exemples daffichages utiles :
```text
candidate observed in sources: pump_swap.db, pump_fees.db
candidate observed only after final.db merge
candidate correlated with replay decode failure
candidate appears in transaction with multiple DEX protocols
```
Objectif : rendre visibles les régressions cross-surface comme le cas PumpSwap/PumpFees.
## SQL de validation Demo4
Ajouter :
```text
validation_sql/SQL_VALIDATION_DEMO4_PROGRAM_SURFACE_DISCOVERY_0_7_59.sql
```
Checks :
```sql
-- Demo4 queries should not create decoded/materialized rows
SELECT COUNT(*) FROM k_sol_dex_decoded_events;
SELECT COUNT(*) FROM k_sol_trade_events;
-- candidate status table should not auto-promote anything
SELECT status, COUNT(*)
FROM k_sol_program_surface_candidates
GROUP BY status;
```
Adapter selon schéma réel.
## Tests attendus
- requêtes unknown program sur fixture minimale ;
- discriminants inconnus sur program connu ;
- extraction Anchor `Instruction: Name` ;
- hash Anchor discriminator ;
- split success/failed ;
- no write en mode read-only ;
- export Markdown/CSV stable ;
- table statut manuelle si implémentée.
## Critères de clôture 0.7.59
- `cargo test -p kb_lib` OK ;
- `cargo test` UI/Tauri si existant OK ;
- clippy `-D warnings` OK ;
- Demo4 affiche les surfaces inconnues depuis `final.db` ;
- aucun auto-decode métier ;
- aucune auto-materialization ;
- export exploitable pour préparer `0.7.60 meteora_damm_v1` ou une tranche future ;
- README/ROADMAP/CHANGELOG mis à jour.
## Note finale
Demo4 ne remplace pas les prompts DEX. Il prépare les prochaines tranches en rendant les surfaces observées lisibles, priorisées et reproductibles.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_59_sqlite_db_transaction_merger_binary.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.59`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md
```

View File

@@ -0,0 +1,330 @@
<!-- file: docs/prompts/PROMPT_0_7_59_demo4_program_surface_discovery.md -->
# Prompt — 0.7.59 Demo4 Program Surface Discovery
## Contexte
Nous reprenons le workspace Rust `khadhroony-bobobot` après :
```text
0.7.57 -> meteora_dlmm clos
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
```
Décision de planification : `demo4_program_surface_discovery` est déplacé de `0.7.58` vers `0.7.59` afin de permettre dabord la création dune base consolidée `final.db`.
Cette base consolidée doit permettre à Demo4 dexplorer :
```text
program_id inconnus
program_id connus avec discriminants non mappés
Anchor logs Instruction non mappés
Program data events non mappés
upstream fallbacks
layouts répétitifs daccounts/data
success/failed split
```
## Objectif principal
Ajouter une fenêtre `Demo4` dans `kb_demo_app` et les requêtes `kb_lib` associées pour afficher les surfaces non prises en compte sans les promouvoir automatiquement.
Demo4 est un outil dobservation, de tri et de préparation de futures tranches de decoder. Il ne doit pas créer de trade, candle, pool, pair, fee, reward, admin ou lifecycle métier.
## Règles strictes
Demo4 doit être read-only par défaut.
Interdictions :
- ne pas matérialiser automatiquement ;
- ne pas ajouter automatiquement de coverage comme supportée ;
- ne pas marquer automatiquement un `program_id` comme connu ;
- ne pas générer de decoder métier ;
- ne pas promouvoir un upstream fallback vers un decoder local sans intervention humaine ;
- ne pas masquer les failed transactions ;
- ne pas supprimer les observations existantes.
Actions autorisées :
- lister ;
- grouper ;
- scorer ;
- exporter Markdown/CSV/JSON ;
- marquer manuellement un candidat comme `reviewed`, `ignored`, `accepted_for_future_decoder`, si table de statut ajoutée ;
- ouvrir une signature dans Demo Pipeline 2 ou Demo3.
## Sources de données prioritaires
Demo4 doit exploiter la base consolidée construite par `0.7.58`, par exemple :
```text
final.db
final.next.db
```
Cette base est issue de merges raw-corpus de bases dédiées :
```text
pump_swap.db
pump_fun.db
pump_fees.db
raydium_*.db
meteora_*.db
```
Le bénéfice attendu : détecter les surfaces inconnues et les régressions qui napparaissent pas dans une base DEX isolée.
## Surfaces à afficher
### 1. Program IDs non routés
Afficher les `program_id` présents dans `k_sol_chain_instructions` qui ne correspondent pas à une surface supportée ou connue.
Colonnes utiles :
```text
program_id
instruction_count
tx_count
success_count
failed_count
first_slot
last_slot
sample_signature
sample_data_prefix
sample_account_count
```
### 2. Discriminators non mappés sur program id connu
Pour un `program_id` déjà supporté, afficher les discriminants inconnus ou encore en `instruction_audit`.
Colonnes utiles :
```text
protocol_guess
program_id
discriminator_hex
data_prefix
instruction_count
tx_count
success_count
failed_count
sample_signature
known_anchor_log_name si disponible
upstream_match_status si disponible
```
### 3. Anchor logs `Instruction: ...`
Extraire depuis `meta_json.logMessages` :
```text
Program log: Instruction: <Name>
```
Normaliser le nom :
```text
InitializePresetParameterV2 -> initialize_preset_parameter_v2
```
Calculer si possible :
```text
sha256("global:<snake_case_name>")[0..8]
```
Comparer au discriminator observé.
### 4. Program data / Anchor events non mappés
Lister les `Program data:` ou events Anchor observés mais non classés localement.
Colonnes utiles :
```text
program_id
anchor_event_discriminator_hex
payload_size
tx_count
success_count
failed_count
sample_signature
possible_event_name
upstream_match_status
```
### 5. Upstream fallbacks
Afficher les événements qui viennent encore de :
```text
upstream_git.instruction_match
upstream_git.event_match
instruction_audit
```
Demo4 doit aider à décider si lentrée doit devenir :
```text
local decoder
coverage 0/0 conservée
decoded-only justifié
materialized admin/lifecycle/fee/reward/liquidity/orderbook
ignored
```
## UI attendue
Fichiers probables :
```text
kb_demo_app/src/demo4.html
kb_demo_app/src/demo4.ts
kb_demo_app/src/main.ts
kb_demo_app/src/shared/api.ts
kb_demo_app/src/shared/types.ts
```
Ajouter une fenêtre Tauri si nécessaire dans :
```text
kb_demo_app/src-tauri/src/main.rs
kb_demo_app/tauri.conf.json
```
Organisation UI suggérée :
```text
Filters:
- program_id
- protocol_guess
- success/failed/all
- minimum tx_count
- known/unknown program
- audit/upstream/unknown discriminator
- date/slot range si disponible
Tabs:
1. Unknown programs
2. Known program unknown discriminators
3. Anchor instruction logs
4. Program data events
5. Upstream fallbacks
6. Regression suspects
```
## API / services kb_lib suggérés
Créer des DTOs sous :
```text
kb_lib/src/db/dtos/program_surface_candidate_summary.rs
kb_lib/src/db/dtos/program_surface_candidate_sample.rs
```
Créer des requêtes sous :
```text
kb_lib/src/db/queries/program_surface_discovery.rs
```
Créer éventuellement une façade :
```text
kb_lib/src/program_surface_discovery.rs
```
Rappel : si des requêtes DB sont ajoutées, mettre à jour les re-exports dans :
```text
kb_lib/src/db.rs
kb_lib/src/lib.rs
```
## Table de statut optionnelle
Si utile, ajouter :
```text
k_sol_program_surface_candidates
```
Statuts possibles :
```text
new
reviewed
accepted_for_future_decoder
ignored
promoted_manually
rejected
```
Ne jamais passer automatiquement à `promoted_manually`.
## Intégration avec 0.7.58
Demo4 doit intégrer explicitement la notion de source DB/merge si les tables `k_sol_db_merge_*` existent.
Exemples daffichages utiles :
```text
candidate observed in sources: pump_swap.db, pump_fees.db
candidate observed only after final.db merge
candidate correlated with replay decode failure
candidate appears in transaction with multiple DEX protocols
```
Objectif : rendre visibles les régressions cross-surface comme le cas PumpSwap/PumpFees.
## SQL de validation Demo4
Ajouter :
```text
validation_sql/SQL_VALIDATION_DEMO4_PROGRAM_SURFACE_DISCOVERY_0_7_59.sql
```
Checks :
```sql
-- Demo4 queries should not create decoded/materialized rows
SELECT COUNT(*) FROM k_sol_dex_decoded_events;
SELECT COUNT(*) FROM k_sol_trade_events;
-- candidate status table should not auto-promote anything
SELECT status, COUNT(*)
FROM k_sol_program_surface_candidates
GROUP BY status;
```
Adapter selon schéma réel.
## Tests attendus
- requêtes unknown program sur fixture minimale ;
- discriminants inconnus sur program connu ;
- extraction Anchor `Instruction: Name` ;
- hash Anchor discriminator ;
- split success/failed ;
- no write en mode read-only ;
- export Markdown/CSV stable ;
- table statut manuelle si implémentée.
## Critères de clôture 0.7.59
- `cargo test -p kb_lib` OK ;
- `cargo test` UI/Tauri si existant OK ;
- clippy `-D warnings` OK ;
- Demo4 affiche les surfaces inconnues depuis `final.db` ;
- aucun auto-decode métier ;
- aucune auto-materialization ;
- export exploitable pour préparer `0.7.60 meteora_damm_v1` ou une tranche future ;
- README/ROADMAP/CHANGELOG mis à jour.
## Note finale
Demo4 ne remplace pas les prompts DEX. Il prépare les prochaines tranches en rendant les surfaces observées lisibles, priorisées et reproductibles.

View File

@@ -0,0 +1,18 @@
<!-- file: docs/prompts/PROMPT_0_7_59_sqlite_db_transaction_merger_binary.md -->
# OBSOLETE — Prompt déplacé
Ce prompt n'est plus la cible `0.7.59`.
Nouvel ordre validé :
```text
0.7.58 -> sqlite_db_transaction_merger
0.7.59 -> demo4_program_surface_discovery
```
Utiliser :
```text
docs/prompts/PROMPT_0_7_58_sqlite_db_transaction_merger_binary.md
```

View File

@@ -0,0 +1,232 @@
<!-- file: docs/prompts/PROMPT_0_7_60_meteora_damm_next_dex.md -->
# Prompt — 0.7.60 Meteora DAMM v1 puis DAMM v2
## Décision
Ne pas fusionner Meteora DAMM v1 et Meteora DAMM v2 dans une seule tranche dimplémentation.
Utiliser des versions séparées :
```text
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Raison :
- `program_id` différents ;
- surfaces IDL/discriminators différentes ;
- corpus historiques et besoins de validation différents ;
- clôture SQL plus lisible ;
- risque réduit de faux positifs cross-version ;
- rollback plus simple si une version contient une hypothèse incorrecte.
Partage autorisé :
- helpers communs privés ;
- patterns communs de récupération fee/reward amounts ;
- conventions communes de coverage/tests ;
- structure commune de rapport ;
- template SQL commun.
Ne pas partager la classification de decoder dune manière qui masque les discriminators version-spécifiques ou les layouts propres à chaque programme.
## Contexte
`0.7.57 meteora_dlmm` est clos.
Les tranches intermédiaires planifiées avant DAMM sont maintenant :
```text
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
0.7.59 -> demo4_program_surface_discovery
```
Raison du changement : la régression PumpSwap/PumpFees a montré quune base DEX isolée ne suffit pas. Les futurs décodeurs doivent être validés à la fois sur une base dédiée et sur une base consolidée `final.db` issue du merger.
Surfaces Meteora connues :
```text
meteora_dbc -> clos 0.7.56
meteora_dlmm -> clos 0.7.57
meteora_damm_v1 -> 0.7.60
meteora_damm_v2 -> 0.7.61
meteora_vault -> plus tard, surface séparée
```
## Workflow obligatoire pour 0.7.60+
Pour chaque nouvelle tranche DEX :
1. Créer une base vide dédiée au DEX.
2. Backfiller le corpus DAMM v1 dans cette base dédiée.
3. Développer decoder/materializer sur cette base.
4. Clore les gates SQL DAMM v1 localement.
5. Fusionner la base dédiée dans une copie de `final.db` via le merger `0.7.58`.
6. Rejouer la base fusionnée avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
7. Lancer les validations globales anti-régression Pump/Raydium/Meteora.
8. Ne considérer la tranche close que si la base dédiée et la base fusionnée sont propres.
## Cible 0.7.60 — meteora_damm_v1
Program id depuis la roadmap :
```text
Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
```
Objectif principal :
```text
Full decode + full materialization pour toutes les instructions/events DAMM v1 disponibles depuis les IDL locales et les sources upstream.
```
Familles attendues :
```text
swap
pool_create
add_liquidity
remove_liquidity
lock/unlock liquidity si présent
fee/admin/config
lifecycle/migration si présent
```
Règles :
- Pas de decoded-only pour une entrée utile observée si elle peut être matérialisée sûrement.
- Ne pas créer de trade/candle depuis des non-swaps.
- Ne pas matérialiser les transactions failed.
- Ne pas agréger artificiellement les fees multi-mint.
- Utiliser `k_sol_fee_event_amounts` pour les legs fee fiables.
- Utiliser la récupération inner SPL transfer seulement avec allowlist explicite et tests.
- Conserver toutes les entrées IDL/upstream non observées dans la coverage avec `0/0` et proof status clair.
- Un decoder ne doit pas aborter toute une transaction multi-protocoles pour un payload secondaire tronqué/incompatible si lentrée peut être ignorée proprement.
## Sources à vérifier
Inspecter dabord le répertoire local :
```text
idls/
```
Puis comparer avec :
```text
Carbon decoders
Pinax/substreams-solana-idls
0xfnzero sol-parser-sdk / solana-streamer
ancien code local et rapports historiques du projet
samples Solscan / backfills Demo3
surfaces visibles dans Demo4 si 0.7.59 est disponible
```
Ne pas considérer les anciens résultats `0.7.36` ou `0.7.46` comme clôture finale. Revalider depuis le schéma courant et les règles actuelles de matérialisation.
## Plan de travail
1. Créer ou rafraîchir les entrées coverage `meteora_damm_v1`.
2. Vérifier le `program_id` et la surface IDL locale.
3. Étendre lenum/local classifier des discriminators.
4. Ajouter le naming dans `instruction_observation_index`.
5. Décoder toutes les instructions et tous les events Anchor disponibles.
6. Matérialiser swaps, liquidity, lifecycle, fee, reward/admin/orderbook si applicable.
7. Ajouter des tests synthétiques pour chaque instruction/event IDL, y compris non observé.
8. Ajouter le SQL de validation DAMM v1.
9. Rejouer sur base fraîche dédiée avec `forceDexDecode=yes`.
10. Fusionner la base dédiée vers `final.next.db` via `kb_db_merge`.
11. Rejouer `final.next.db`.
12. Lancer les gates cross-DEX.
13. Clore seulement si les gates locales et globales sont propres.
## Gates SQL obligatoires
Reprendre le pattern DLMM :
```text
fallback upstream pour entrées localement couvertes -> vide
instruction_name null/blank -> vide
decoded sans coverage -> vide
successful non-materialized without skip/policy -> vide
failed tx materialization -> vide
multi-target materialization -> vide
non-swap trade/candle -> vide
fee scalar parent without leg -> vide
orphan fee legs -> vide
coverage logical duplicates -> vide
watchlist sans backlog meteora_damm_v1
```
Ajouter les gates anti-régression globales après merge :
```text
successful non-materialized Pump/Raydium/Meteora expliqué ou vide
pure instruction_audit inattendu -> vide
decoder errors cross-surface -> vide
failed tx materialized -> vide
trade/candle non-swap -> vide
```
## Cible 0.7.61 — meteora_damm_v2
Program id depuis la roadmap :
```text
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
```
Nouvrir cette tranche quaprès clôture DAMM v1.
La tranche v2 peut réutiliser le template et des helpers privés, mais doit conserver ses propres éléments :
```text
decoder code
coverage entries
instruction enum
event mapping
synthetic tests
SQL validation
rapport
base dédiée
validation final.db merge
```
## Livrables attendus pour 0.7.60
Fichiers probables :
```text
kb_lib/src/dex/meteora_damm_v1.rs
kb_lib/src/dex_event_coverage.rs
kb_lib/src/dex_event_classification.rs
kb_lib/src/instruction_observation_index.rs
kb_lib/src/non_trade_event_materialization.rs
validation_sql/SQL_VALIDATION_METEORA_DAMM_V1_0_7_60.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_AFTER_DAMM_V1_0_7_60.sql
docs/reports/METEORA_DAMM_V1_EVENT_COVERAGE_REPORT.md
```
Mettre à jour les re-exports si des modules ou requêtes sont ajoutés :
```text
kb_lib/src/dex.rs
kb_lib/src/lib.rs
kb_lib/src/db.rs
```
## Note finale
Si la découverte corpus montre que DAMM v1 et v2 partagent une logique basse-niveau précise, créer des helpers privés communs.
Ne pas fusionner les deux protocoles dans un seul decoder, une seule coverage ou un seul rapport de clôture.

View File

@@ -0,0 +1,232 @@
<!-- file: docs/prompts/PROMPT_0_7_60_meteora_damm_next_dex.md -->
# Prompt — 0.7.60 Meteora DAMM v1 puis DAMM v2
## Décision
Ne pas fusionner Meteora DAMM v1 et Meteora DAMM v2 dans une seule tranche dimplémentation.
Utiliser des versions séparées :
```text
0.7.60 -> meteora_damm_v1
0.7.61 -> meteora_damm_v2
```
Raison :
- `program_id` différents ;
- surfaces IDL/discriminators différentes ;
- corpus historiques et besoins de validation différents ;
- clôture SQL plus lisible ;
- risque réduit de faux positifs cross-version ;
- rollback plus simple si une version contient une hypothèse incorrecte.
Partage autorisé :
- helpers communs privés ;
- patterns communs de récupération fee/reward amounts ;
- conventions communes de coverage/tests ;
- structure commune de rapport ;
- template SQL commun.
Ne pas partager la classification de decoder dune manière qui masque les discriminators version-spécifiques ou les layouts propres à chaque programme.
## Contexte
`0.7.57 meteora_dlmm` est clos.
Les tranches intermédiaires planifiées avant DAMM sont maintenant :
```text
0.7.58 -> sqlite_db_transaction_merger + validation anti-régression cross-DEX
0.7.59 -> demo4_program_surface_discovery
```
Raison du changement : la régression PumpSwap/PumpFees a montré quune base DEX isolée ne suffit pas. Les futurs décodeurs doivent être validés à la fois sur une base dédiée et sur une base consolidée `final.db` issue du merger.
Surfaces Meteora connues :
```text
meteora_dbc -> clos 0.7.56
meteora_dlmm -> clos 0.7.57
meteora_damm_v1 -> 0.7.60
meteora_damm_v2 -> 0.7.61
meteora_vault -> plus tard, surface séparée
```
## Workflow obligatoire pour 0.7.60+
Pour chaque nouvelle tranche DEX :
1. Créer une base vide dédiée au DEX.
2. Backfiller le corpus DAMM v1 dans cette base dédiée.
3. Développer decoder/materializer sur cette base.
4. Clore les gates SQL DAMM v1 localement.
5. Fusionner la base dédiée dans une copie de `final.db` via le merger `0.7.58`.
6. Rejouer la base fusionnée avec :
```text
metadata=no
skipDexDecode=no
forceDexDecode=yes
deferInstructionObservations=yes
```
7. Lancer les validations globales anti-régression Pump/Raydium/Meteora.
8. Ne considérer la tranche close que si la base dédiée et la base fusionnée sont propres.
## Cible 0.7.60 — meteora_damm_v1
Program id depuis la roadmap :
```text
Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB
```
Objectif principal :
```text
Full decode + full materialization pour toutes les instructions/events DAMM v1 disponibles depuis les IDL locales et les sources upstream.
```
Familles attendues :
```text
swap
pool_create
add_liquidity
remove_liquidity
lock/unlock liquidity si présent
fee/admin/config
lifecycle/migration si présent
```
Règles :
- Pas de decoded-only pour une entrée utile observée si elle peut être matérialisée sûrement.
- Ne pas créer de trade/candle depuis des non-swaps.
- Ne pas matérialiser les transactions failed.
- Ne pas agréger artificiellement les fees multi-mint.
- Utiliser `k_sol_fee_event_amounts` pour les legs fee fiables.
- Utiliser la récupération inner SPL transfer seulement avec allowlist explicite et tests.
- Conserver toutes les entrées IDL/upstream non observées dans la coverage avec `0/0` et proof status clair.
- Un decoder ne doit pas aborter toute une transaction multi-protocoles pour un payload secondaire tronqué/incompatible si lentrée peut être ignorée proprement.
## Sources à vérifier
Inspecter dabord le répertoire local :
```text
idls/
```
Puis comparer avec :
```text
Carbon decoders
Pinax/substreams-solana-idls
0xfnzero sol-parser-sdk / solana-streamer
ancien code local et rapports historiques du projet
samples Solscan / backfills Demo3
surfaces visibles dans Demo4 si 0.7.59 est disponible
```
Ne pas considérer les anciens résultats `0.7.36` ou `0.7.46` comme clôture finale. Revalider depuis le schéma courant et les règles actuelles de matérialisation.
## Plan de travail
1. Créer ou rafraîchir les entrées coverage `meteora_damm_v1`.
2. Vérifier le `program_id` et la surface IDL locale.
3. Étendre lenum/local classifier des discriminators.
4. Ajouter le naming dans `instruction_observation_index`.
5. Décoder toutes les instructions et tous les events Anchor disponibles.
6. Matérialiser swaps, liquidity, lifecycle, fee, reward/admin/orderbook si applicable.
7. Ajouter des tests synthétiques pour chaque instruction/event IDL, y compris non observé.
8. Ajouter le SQL de validation DAMM v1.
9. Rejouer sur base fraîche dédiée avec `forceDexDecode=yes`.
10. Fusionner la base dédiée vers `final.next.db` via `kb_db_merge`.
11. Rejouer `final.next.db`.
12. Lancer les gates cross-DEX.
13. Clore seulement si les gates locales et globales sont propres.
## Gates SQL obligatoires
Reprendre le pattern DLMM :
```text
fallback upstream pour entrées localement couvertes -> vide
instruction_name null/blank -> vide
decoded sans coverage -> vide
successful non-materialized without skip/policy -> vide
failed tx materialization -> vide
multi-target materialization -> vide
non-swap trade/candle -> vide
fee scalar parent without leg -> vide
orphan fee legs -> vide
coverage logical duplicates -> vide
watchlist sans backlog meteora_damm_v1
```
Ajouter les gates anti-régression globales après merge :
```text
successful non-materialized Pump/Raydium/Meteora expliqué ou vide
pure instruction_audit inattendu -> vide
decoder errors cross-surface -> vide
failed tx materialized -> vide
trade/candle non-swap -> vide
```
## Cible 0.7.61 — meteora_damm_v2
Program id depuis la roadmap :
```text
cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG
```
Nouvrir cette tranche quaprès clôture DAMM v1.
La tranche v2 peut réutiliser le template et des helpers privés, mais doit conserver ses propres éléments :
```text
decoder code
coverage entries
instruction enum
event mapping
synthetic tests
SQL validation
rapport
base dédiée
validation final.db merge
```
## Livrables attendus pour 0.7.60
Fichiers probables :
```text
kb_lib/src/dex/meteora_damm_v1.rs
kb_lib/src/dex_event_coverage.rs
kb_lib/src/dex_event_classification.rs
kb_lib/src/instruction_observation_index.rs
kb_lib/src/non_trade_event_materialization.rs
validation_sql/SQL_VALIDATION_METEORA_DAMM_V1_0_7_60.sql
validation_sql/SQL_VALIDATION_CROSS_DEX_REGRESSION_AFTER_DAMM_V1_0_7_60.sql
docs/reports/METEORA_DAMM_V1_EVENT_COVERAGE_REPORT.md
```
Mettre à jour les re-exports si des modules ou requêtes sont ajoutés :
```text
kb_lib/src/dex.rs
kb_lib/src/lib.rs
kb_lib/src/db.rs
```
## Note finale
Si la découverte corpus montre que DAMM v1 et v2 partagent une logique basse-niveau précise, créer des helpers privés communs.
Ne pas fusionner les deux protocoles dans un seul decoder, une seule coverage ou un seul rapport de clôture.

View File

@@ -0,0 +1,247 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.48-raydium-cpmm.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.48` / Raydium CPMM event coverage
Reprise du projet `khadhroony-bobobot` après clôture de `0.7.48-pre`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.48-pre-event-coverage-report
```
Docs à fournir aussi :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
```
## État validé avant reprise
`0.7.48-pre` a ajouté et clôturé le checkpoint DB/reporting de couverture événementielle :
```text
k_sol_dex_event_coverage_entries
DexEventCoverageService
sync upstream registry -> coverage table
refresh local counts depuis k_sol_dex_decoded_events + tables métier existantes
summaries coverage dans LocalPipelineDiagnosticSummaryDto
summaries/counters coverage dans LocalPipelineValidationReportDto
profil validation 0.7.48-pre_event_coverage_db_checkpoint
profil exposé dans Demo Pipeline 2
```
Invariants maintenus :
```text
aucun decoder DEX modifié
aucun trade/candle créé par la couverture
aucun program_id promu sans corpus local
upstream Git/IDL = indice, pas preuve métier
failed transaction = audit-only
non-trade event = jamais trade/candle
```
## Décision de reprise
Commencer maintenant par Raydium avant Meteora.
Ordre courant :
```text
0.7.48 raydium_cpmm
0.7.49 raydium_clmm
0.7.50 pump_swap
0.7.51 pump_fun
0.7.52 meteora_dbc
0.7.53 meteora_dlmm upstream parity
0.7.54 meteora_damm_v1 upstream parity
0.7.55 meteora_damm_v2
0.7.56 phoenix_v1 audit-only completion
0.7.57 openbook_v2 audit-only completion
0.7.58 orca_whirlpools
0.7.59+ launch surfaces, candidats/historiques, validation consolidée
```
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
Pour `0.7.48`, commencer par Carbon + fnzero pour Raydium CPMM, puis comparer aux IDL complémentaires si disponibles.
## Objectif `0.7.48` — `raydium_cpmm`
Objectif : reprendre `raydium_cpmm` comme première tranche DEX/version après le checkpoint coverage.
À faire :
1. lister tous les discriminants/instructions/events `raydium_cpmm` depuis Carbon/fnzero/IDL ;
2. synchroniser/remplir `k_sol_dex_event_coverage_entries` pour `raydium-cpmm` ;
3. comparer listed/decoded/observed/materialized/trade_count via le rapport coverage ;
4. compléter le decoder spécialisé `raydium_cpmm` seulement pour les events CPMM confirmables ;
5. remplacer/nettoyer le fallback `upstream_git.instruction_match` quand un decoder local spécialisé couvre l'entrée ;
6. garder les events connus mais non observés en `upstream_git_mapped_unverified` ;
7. garder les events observés mais non matérialisés en audit-only/decoded ;
8. ne matérialiser que les non-trades déjà prouvés par corpus et compatibles avec les tables existantes ;
9. ne pas ajouter encore `k_sol_token_transfer_events` ou `k_sol_orderbook_events`, sauf besoin bloquant démontré ;
10. ne pas modifier les règles trade/candle sauf bug de faux positif prouvé.
## Events/familles à couvrir explicitement
Ne pas se limiter aux swaps.
Inclure dans l'audit coverage :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Pour `raydium_cpmm`, certaines familles seront probablement `-` ou `non applicable`, mais elles doivent être explicitement justifiées dans la coverage matrix ou la table.
## Règles fixes
- Un event non-trade ne produit jamais `trade_event`, metric ou candle.
- Une transaction failed reste audit, jamais trade/candle.
- Un discriminator upstream n'est pas une preuve métier.
- Un program id upstream n'est pas vérifié sans corpus local.
- Chaque decoder spécialisé doit remplacer le fallback `upstream_git.instruction_match` pour éviter les doublons.
- Tout event connu mais non observé reste `upstream_git_mapped_unverified`.
- Tout event observé mais non matérialisé reste audit-only ou decoded, pas materialized.
- Ne pas promouvoir de nouvelle table DB métier sans preuve que plusieurs DEX en auront besoin.
## Requêtes SQL utiles
Après sync/refresh coverage :
```sql
SELECT *
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium-cpmm'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
```sql
SELECT
decoder_code,
listed_entry_count,
decoded_entry_count,
observed_entry_count,
materialized_entry_count,
total_observed_count,
total_materialized_count,
trade_count,
audit_only_entry_count,
upstream_git_mapped_unverified_entry_count,
upstream_git_local_corpus_observed_entry_count,
upstream_git_local_corpus_materialized_entry_count
FROM (
SELECT
decoder_code,
COUNT(*) AS listed_entry_count,
SUM(CASE WHEN local_event_kind IS NOT NULL AND local_event_kind <> '' THEN 1 ELSE 0 END) AS decoded_entry_count,
SUM(CASE WHEN observed_count > 0 THEN 1 ELSE 0 END) AS observed_entry_count,
SUM(CASE WHEN materialized_count > 0 THEN 1 ELSE 0 END) AS materialized_entry_count,
COALESCE(SUM(observed_count), 0) AS total_observed_count,
COALESCE(SUM(materialized_count), 0) AS total_materialized_count,
COALESCE(SUM(trade_count), 0) AS trade_count,
SUM(CASE WHEN expected_db_target = 'k_sol_dex_decoded_events_only' THEN 1 ELSE 0 END) AS audit_only_entry_count,
SUM(CASE WHEN proof_status = 'upstream_git_mapped_unverified' THEN 1 ELSE 0 END) AS upstream_git_mapped_unverified_entry_count,
SUM(CASE WHEN proof_status = 'upstream_git_local_corpus_observed' THEN 1 ELSE 0 END) AS upstream_git_local_corpus_observed_entry_count,
SUM(CASE WHEN proof_status = 'upstream_git_local_corpus_materialized' THEN 1 ELSE 0 END) AS upstream_git_local_corpus_materialized_entry_count
FROM k_sol_dex_event_coverage_entries
GROUP BY decoder_code
)
WHERE decoder_code = 'raydium-cpmm';
```
Audit-only safety :
```sql
SELECT
de.protocol_name,
de.event_kind,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_cpmm'
AND (
de.event_kind LIKE '%audit%'
OR json_extract(de.payload_json, '$.eventActionability') IN ('non_trade_useful', 'informational', 'non_actionable_trade')
)
GROUP BY de.protocol_name, de.event_kind
ORDER BY trade_count DESC, de.event_kind;
```
## Contraintes de code
Conserver les règles du workspace :
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Livrables attendus pour `0.7.48`
1. delta archive avec uniquement les fichiers ajoutés/modifiés ;
2. mise à jour `README.md`, `ROADMAP.md`, `CHANGELOG.md` si la tranche avance ;
3. rapport de couverture `raydium_cpmm` ;
4. SQL de validation ;
5. tests verts :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```

View File

@@ -0,0 +1,338 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.50-raydium-launchpad.md -->
# khadhroony-bobobot `0.7.50` / Raydium Launchpad event coverage
Reprise du projet `khadhroony-bobobot` après clôture fonctionnelle de `0.7.49 raydium_clmm`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.49-raydium-clmm-final
```
Inclure les docs et SQL de validation produits en fin de `0.7.49`, notamment :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md
docs/RAYDIUM_CLMM_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_48.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_49_PRE23.sql
```
## État validé avant reprise
`0.7.48` a clôturé `raydium_cpmm`.
`0.7.49` a clôturé `raydium_clmm` avec les invariants suivants :
```text
Raydium CLMM decoder_code local = raydium_clmm
coverage synchronisée avec Carbon / Raydium IDL / Pinax / fnzero
45 entrées coverage CLMM listées
33 entrées CLMM décodées localement
33 entrées observées localement
25 entrées matérialisées localement
residual raydium_clmm.instruction_audit = 0
fallback upstream_git.instruction_match localement couvert = 0 après cleanup FK-safe
non-trade CLMM = jamais trade/candle
failed transaction = jamais matérialisée dans les tables métier
Program data CLMM préparé mais non promu sans corpus local observé
side effects SPL Token / Token-2022 restent transversaux, pas raydium_clmm.* directs
```
Dernière validation locale observée :
```text
cargo test -p kb_lib: ok
local pipeline replay: 2197 replayed, 0 decode skipped, 2197 ledger upserts, 1461 unsafe ledger rows, 1217 trades, 111 liquidity, 25 lifecycle, 4868 candle upserts, instructionObservations='19798'
```
## Décision de reprise
Commencer `0.7.50` par `raydium_launchpad`, avant Pump/Meteora.
Ordre strict Raydium proposé avant Pump :
```text
0.7.50 raydium_launchpad / Raydium LaunchLab-Launchpad surface
0.7.51 raydium_amm_v4
0.7.52 raydium_stable
0.7.53 raydium_pool_v4 audit / program-id decision, seulement si program id distinct et corpus exploitable
0.7.54 pump_swap
0.7.55 pump_fun
0.7.56 meteora_dbc
0.7.57 meteora_dlmm upstream parity
0.7.58 meteora_damm_v1 upstream parity
0.7.59 meteora_damm_v2
0.7.60 phoenix_v1 audit-only completion
0.7.61 openbook_v2 audit-only completion
0.7.62 orca_whirlpools
0.7.63+ launch surfaces, candidats/historiques, validation consolidée
```
`raydium_pool_v4` ne doit pas être promu automatiquement comme DEX/surface métier tant que son program id et son rôle exact n'ont pas été confirmés. Le fichier `raydium_pool_v4.json` de `sol-parser-sdk` doit être audité comme source IDL annexe, pas comme preuve métier.
## Sources Git/IDL à utiliser systématiquement
- https://github.com/sevenlabs-hq/carbon/tree/main/decoders
- https://github.com/0xfnzero/solana-streamer
- https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
- copie locale fournie de `0xfnzero/sol-parser-sdk`, si présente dans l'archive de reprise
- https://github.com/pinax-network/substreams-solana-idls/tree/main/src
- https://github.com/hodlwarden/solana-tx-parser/tree/main/src
- https://github.com/openbook-dex/openbook-v2
- https://github.com/all-in-one-blockchain/phoenix-onchain-mm
- https://docs.vybenetwork.com/docs/available-dexs-amms
Pour `0.7.50 raydium_launchpad`, utiliser aussi explicitement :
```text
https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj#programIdl
```
et les filtres Solscan de type :
```text
https://solscan.io/account/LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
Solscan sert à trouver vite des signatures à backfiller. Solscan ne doit jamais être considéré comme preuve métier finale sans corpus local et validation SQL.
## Base de données de travail
Initialiser une nouvelle base SQLite dédiée à `0.7.50`.
Procédure attendue :
1. créer une nouvelle DB via `config.json` ou équivalent ;
2. démarrer `kb_demo_app` pour initialiser le schéma ;
3. backfiller des signatures ciblées par discriminant / instruction ;
4. backfiller des pools/comptes pertinents si la surface en expose ;
5. exécuter un replay local avec `forceDexDecode=yes` ;
6. relancer les SQL de coverage ;
7. ne promouvoir une entrée que si le corpus local confirme son sens métier.
## Objectif `0.7.50` — `raydium_launchpad`
Objectif : couvrir Raydium Launchpad/LaunchLab comme nouvelle surface Raydium après CPMM et CLMM.
À faire :
1. lire le code local existant lié à Raydium Launchpad, s'il existe ;
2. lister toutes les instructions/events depuis Carbon/fnzero/IDL/Pinax/Solscan Program IDL ;
3. synchroniser/remplir `k_sol_dex_event_coverage_entries` pour `raydium_launchpad` ;
4. vérifier `decoder_code` local en snake_case : `raydium_launchpad` ;
5. utiliser `k_sol_instruction_observations` pour inspecter les discriminants observés localement ;
6. utiliser Demo3 / Solscan `instruction=<discriminator>` pour trouver des signatures ciblées ;
7. backfiller les signatures via Demo2, idéalement par batch textarea ;
8. rejouer localement avec `forceDexDecode=yes` et `deferInstructionObservations=yes` ;
9. comparer listed/decoded/observed/materialized/trade_count via SQL coverage ;
10. compléter le decoder spécialisé seulement pour les entrées confirmées ;
11. supprimer/nettoyer `upstream_git.instruction_match` lorsque l'entrée est couverte localement ;
12. garder les entrées connues mais non observées en `upstream_git_unverified` ou `upstream_git_mapped_unverified` ;
13. garder les entrées observées mais non matérialisées en audit-only/decoded ;
14. ne matérialiser que les non-trades prouvés par corpus local et compatibles avec les tables existantes ;
15. ne modifier les règles trade/candle que si un faux positif est prouvé.
## Familles à auditer explicitement
Ne pas se limiter aux swaps.
Inclure dans la coverage :
```text
swap
pool_create
add_liquidity
remove_liquidity
position_open
position_close
fee
reward
admin/config
mint
burn
transfer
account_create
account_close
wrap_sol
unwrap_sol
order_place
order_cancel
order_fill
consume_events
settle_funds
vault_deposit
vault_withdraw
lock
unlock
launch
migration
stake
unstake
unknown/unmapped audit
```
Certaines familles peuvent être non applicables ou uniquement visibles comme side effects SPL Token / Token-2022. Elles doivent être explicitement justifiées dans `DEX_EVENT_COVERAGE_MATRIX.md`.
## Points d'attention hérités de CPMM/CLMM
- `decoder_code` local doit rester en `snake_case`.
- Les slugs upstream peuvent garder les tirets.
- `upstream Git/IDL/Solscan = indice, pas preuve métier`.
- `program_id` upstream non promu sans corpus local.
- Chaque decoder spécialisé doit remplacer le fallback `upstream_git.instruction_match` pour les entrées localement couvertes.
- Les side effects SPL Token (`mintTo`, `burn`, `transfer`, `transferChecked`, `closeAccount`) ne deviennent pas `raydium_launchpad.*` sans preuve qu'il s'agit d'instructions directes du programme Launchpad.
- Failed transaction = decoded/audit possible, jamais matérialisée métier.
- Non-trade event = jamais trade/candle.
- Pas de nouvelle table métier transversale sans preuve multi-DEX.
## Requêtes SQL minimales à produire
Créer un fichier :
```text
validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql
```
Inclure au minimum :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_launchpad'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Coverage summary :
```sql
SELECT
decoder_code,
COUNT(*) AS listed_entry_count,
SUM(CASE WHEN local_event_kind IS NOT NULL AND local_event_kind <> '' THEN 1 ELSE 0 END) AS decoded_entry_count,
SUM(CASE WHEN observed_count > 0 THEN 1 ELSE 0 END) AS observed_entry_count,
SUM(CASE WHEN materialized_count > 0 THEN 1 ELSE 0 END) AS materialized_entry_count,
COALESCE(SUM(observed_count), 0) AS total_observed_count,
COALESCE(SUM(materialized_count), 0) AS total_materialized_count,
COALESCE(SUM(trade_count), 0) AS trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_launchpad'
GROUP BY decoder_code;
```
Instruction observations :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_launchpad'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC, instruction_name;
```
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_launchpad'
GROUP BY de.event_kind
ORDER BY decoded_count DESC, de.event_kind;
```
```sql
SELECT
json_extract(payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(payload_json, '$.upstreamEntryName') AS entry_name,
json_extract(payload_json, '$.upstreamDiscriminatorHex') AS discriminator_hex,
COUNT(*) AS fallback_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'upstream_git'
AND event_kind = 'upstream_git.instruction_match'
AND json_extract(payload_json, '$.upstreamDecoderCode') = 'raydium_launchpad'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex
ORDER BY fallback_count DESC, entry_name;
```
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_launchpad'
AND tx.err_json IS NOT NULL
AND tx.err_json <> ''
AND tx.err_json <> 'null'
GROUP BY de.event_kind
ORDER BY trade_count DESC, decoded_count DESC;
```
## Contraintes de code
Conserver les règles du workspace :
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Livrables attendus pour `0.7.50`
1. delta archive avec uniquement les fichiers ajoutés/modifiés ;
2. mise à jour `README.md`, `ROADMAP.md`, `CHANGELOG.md` ;
3. rapport `docs/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md` ;
4. SQL `validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql` ;
5. tests verts :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## Question ouverte à traiter tôt dans `0.7.50`
Auditer `raydium_pool_v4.json` dans `sol-parser-sdk` :
- confirmer s'il correspond à un program id distinct ;
- confirmer s'il s'agit d'une surface Raydium Pool/Lending/Strategy différente de `raydium_amm_v4` ;
- décider si une version dédiée `0.7.53 raydium_pool_v4` est nécessaire ;
- ne pas modifier la roadmap comme surface finale tant que le program id n'est pas confirmé.

View File

@@ -0,0 +1,386 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.51-raydium-amm-v4.md -->
# Prompt de reprise — khadhroony-bobobot `0.7.51` / Raydium AMM v4 event coverage
Reprise du projet `khadhroony-bobobot` après clôture de `0.7.50 raydium_launchpad` et re-vérification finale CPMM/CLMM.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusqu'à :
```text
0.7.50-raydium-launchpad-final
```
Joindre aussi les docs et SQL de validation à jour :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md
docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_AUDIT_CLEANUP_0_7_50_FINAL.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_50_RECHECK.sql
validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_50_RECHECK.sql
```
## État validé avant reprise
`0.7.50` a clôturé `raydium_launchpad` et consolidé les rechecks CPMM/CLMM.
Dernier replay local rapporté après cleanup final CPMM :
```text
1124 replayed
0 decode skipped
1124 ledger upserts
539 unsafe ledger rows
561 trades
50 liquidity
13 lifecycle
0 tokenAccount
2224 candle upserts
instructionObservations = 7010
resetDeleted = 1182
catalog = 37 tokens / 40 pools / 40 pairs
```
Points de clôture à préserver :
```text
raydium_launchpad : surface canonique, program id LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj
Launchpad trade_event matérialisé seulement quand corpus + successful tx le prouvent
Launchpad initialize* fournit le catalogue pool/pair, pas de faux trade/candle
CPMM 40f4bc78a7e9690a est raydium_cpmm.anchor_idl_instruction decoded-only
CPMM residual raydium_cpmm.instruction_audit 40f4bc78a7e9690a = vide après replay final
CPMM decoded event without coverage entry = vide après replay final
CPMM upstream_git.instruction_match fallback résiduel = vide
CPMM non-swap materialization gap hors failed tx = vide
CLMM residual instruction_audit / upstream fallback doivent rester vides
k_sol_instruction_observations reste une table technique, pas une table métier
Solscan instruction=<discriminator> est une aide de découverte, pas une preuve métier
```
Requêtes CPMM post-fix obligatoires avant d'ouvrir `0.7.51` :
```sql
SELECT
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS audit_count,
COUNT(DISTINCT transaction_id) AS tx_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'raydium_cpmm'
AND event_kind = 'raydium_cpmm.instruction_audit'
GROUP BY discriminator_hex
ORDER BY audit_count DESC, discriminator_hex;
```
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_cpmm'
AND ce.local_event_kind = de.event_kind
WHERE de.protocol_name = 'raydium_cpmm'
AND ce.id IS NULL
GROUP BY de.event_kind
ORDER BY decoded_count DESC, de.event_kind;
```
Ces deux requêtes doivent être vides après replay `forceDexDecode=yes`.
## Décision de reprise
Ouvrir une nouvelle tranche :
```text
0.7.51 raydium_amm_v4
```
Ne pas commencer par `raydium_pool_v4` comme nouveau decoder autonome tant que son program id et son rôle métier ne sont pas prouvés localement.
`raydium_pool_v4` doit être traité dans `0.7.51` comme une **source à auditer / comparer** avec `raydium_amm_v4`, pas comme version déjà décidée. La roadmap peut conserver une entrée de décision `raydium_pool_v4 audit / program-id decision`, mais cette entrée doit être reformulée comme décision conditionnelle :
```text
si raydium_pool_v4 correspond au même program id AMM v4 ou à un layout alternatif -> intégrer à raydium_amm_v4
si raydium_pool_v4 correspond à un autre program id / strategy / farm / pool wrapper -> créer une tranche dédiée seulement après corpus local
```
## Objectif `0.7.51` — `raydium_amm_v4`
Reprendre Raydium AMM v4 legacy au même niveau de couverture que CPMM/CLMM :
```text
swaps
pool lifecycle / pool_create
add_liquidity / remove_liquidity
fees / admin/config
open_orders / target_orders / serum/openbook side effects documentés
side effects SPL Token / Token-2022 documentés mais non promus comme raydium_amm_v4.* directs
fallback instruction_audit nettoyé quand une entrée locale spécialisée couvre l'instruction
coverage entries synchronisées et rafraîchies
```
Code local canonique :
```text
raydium_amm_v4
```
Program id canonique connu :
```text
675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
```
Solscan Program IDL / recherche par instruction :
```text
https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8#programIdl
https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8?instruction=<DISCRIMINATOR>&hide_spam=true&hide_failed=true&show_related=false&sort=desc
```
## Nouvelle base de travail
Démarrer `0.7.51` sur une base SQLite vide dédiée.
Avant le replay de validation complet, prévoir un corpus initial construit volontairement :
```text
1. Demo3 program_id = 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8
2. Solscan Program IDL + instruction=<DISCRIMINATOR>
3. backfill Demo2 de signatures contenant des instructions AMM v4 variées
4. backfill de pools AMM v4 quand Demo3/Solscan fournit un AMM/pool account fiable
```
Ne pas interpréter l'absence de résultat Solscan comme absence on-chain définitive.
## Sources Git/IDL à utiliser systématiquement
Sources globales :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders
https://github.com/0xfnzero/solana-streamer
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idls
https://github.com/pinax-network/substreams-solana-idls/tree/main/src
https://github.com/hodlwarden/solana-tx-parser/tree/main/src
https://docs.vybenetwork.com/docs/available-dexs-amms
```
Sources spécifiques `raydium_amm_v4` à vérifier en priorité :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/raydium-amm-v4-decoder
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/amm
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idl/raydium_amm_v4.json
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idls/raydium_amm_v4.json
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idl/raydium_pool_v4.json
https://github.com/0xfnzero/sol-parser-sdk/blob/main/idls/raydium_pool_v4.json
https://solscan.io/account/675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8#programIdl
```
## Vérification obligatoire `raydium_pool_v4`
Avant de coder une tranche séparée `raydium_pool_v4`, faire une vérification explicite :
```text
1. comparer idl/raydium_pool_v4.json et idls/raydium_pool_v4.json
2. comparer idl/raydium_amm_v4.json et idls/raydium_amm_v4.json
3. chercher si raydium_pool_v4 contient un program id explicite
4. comparer les instructions communes : initialize, initialize2, deposit, withdraw, swapBaseIn, swapBaseOut, monitorStep, admin/config
5. vérifier si raydium_pool_v4 décrit :
- le même Raydium AMM v4 program id 675kPX...
- un layout alternatif d'instruction
- un wrapper strategy / pool / farming / lending
- une ancienne ABI non directement liée au program id 675kPX...
6. ne pas promouvoir `raydium_pool_v4` sans corpus local :
- k_sol_instruction_observations
- decoded events locaux
- coverage local_event_kind
- absence de fallback upstream
```
Décision attendue dans `0.7.51` :
```text
Option A : raydium_pool_v4 = alias/source complémentaire de raydium_amm_v4 -> intégrer ses discriminants/layouts dans raydium_amm_v4 et supprimer la version roadmap autonome.
Option B : raydium_pool_v4 = autre program id / autre surface -> conserver une future version dédiée avec program id prouvé.
Option C : raydium_pool_v4 = IDL ambiguë / strategy wrapper sans corpus -> garder en audit roadmap, pas de decoder local.
```
## Règles fixes
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Invariants métier
```text
non-trade event = jamais trade/candle
failed transaction = audit-only / jamais matérialisée métier
upstream Git/IDL/Solscan = indice, pas preuve métier
program id upstream non promu sans corpus local
side effects SPL Token / Token-2022 restent transversaux sauf preuve multi-DEX et décision DB
instruction_audit et upstream_git.instruction_match doivent être nettoyés quand une entrée locale spécialisée couvre le discriminant
```
## Workflow conseillé
1. Créer une nouvelle base SQLite dédiée `0.7.51`.
2. Inventorier Carbon/fnzero/Pinax/Solscan Program IDL pour `raydium_amm_v4`.
3. Auditer `raydium_pool_v4` avant de décider si la roadmap garde une tranche dédiée.
4. Synchroniser `k_sol_dex_event_coverage_entries` avec `decoder_code = raydium_amm_v4`.
5. Utiliser Solscan `instruction=<discriminator>` pour obtenir rapidement des signatures non failed.
6. Backfill Demo2 signature/pool sur corpus varié.
7. Replay local avec :
```text
skipDexDecode = no
forceDexDecode = yes
deferInstructionObservations = yes
```
8. Vérifier :
```text
coverage listed/observed/materialized
residual instruction_audit
residual upstream_git.instruction_match
failed tx materialization = 0
non-trade trade_count = 0
trade/candle only for swap events validés
raydium_pool_v4 decision documented
```
## SQL de contrôle minimal `0.7.51`
Coverage AMM v4 :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_amm_v4'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Instruction observations :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_amm_v4'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC, instruction_name, discriminator_hex;
```
Residual audit :
```sql
SELECT
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS audit_count,
COUNT(DISTINCT transaction_id) AS tx_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'raydium_amm_v4'
AND event_kind = 'raydium_amm_v4.instruction_audit'
GROUP BY discriminator_hex
ORDER BY audit_count DESC, discriminator_hex;
```
Fallback upstream :
```sql
SELECT
json_extract(ug.payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(ug.payload_json, '$.upstreamEntryName') AS entry_name,
json_extract(ug.payload_json, '$.upstreamDiscriminatorHex') AS discriminator_hex,
json_extract(ug.payload_json, '$.upstreamSourceRepo') AS source_repo,
COUNT(*) AS fallback_count,
COUNT(DISTINCT ug.transaction_id) AS tx_count
FROM k_sol_dex_decoded_events ug
JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = json_extract(ug.payload_json, '$.upstreamDecoderCode')
AND ce.entry_name = json_extract(ug.payload_json, '$.upstreamEntryName')
AND ce.discriminator_hex = json_extract(ug.payload_json, '$.upstreamDiscriminatorHex')
AND ce.local_event_kind IS NOT NULL
AND ce.local_event_kind <> ''
WHERE ug.protocol_name = 'upstream_git'
AND ug.event_kind = 'upstream_git.instruction_match'
AND json_extract(ug.payload_json, '$.upstreamDecoderCode') = 'raydium_amm_v4'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex, source_repo
ORDER BY fallback_count DESC, entry_name;
```
Non-swap safety :
```sql
SELECT
de.event_kind,
ce.event_family,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_amm_v4'
AND ce.local_event_kind = de.event_kind
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_amm_v4'
GROUP BY de.event_kind, ce.event_family
HAVING ce.event_family <> 'swap'
AND COUNT(te.id) > 0
ORDER BY trade_count DESC, de.event_kind;
```
## Livrables attendus
```text
archive delta fichiers modifiés/ajoutés
README.md / ROADMAP.md / CHANGELOG.md mis à jour
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_AMM_V4_EVENT_COVERAGE_REPORT.md
docs/reports/RAYDIUM_POOL_V4_DECISION_NOTE.md
validation_sql/SQL_VALIDATION_RAYDIUM_AMM_V4_0_7_51.sql
```
Validation finale locale :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```

View File

@@ -0,0 +1,626 @@
<!-- file: docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.52-raydium-stable.md -->
# Prompt de reprise — `khadhroony-bobobot` — `0.7.52 raydium_stable_swap`
Reprise du projet `khadhroony-bobobot` après clôture de `0.7.51 raydium_amm_v4`.
## Archive de départ
Utiliser la dernière archive complète du workspace intégrant les deltas validés jusquà :
```text
0.7.51-raydium-amm-v4-final
```
Joindre aussi les docs et SQL de validation à jour :
```text
README.md
ROADMAP.md
CHANGELOG.md
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_AMM_V4_EVENT_COVERAGE_REPORT.md
docs/reports/RAYDIUM_POOL_V4_DECISION_NOTE.md
docs/VALIDATION_STATUS_0_7_51_FINAL.md
validation_sql/SQL_VALIDATION_RAYDIUM_AMM_V4_0_7_51.sql
```
## État validé avant reprise
`0.7.51` a clôturé `raydium_amm_v4`.
Validation locale finale rapportée :
```text
cargo test -p kb_lib
405 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings
OK
```
Dernier replay local `0.7.51` :
```text
195 replayed
0 decode skipped
195 ledger upserts
70 unsafe ledger rows
168 trades
7 liquidity
15 lifecycle
0 tokenAccount
668 candle upserts
instructionObservations = 2599
resetDeleted = 1578
catalog = 61 tokens / 65 pools / 65 pairs
```
Points de clôture AMM v4 à préserver :
```text
raydium_amm_v4.swap legacy = vide
decoded without coverage entry = vide
instruction_observations > 1 octet = vide
non-swap -> trade = vide
failed tx -> trade = vide
unexplained successful non-materialized events = vide
multi-target materialization = vide
pre_initialize lifecycle audit = 7 / 7
migrate_to_open_book = orderbook only
simulate_info = decoded-only
raydium_pool_v4 = audit-only / pas de decoder autonome
```
## Décision de reprise
Ouvrir une nouvelle tranche :
```text
0.7.52 raydium_stable_swap
```
Code local canonique :
```text
raydium_stable_swap
```
Program id canonique à utiliser comme hypothèse de départ :
```text
5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h
```
Important : upstream Git/IDL/Solscan est un indice, pas une preuve métier. Le program id doit être confirmé par corpus local via `k_sol_instruction_observations`, decoded events, coverage entries et absence de fallback upstream.
## Nouvelle base de travail
Démarrer `0.7.52` sur une base SQLite vide dédiée.
Avant le replay de validation complet, construire volontairement un corpus initial :
```text
1. Demo3 program_id = 5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h
2. Solscan non filtré + essais instruction=<DISCRIMINATOR>
3. backfill Demo2 de signatures contenant des instructions stable swap variées
4. backfill de pools stable swap quand Demo3/Solscan fournit un AMM/pool account fiable
```
Ne pas interpréter labsence de résultat Solscan comme absence on-chain définitive.
## Note Solscan importante
Pour `raydium_stable_swap`, il semble que Solscan ne dispose pas dun Program IDL exploitable sur :
```text
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h#programIdl
```
Donc le filtrage Solscan par instruction peut ne pas fonctionner avec les discriminants 8 octets Carbon/Pinax.
Il faut tester deux approches :
```text
1. Liens exploratoires courts : instruction=00, 01, 02, ...
2. Liens discriminants upstream 8 octets : instruction=<DISCRIMINATOR_HEX>
```
Solscan est une aide de découverte uniquement. La preuve métier reste locale : signatures backfillées, decoded events, instruction observations et coverage DB.
## Sources Git/IDL à utiliser systématiquement
Sources globales :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders
https://github.com/0xfnzero/solana-streamer
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idl
https://github.com/0xfnzero/sol-parser-sdk/tree/main/idls
https://github.com/pinax-network/substreams-solana-idls/tree/main/src
https://github.com/hodlwarden/solana-tx-parser/tree/main/src
https://docs.vybenetwork.com/docs/available-dexs-amms
```
Sources spécifiques `raydium_stable_swap` à vérifier en priorité :
```text
https://github.com/sevenlabs-hq/carbon/tree/main/decoders/raydium-stable-swap-decoder
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/idl.json
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/instructions.rs
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/events.rs
https://github.com/pinax-network/substreams-solana-idls/tree/main/src/raydium/stable/accounts.rs
```
## Solscan — liens exploratoires
Base non filtrée :
```text
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?hide_spam=false&hide_failed=false&show_related=true&sort=desc
```
Base non filtrée sans related :
```text
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?hide_spam=false&hide_failed=false&show_related=false&sort=desc
```
### Essais courts `instruction=00..11`
Ces liens sont exploratoires. Ils ne prouvent pas que le program utilise des discriminants 1 octet ; ils servent seulement à tester le comportement Solscan quand aucun IDL nest présent.
```text
instruction=00
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=00&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=01
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=01&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=02
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=02&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=03
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=03&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=04
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=04&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=05
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=05&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=06
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=06&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=07
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=07&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=08
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=08&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=09
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=09&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0a
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0a&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0b
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0b&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0c
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0c&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0d
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0d&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0e
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0e&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=0f
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=0f&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=10
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=10&hide_spam=false&hide_failed=false&show_related=false&sort=desc
instruction=11
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=11&hide_spam=false&hide_failed=false&show_related=false&sort=desc
```
### Essais discriminants 8 octets Carbon/Pinax
À tester aussi, mais ne pas bloquer si Solscan ne filtre rien.
```text
initialize / afaf6d1f0d989bed
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=afaf6d1f0d989bed&hide_spam=false&hide_failed=false&show_related=false&sort=desc
pre_initialize / ff5c572dc6acec02
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=ff5c572dc6acec02&hide_spam=false&hide_failed=false&show_related=false&sort=desc
deposit / f223c68952e1f2b6
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=f223c68952e1f2b6&hide_spam=false&hide_failed=false&show_related=false&sort=desc
withdraw / b712469c946da122
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=b712469c946da122&hide_spam=false&hide_failed=false&show_related=false&sort=desc
swap_base_in / 2aec48a2f2182754
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=2aec48a2f2182754&hide_spam=false&hide_failed=false&show_related=false&sort=desc
swap_base_out / a3d29bd0af92d596
https://solscan.io/account/5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h?instruction=a3d29bd0af92d596&hide_spam=false&hide_failed=false&show_related=false&sort=desc
```
## Instructions/discriminants de départ à couvrir
À partir de Carbon stable swap, à vérifier contre Pinax :
```text
initialize afaf6d1f0d989bed pool_create / k_sol_pool_lifecycle_events
pre_initialize ff5c572dc6acec02 pool_create deprecated/partial / k_sol_pool_lifecycle_events si pool context suffisant
deposit f223c68952e1f2b6 liquidity_add / k_sol_liquidity_events
withdraw b712469c946da122 liquidity_remove / k_sol_liquidity_events
swap_base_in 2aec48a2f2182754 swap / k_sol_trade_events
swap_base_out a3d29bd0af92d596 swap / k_sol_trade_events
```
Si Pinax expose des discriminants numériques ou une ABI non Anchor, ne pas forcer les discriminants 8 octets. Le decoder local doit suivre le layout prouvé par corpus local.
## Objectif `0.7.52` — `raydium_stable_swap`
Reprendre Raydium Stable Swap au même niveau de couverture que CPMM/CLMM/AMM v4 :
```text
initialize / pre_initialize
pool lifecycle / pool_create
deposit / withdraw
swap_base_in / swap_base_out
fees / admin/config si présents dans IDL/events/accounts
OpenBook/Serum side effects documentés si présents
side effects SPL Token / Token-2022 documentés mais non promus comme raydium_stable_swap.* directs
fallback instruction_audit nettoyé quand une entrée locale spécialisée couvre linstruction
coverage entries synchronisées et rafraîchies
decoded-only explicitement expliqué quand la matérialisation métier est impossible
```
## Règles fixes
```text
Rust 2024
pas de mod.rs
fichiers Rust avec // file: ...
pas de anyhow
pas de thiserror
pas de ? / unwrap / expect dans kb_lib applicatif
match / if let Err / let Err = ... else
rustdoc sur API publique
re-exports db.rs puis lib.rs si DB modifiée
```
## Invariants métier
```text
non-trade event = jamais trade/candle
failed transaction = audit-only / jamais matérialisée métier
upstream Git/IDL/Solscan = indice, pas preuve métier
program id upstream non promu sans corpus local
side effects SPL Token / Token-2022 restent transversaux sauf preuve multi-DEX et décision DB
instruction_audit et upstream_git.instruction_match doivent être nettoyés quand une entrée locale spécialisée couvre le discriminant
observed_count ne doit pas obligatoirement égaler materialized_count
règle de clôture : observed_count = materialized_count + decoded_only_explained_count + failed_count
```
## Workflow conseillé
1. Créer une nouvelle base SQLite dédiée `0.7.52`.
2. Inventorier Carbon + Pinax pour `raydium_stable_swap`.
3. Vérifier explicitement le program id `5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h`.
4. Vérifier si les discriminants sont 8 octets Anchor-like, 1 octet, ou autre layout.
5. Synchroniser `k_sol_dex_event_coverage_entries` avec `decoder_code = raydium_stable_swap`.
6. Utiliser Solscan seulement comme aide exploratoire ; si le filtre instruction échoue, utiliser Demo3 program_id + signatures récentes/non filtrées.
7. Backfill Demo2 signature/pool sur corpus varié.
8. Replay local avec :
```text
skipDexDecode = no
forceDexDecode = yes
deferInstructionObservations = yes
```
9. Vérifier :
```text
coverage listed/observed/materialized
residual instruction_audit
residual upstream_git.instruction_match
decoded without coverage entry
failed tx materialization = 0
non-trade trade_count = 0
single-target materialization
trade/candle only for swap events validés
decoded-only explanations
```
## SQL de contrôle minimal `0.7.52`
Coverage stable swap :
```sql
SELECT
entry_name,
entry_kind,
event_family,
expected_db_target,
proof_status,
local_event_kind,
discriminator_hex,
observed_count,
materialized_count,
trade_count
FROM k_sol_dex_event_coverage_entries
WHERE decoder_code = 'raydium_stable_swap'
ORDER BY entry_kind, entry_name, discriminator_hex;
```
Instruction observations :
```sql
SELECT
instruction_name,
discriminator_hex,
COUNT(*) AS observed_count,
COUNT(DISTINCT signature) AS tx_count
FROM k_sol_instruction_observations
WHERE decoder_code = 'raydium_stable_swap'
GROUP BY instruction_name, discriminator_hex
ORDER BY observed_count DESC, instruction_name, discriminator_hex;
```
Residual audit :
```sql
SELECT
json_extract(payload_json, '$.discriminatorHex') AS discriminator_hex,
COUNT(*) AS audit_count,
COUNT(DISTINCT transaction_id) AS tx_count
FROM k_sol_dex_decoded_events
WHERE protocol_name = 'raydium_stable_swap'
AND event_kind = 'raydium_stable_swap.instruction_audit'
GROUP BY discriminator_hex
ORDER BY audit_count DESC, discriminator_hex;
```
Fallback upstream :
```sql
SELECT
json_extract(ug.payload_json, '$.upstreamDecoderCode') AS upstream_decoder_code,
json_extract(ug.payload_json, '$.upstreamEntryName') AS entry_name,
json_extract(ug.payload_json, '$.upstreamDiscriminatorHex') AS discriminator_hex,
json_extract(ug.payload_json, '$.upstreamSourceRepo') AS source_repo,
COUNT(*) AS fallback_count,
COUNT(DISTINCT ug.transaction_id) AS tx_count
FROM k_sol_dex_decoded_events ug
JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = json_extract(ug.payload_json, '$.upstreamDecoderCode')
AND ce.entry_name = json_extract(ug.payload_json, '$.upstreamEntryName')
AND ce.discriminator_hex = json_extract(ug.payload_json, '$.upstreamDiscriminatorHex')
AND ce.local_event_kind IS NOT NULL
AND ce.local_event_kind <> ''
WHERE ug.protocol_name = 'upstream_git'
AND ug.event_kind = 'upstream_git.instruction_match'
AND json_extract(ug.payload_json, '$.upstreamDecoderCode') = 'raydium_stable_swap'
GROUP BY upstream_decoder_code, entry_name, discriminator_hex, source_repo
ORDER BY fallback_count DESC, entry_name;
```
Non-swap safety :
```sql
SELECT
de.event_kind,
ce.event_family,
COUNT(*) AS decoded_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_stable_swap'
AND ce.local_event_kind = de.event_kind
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
GROUP BY de.event_kind, ce.event_family
HAVING ce.event_family <> 'swap'
AND COUNT(te.id) > 0
ORDER BY trade_count DESC, de.event_kind;
```
Failed tx safety :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_failed_count,
COUNT(te.id) AS trade_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
AND tx.err_json IS NOT NULL
AND tx.err_json <> ''
AND tx.err_json <> 'null'
GROUP BY de.event_kind
HAVING COUNT(te.id) > 0
ORDER BY trade_count DESC, de.event_kind;
```
Decoded without coverage :
```sql
SELECT
de.event_kind,
COUNT(*) AS decoded_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_dex_event_coverage_entries ce
ON ce.decoder_code = 'raydium_stable_swap'
AND ce.local_event_kind = de.event_kind
WHERE de.protocol_name = 'raydium_stable_swap'
AND ce.id IS NULL
GROUP BY de.event_kind
ORDER BY decoded_count DESC, de.event_kind;
```
Multi-target materialization :
```sql
SELECT
de.event_kind,
COUNT(DISTINCT de.id) AS decoded_count,
COUNT(DISTINCT te.id) AS trade_count,
COUNT(DISTINCT le.id) AS liquidity_count,
COUNT(DISTINCT pe.id) AS lifecycle_count,
COUNT(DISTINCT fe.id) AS fee_count,
COUNT(DISTINCT ae.id) AS admin_count,
COUNT(DISTINCT oe.id) AS orderbook_count,
(
CASE WHEN COUNT(DISTINCT te.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT le.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT pe.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT fe.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT ae.id) > 0 THEN 1 ELSE 0 END
+ CASE WHEN COUNT(DISTINCT oe.id) > 0 THEN 1 ELSE 0 END
) AS materialized_target_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events pe
ON pe.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events ae
ON ae.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events oe
ON oe.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
GROUP BY de.event_kind
HAVING materialized_target_count > 1
ORDER BY materialized_target_count DESC, de.event_kind;
```
Unexplained successful non-materialized events :
```sql
SELECT
de.event_kind,
COUNT(*) AS unexplained_count
FROM k_sol_dex_decoded_events de
JOIN k_sol_chain_transactions tx
ON tx.id = de.transaction_id
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events pe
ON pe.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events ae
ON ae.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events oe
ON oe.decoded_event_id = de.id
LEFT JOIN k_sol_token_account_events tae
ON tae.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
AND (
tx.err_json IS NULL
OR tx.err_json = ''
OR tx.err_json = 'null'
)
AND te.id IS NULL
AND le.id IS NULL
AND pe.id IS NULL
AND fe.id IS NULL
AND ae.id IS NULL
AND oe.id IS NULL
AND tae.id IS NULL
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipTradeReason')), '') = ''
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipLiquidityReason')), '') = ''
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipLifecycleReason')), '') = ''
AND COALESCE(TRIM(json_extract(de.payload_json, '$.skipCatalogReason')), '') = ''
GROUP BY de.event_kind
ORDER BY unexplained_count DESC, de.event_kind;
```
Materialization summary :
```sql
SELECT
de.event_kind,
COUNT(DISTINCT de.id) AS decoded_count,
COUNT(DISTINCT te.id) AS trade_count,
COUNT(DISTINCT le.id) AS liquidity_count,
COUNT(DISTINCT pe.id) AS lifecycle_count,
COUNT(DISTINCT fe.id) AS fee_count,
COUNT(DISTINCT ae.id) AS admin_count,
COUNT(DISTINCT oe.id) AS orderbook_count
FROM k_sol_dex_decoded_events de
LEFT JOIN k_sol_trade_events te
ON te.decoded_event_id = de.id
LEFT JOIN k_sol_liquidity_events le
ON le.decoded_event_id = de.id
LEFT JOIN k_sol_pool_lifecycle_events pe
ON pe.decoded_event_id = de.id
LEFT JOIN k_sol_fee_events fe
ON fe.decoded_event_id = de.id
LEFT JOIN k_sol_pool_admin_events ae
ON ae.decoded_event_id = de.id
LEFT JOIN k_sol_orderbook_events oe
ON oe.decoded_event_id = de.id
WHERE de.protocol_name = 'raydium_stable_swap'
GROUP BY de.event_kind
ORDER BY de.event_kind;
```
## Livrables attendus
```text
archive delta fichiers modifiés/ajoutés
README.md / ROADMAP.md / CHANGELOG.md mis à jour
docs/DEX_DECODER_MATRIX.md
docs/DEX_EVENT_COVERAGE_MATRIX.md
docs/DB_EVENT_MODEL_REVIEW.md
docs/reports/RAYDIUM_STABLE_SWAP_EVENT_COVERAGE_REPORT.md
validation_sql/SQL_VALIDATION_RAYDIUM_STABLE_SWAP_0_7_52.sql
```
Validation finale locale :
```bash
cargo fmt
cargo test -p kb_lib
cargo clippy -p kb_lib --all-targets -- -D warnings
```
## Critères de clôture `0.7.52`
```text
tous les discriminants stable swap connus sont listés en coverage
tous les discriminants stable swap connus sont observés localement ou explicitement marqués mapped_unverified
instruction_audit résiduel vide pour les discriminants couverts
fallback upstream_git.instruction_match résiduel vide pour les discriminants couverts
decoded without coverage vide
non-swap -> trade vide
failed tx -> trade vide
multi-target materialization vide
successful decoded-only events expliqués par skip*Reason
trade/candle uniquement pour swaps avec montants fiables
deposit/withdraw uniquement vers liquidity
initialize/pre_initialize uniquement vers lifecycle
simulate/transport éventuel reste decoded-only sauf preuve métier
```