<!-- file: README.md -->

# khadhroony-bobobot


## État final validé `0.7.57` — `meteora_dlmm` full decode / full materialization

La tranche `0.7.57 meteora_dlmm` est clôturée côté decoder local maximal, coverage, tests synthétiques, matérialisation prudente et validation SQL sur base dédiée. Le programme traité est :

```text
LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo
```

Source IDL locale prioritaire :

```text
idls/meteora_dlmm.LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo.json
```

Surface couverte : `76` instructions IDL, `30` events Anchor et `12` accounts, avec correction locale du discriminant `75c73e67068e1fcb`, identifié comme `initialize_preset_parameter_v2` par les logs Anchor (`Instruction: InitializePresetParameterV2`) et par hash Anchor. Les entrées observées utiles ne restent pas en decoded-only : elles alimentent `trade`, `liquidity`, `lifecycle`, `fee`, `reward`, `admin` ou `orderbook` selon leur famille.

Validation locale finale rapportée :

```text
cargo test -p kb_lib -> 460 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
769 replayed
0 decode skipped
769 ledger upserts
646 unsafe ledger rows
106 trades
664 liquidity
1107 lifecycle
0 tokenAccount
424 candle upserts
instructionObservations = 8062
resetDeleted = 9898
catalog = 169 tokens / 218 pools / 218 pairs
```

Règles métier verrouillées :

- les trades/candles DLMM proviennent uniquement des instructions swap fiables : `swap`, `swap2`, `swap_exact_out`, `swap_exact_out2`, `swap_with_price_impact`, `swap_with_price_impact2` ;
- `swap_event` et `swap2_evt` sont matérialisés comme `swap_log` lifecycle afin d'éviter tout double comptage trade/candle ;
- les positions, bins, pool create, preset parameters, pair status, token badge et operator/config alimentent lifecycle/admin selon contexte ;
- les limit orders alimentent `k_sol_orderbook_events` et ne produisent jamais trade/candle ;
- les fees DLMM utilisent `k_sol_fee_events` + `k_sol_fee_event_amounts`, avec recovery strictement allowlistée depuis inner SPL transfers ;
- les rewards DLMM utilisent une recovery strictement allowlistée, sans inventer de montant pour les initialisations/configurations ;
- les transactions failed restent décodées/auditables mais ne matérialisent aucune table métier.

Synthèse fee/reward finale observée :

```text
claim_fee                  64 parents /  64 legs
claim_fee2                 63 parents /  88 legs
claim_fee_event           127 parents / 187 legs
claim_fee2_event           78 parents / 118 legs
composition_fee_event      51 parents /  63 legs
withdraw_protocol_fee      14 parents /  20 legs
zap_protocol_fee           13 parents /  13 legs
claim_reward               15 parents /   1 scalar amount
claim_reward2              19 parents /  10 scalar amounts
claim_reward_event         34 parents /  25 scalar amounts
claim_reward2_event        19 parents /  10 scalar amounts
fund_reward                10 parents /  10 scalar amounts
fund_reward_event          10 parents /  10 scalar amounts
initialize_reward           9 parents /   0 amount, attendu car init/config
initialize_reward_event     9 parents /   0 amount, attendu car init/config
```

Checks de fermeture `0.7.57` :

- fallback `upstream_git` `meteora_dlmm` pour entrées couvertes localement : vide ;
- `instruction_audit` observé : `0` ;
- decoded `meteora_dlmm` sans coverage : vide ;
- successful non-materialized sans `skip*Reason` ou policy explicite : vide ;
- failed transaction avec business materialization : vide ;
- multi-target materialization : vide ;
- non-swap vers trade/candle : vide ;
- parent fee scalaire sans leg : vide ;
- fee amount legs orphelins : vide ;
- limit/orderbook vers trade/candle : vide ;
- duplicate logical coverage rows : vide.

Écart coverage restant et expliqué : `close_bin_array` affiche `16 observed / 14 materialized`, car `14` transactions sont OK et matérialisées, tandis que `2` transactions failed (`Custom 6015`) restent audit-only.

Documents de référence :

```text
docs/reports/METEORA_DLMM_EVENT_COVERAGE_REPORT.md
docs/VALIDATION_STATUS_0_7_57_FINAL.md
validation_sql/SQL_VALIDATION_METEORA_DLMM_0_7_57.sql
docs/prompts/PROMPT_0_7_58_SQLITE_DB_TRANSACTION_MERGER_BINARY.md
docs/prompts/PROMPT_0_7_59_DEMO4_PROGRAM_SURFACE_DISCOVERY.md
docs/prompts/PROMPT_0_7_60_METEORA_DAMM_NEXT_DEX.md
```

Prochaine étape recommandée : `0.7.58 sqlite_db_transaction_merger`, un binaire de fusion de bases SQLite transactionnelles pour construire `final.db`/`final.next.db` et lancer des replays anti-régression cross-DEX Pump/Raydium/Meteora. `demo4 / program surface discovery` est déplacé en `0.7.59` et exploitera cette base consolidée sans matérialisation automatique ni promotion automatique.



## État final validé `0.7.56` — `meteora_dbc` + socle `fee_event_amounts`

La tranche `0.7.56 meteora_dbc` est clôturée côté decoder local maximal, coverage, tests synthétiques, matérialisation prudente et validation SQL sur base dédiée. Le programme traité est :

```text
dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN
```

Source IDL locale prioritaire :

```text
idls/meteora_dbc.dbcij3LWUppWqq96dh6gJWwBifmcGfLSB5D4DuSMaqN.json
```

Surface couverte : `28` instructions, `23` events Anchor, `9` accounts et `59` types. Les instructions `swap` et `swap2` sont les seules candidates trade/candle directes, uniquement lorsque les montants et les mints base/quote sont fiables. Les initialisations de virtual pool, migrations, lockers, metadata/config/operator et transferts de créateur alimentent les tables non-trade adaptées ou restent decoded-only avec raison explicite. Les transactions failed restent audit-only.

Validation locale finale rapportée :

```text
cargo test -p kb_lib -> 446 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
480 replayed
0 decode skipped
480 ledger upserts
454 unsafe ledger rows
264 trades
1 liquidity
122 lifecycle
0 tokenAccount
1056 candle upserts
instructionObservations = 7167
resetDeleted = 3583
catalog = 86 tokens / 60 pools / 60 pairs
```

Matérialisation DBC finale observée :

```text
claim_creator_trading_fee          8 parents /  8 scalar /  8 legs
claim_partner_pool_creation_fee   10 parents / 10 scalar / 10 legs
claim_protocol_fee                10 parents / 10 scalar / 10 legs
claim_protocol_pool_creation_fee  10 parents / 10 scalar / 10 legs
claim_trading_fee                 11 parents /  6 scalar / 18 legs
creator_withdraw_surplus           2 parents /  2 scalar /  2 legs
partner_withdraw_surplus           9 parents /  9 scalar /  9 legs
withdraw_leftover                 10 parents / 10 scalar / 10 legs
withdraw_migration_fee             9 parents /  9 scalar /  9 legs
zap_protocol_fee                  10 parents / 10 scalar / 10 legs
Total meteora_dbc                 89 fee parents / 96 amount legs
```

La tranche introduit le socle générique `k_sol_fee_event_amounts` :

- `k_sol_fee_events` reste l'événement fee parent ;
- `k_sol_fee_event_amounts` stocke les legs de montants, avec `fee_event_id`, `leg_index`, `token_mint`, `amount_raw`, comptes source/destination et `amount_source` ;
- tout parent fee avec `fee_token_mint + fee_amount_raw` crée automatiquement un leg scalaire ;
- les fees multi-mint/multi-leg laissent le parent sans montant scalaire et stockent les montants fiables dans les legs ;
- une recovery `allowlisted_inner_spl_transfer` existe pour les anciens DEX validés, mais aucun futur décodeur ne l'hérite par défaut ;
- tout futur décodeur doit déclarer explicitement sa policy de récupération des montants fee.

Checks de fermeture `0.7.56` :

- fallback `upstream_git` `meteora_dbc` pour entrées couvertes localement : vide ;
- decoded `meteora_dbc` sans coverage : vide ;
- successful non-materialized sans `skip*Reason` ou policy explicite : vide ;
- failed transaction avec business materialization : vide ;
- multi-target materialization : vide ;
- non-swap vers trade/candle : vide ;
- parent fee avec `fee_token_mint + fee_amount_raw` mais sans `k_sol_fee_event_amounts` : vide ;
- legs fee orphelins : vide ;
- recovery générique `allowlisted_inner_spl_transfer` non appliquée à `meteora_dbc`, qui reste couvert par ses chemins spécifiques.

Contrôles croisés réalisés sur anciennes bases : `raydium_launchpad`, `raydium_cpmm`, `pump_swap`, `pump_fees`, `pump_fun`, `raydium_amm_v4`, `raydium_clmm`, `raydium_stable_swap`. Les parents fees scalaires ont des legs ; les events sans transfert exploitable restent documentés par `fee_instruction_has_no_actual_transfer` ou `fee_instruction_has_only_zero_amount_transfers`.

Documents de référence :

```text
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
docs/prompts/PROMPT_0_7_57_METEORA_DLMM_FULL_DECODE_MATERIALIZATION.md
```

La tranche suivante `0.7.57 meteora_dlmm` est désormais clôturée. La prochaine étape recommandée est `0.7.58 sqlite_db_transaction_merger`, afin de construire `final.db`/`final.next.db` par merge de bases dédiées et de rejouer la base consolidée pour détecter les régressions cross-DEX. `0.7.59` est réservé à `demo4 / program surface discovery`.

## État final validé `0.7.55` — `pump_fees`

La tranche `0.7.55 pump_fees` est clôturée côté decoder local maximal, coverage, tests synthétiques, matérialisation prudente et validation SQL. Le programme `pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ` est traité comme surface fee/config/accounting : `get_fees` reste decoded-only, les claims social fee alimentent `k_sol_reward_events`, les donation/buyback alimentent `k_sol_fee_events`, les authority/config/tier/update alimentent `k_sol_pool_admin_events`, les créations/init/extend alimentent `k_sol_pool_lifecycle_events`, et aucun trade/candle direct n'est produit.

Source IDL locale prioritaire :

```text
idls/pump_fees.pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ.json
```

Surface couverte : `29` instructions, `20` events Anchor, `9` accounts et `34` types. Les discriminators Solscan hors IDL locale `revoke_fee_sharing_authority_event` (`7217653c0ebe993e`) et `transfer_fee_sharing_authority_event` (`7c8fc6f54db808ec`) restent conservés en coverage comme surfaces futures `upstream_git_mapped_unverified`.

Validation locale finale rapportée :

```text
cargo test -p kb_lib -> 431 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
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
```

Checks de fermeture Pump Fees :

- fallback `upstream_git` `pump_fees` : vide ;
- `instruction_name` `pump_fees` vide : vide ;
- `event_family = unknown` ou vide pour instruction/event : vide ;
- decoded `pump_fees` sans coverage : vide ;
- fallback résiduel pour entrées couvertes localement : vide ;
- successful non-materialized sans skip/policy : vide ;
- failed transaction avec business materialization : vide ;
- multi-target materialization : vide ;
- anti-trade/candle direct `pump_fees` : vide ;
- watchlist globale : plus aucun `pump_fees`, reste seulement `jupiter_swap.route_v2` observé ponctuellement.

Le SQL de validation propre et exécutable reste `validation_sql/SQL_VALIDATION_PUMP_FEES_0_7_55.sql`.

## État final validé `0.7.54` — `pump_fun`

La tranche `0.7.54 pump_fun` est clôturée côté coverage, décodage local maximal, matérialisation métier prudente et validation SQL. Elle ferme la surface Pump.fun principale avant l'ouverture de `0.7.55 pump_fees`.

Program id canonique :

```text
6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P
```

Source IDL locale prioritaire :

```text
idls/pump_fun.6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P.json
```

Points verrouillés :

- les `40` instructions et `23` events Anchor connus par l'IDL locale sont inventoriés et couverts localement ;
- les instructions IDL-only absentes du registre upstream initial sont intégrées côté coverage, notamment `buy_v2`, `sell_v2`, `buy_exact_quote_in_v2`, `migrate_v2`, `claim_cashback_v2`, `collect_creator_fee_v2`, `distribute_creator_fees_v2` et `update_buyback_config` ;
- `pump_fun.buy` et `pump_fun.sell` restent matérialisés directement comme trades quand les montants sont fiables ;
- `pump_fun.buy_exact_sol_in` est matérialisé directement, y compris pour les logs `Program data` Anchor tronqués quand les montants exacts sont extractibles ;
- `pump_fun.buy_v2`, `pump_fun.sell_v2` et `pump_fun.buy_exact_quote_in_v2` restent des instructions audit/coverage/routing : elles ne sont pas matérialisées directement ;
- la matérialisation canonique des trades v2/exact passe par `pump_fun.trade_event` quand l'event Anchor porte les montants exécutés et se corrèle sans ambiguïté à l'instruction ;
- les `trade_event` couverts par un trade direct reçoivent un skip explicite afin d'éviter le double-count ;
- les familles non-trade alimentent uniquement les tables prévues (`launch`, `fee`, `reward`, `admin`, `lifecycle`) ou restent decoded-only/audit-only avec raison explicite ;
- les transactions failed restent décodables pour audit mais ne produisent aucun business event.

Validation locale finale rapportée après replay forcé :

```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
```

Matérialisation Pump.fun finale observée :

```text
pump_fun.buy               17 trades
pump_fun.sell              25 trades
pump_fun.buy_exact_sol_in  15 trades
pump_fun.trade_event       25 trades
```

Checks de fermeture :

- fallback `upstream_git` Pump.fun : vide ;
- decoded Pump.fun sans coverage : vide ;
- fallback upstream résiduel pour entrées couvertes : vide ;
- successful non-materialized sans skip reason : vide ;
- failed transaction avec business materialization : vide ;
- multi-target materialization : vide ;
- trade candidates Pump.fun sans matérialisation ni skip : vide ;
- watchlist globale : plus aucun `pump_fun` ; la surface suivante `pump_fees` a été traitée en `0.7.55`.


## État final validé `0.7.53` — `pump_swap`

La tranche `0.7.53 pump_swap` est clôturée côté décodage transaction/log et matérialisation métier. Elle ferme le program id unique `pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA` sans rouvrir Raydium.

Points verrouillés :

- `pump_swap.buy` et `pump_swap.sell` restent matérialisés uniquement depuis montants exacts transaction/vault/balance-delta ;
- `pump_swap.buy_exact_quote_in` est matérialisable seulement lorsqu'un `BuyEvent` Anchor exact est présent (`amountSource=pump_swap_anchor_buy_event`) ; les cas `instruction_bounds_only` restent decoded-only avec raison explicite ;
- les events Anchor `*_event` sont décodés comme events autonomes audit-only, sauf exception explicitement matérialisable (`claim_token_incentives_event` si un corpus réussi apparaît) ;
- les transactions failed restent traçables mais non actionnables ;
- les non-trades PumpSwap alimentent uniquement les tables métier prévues (`liquidity`, `lifecycle`, `fee`, `reward`, `admin`) et ne créent jamais de trade/candle ;
- les tests synthétiques verrouillent les instructions/events IDL non observés dans le corpus local ;
- la surveillance globale distingue maintenant les vrais gaps locaux, le backlog `upstream_git` et les observations non attribuées.

Validation locale finale rapportée :

```text
cargo test -p kb_lib -> 421 passed / 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> OK
```

Dernier replay élargi rapporté après backfill pool :

```text
1189 replayed
0 decode skipped
1189 ledger upserts
967 unsafe ledger rows
928 trades
13 liquidity
8 lifecycle
0 tokenAccount
3700 candle upserts
instructionObservations = 25724
resetDeleted = 5622
catalog = 76 tokens / 80 pools / 80 pairs
```

Checks de fermeture :

- `pump_swap` decoded without coverage : vide ;
- fallback `upstream_git` PumpSwap couvert localement : vide ;
- successful trade candidates PumpSwap sans trade et sans raison explicite : vide ;
- failed transaction avec business trade : vide ;
- non-swap matérialisé en trade : vide ;
- multi-target materialization : vide ;
- Raydium AMM v4 / CLMM / CPMM targeted observation gaps : vide après normalisation.

Livrables `0.7.53` :

- `docs/reports/PUMP_SWAP_EVENT_COVERAGE_REPORT.md` ;
- `docs/reports/DEX_COVERAGE_GLOBAL_WATCHLIST_0_7_53.md` ;
- `validation_sql/SQL_VALIDATION_PUMP_SWAP_0_7_53.sql` ;
- `validation_sql/SQL_VALIDATION_DEX_COVERAGE_GLOBAL_0_7_53.sql` ;
- `idls/` comme corpus local d'IDL Solscan à comparer aux sources Git.

La suite immédiate après `0.7.54 pump_fun` est `pump_fees` (`0.7.55`). Les petits gaps Meteora restent volontairement reportés aux tranches Meteora futures.


## État final validé `0.7.51` — `raydium_amm_v4`

La tranche `0.7.51 raydium_amm_v4` est clôturable côté `kb_lib` après validation locale du decoder maximal AMM v4.

Points verrouillés :

- `raydium_amm_v4` est le code canonique local ;
- program id canonique : `675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8` ;
- tous les discriminants officiels AMM v4 `00..11` sont reconnus et observés localement ;
- les swaps sont spécialisés par discriminant : `swap_base_in`, `swap_base_out`, `swap_base_in_v2`, `swap_base_out_v2` ;
- le `event_kind` legacy `raydium_amm_v4.swap` est interdit et doit rester absent ;
- les discriminants AMM v4 sont indexés sur 1 octet, jamais comme discriminants Anchor 8 octets ;
- `pre_initialize` est conservé pour les scans historiques et matérialisé comme lifecycle audit minimal, sans création de pair exploitable ;
- `simulate_info` reste `decoded_events_only` ;
- `monitor_step`, `migrate_to_open_book` et `admin_cancel_orders` sont des side effects orderbook AMM v4 ;
- `raydium_pool_v4` reste une source d'audit/comparaison et ne devient pas un decoder autonome sans program id + corpus local.

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 :

```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
```

Livrables `0.7.51` :

- `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` ;
- `docs/VALIDATION_STATUS_0_7_51_FINAL.md`.


`khadhroony-bobobot` est un workspace Rust destiné à la détection, au décodage, à l’analyse et, à terme, au trading semi-automatisé de tokens Solana.

Ce document reflète le point de reprise `0.7.43-E5C` et l’état de consolidation atteint après `0.7.45` pour `meteora_dlmm`. La version Cargo a évolué ensuite à `0.7.46` côté workspace. Le lot Meteora initialement ouvert en bloc a été redécoupé : `meteora_dlmm` est traité séparément, puis la suite reprend `meteora_damm_v1`, `meteora_damm_v2` et `meteora_dbc` un par un.


## État courant finalisé `0.7.49`

La branche de travail `0.7.49` clôture la tranche `raydium_clmm` après la clôture fonctionnelle de `0.7.48 raydium_cpmm`. Le code Rust de `kb_lib` est considéré finalisé pour cette tranche, sous réserve des validations locales habituelles (`cargo fmt`, `cargo test -p kb_lib`, `cargo clippy -p kb_lib --all-targets -- -D warnings`).

État CLMM validé sur corpus local après replay forcé :

```text
listed_entry_count        = 45
decoded_entry_count       = 33
observed_entry_count      = 33
materialized_entry_count  = 25
total_observed_count      = 2560
total_materialized_count  = 1367
trade_count               = 1186
raydium_clmm.instruction_audit résiduel = 0
upstream_git.instruction_match localement couvert = 0
failed tx matérialisées = 0
non-swap CLMM avec trade_count > 0 = 0
```

Les 11 Anchor / `Program data` events CLMM restent listés en `upstream_git_unverified` car aucun corpus local ne les observe encore. Le code est préparé pour les accueillir en audit-only lorsqu’ils apparaîtront dans un corpus local, sans créer de trade/candle par défaut.

Les tranches `0.7.51 raydium_amm_v4` et `0.7.52 raydium_stable_swap` sont maintenant validées côté `kb_lib`. La suite de roadmap reprend avec les rechecks conditionnels et les surfaces restantes, tandis que `raydium_pool_v4` reste un audit conditionnel ultérieur et ne doit pas être promu sans confirmation de program id/rôle/corpus.

## Organisation documentaire

La racine conserve uniquement les documents de pilotage principaux :

- `README.md` ;
- `ROADMAP.md` ;
- `CHANGELOG.md`.

Les documents spécialisés sont rangés dans :

- `docs/` pour les matrices et revues de modèle ;
- `docs/reports/` pour les rapports de couverture DEX/version ;
- `docs/prompts/` pour les prompts de reprise ;
- `validation_sql/` pour les scripts SQL de validation.

Voir aussi :

- `docs/DEX_DECODER_MATRIX.md` pour la matrice DEX détaillée ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` pour la matrice de familles d’events ;
- `docs/DB_EVENT_MODEL_REVIEW.md` pour la revue du modèle DB ;
- `docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md` et `validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_48.sql` pour la clôture CPMM ;
- `docs/reports/RAYDIUM_CLMM_EVENT_COVERAGE_REPORT.md` et `validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_49.sql` pour la clôture CLMM ;
- `docs/prompts/PROMPT_REPRISE_khadhroony-bobobot_0.7.50-raydium-launchpad.md` pour reprendre en `0.7.50`.

## Sources upstream Git / IDL à utiliser en `0.7.47+`

Les sources externes ci-dessous sont des **indices de décodage**, pas des preuves métier. Elles servent à extraire des `program_id`, discriminants, IDL, layouts et noms d’instructions/events, mais toute promotion locale doit rester conditionnée à :

1. observation Demo3 ;
2. backfill Demo2 ;
3. replay local sur la base de travail ;
4. requêtes SQL de validation ;
5. invariants : aucun faux trade, aucune fausse candle, aucun `program_id` promu sans corpus.

Sources prioritaires :

| Source | Usage attendu |
|---|---|
| `idls/` | Corpus local d’IDL téléchargés depuis Solscan ; source de savoir locale à comparer aux sources Git avant promotion métier. |
| `https://github.com/sevenlabs-hq/carbon/tree/main/decoders` | Source principale de discriminants, instructions et events multi-protocoles. |
| `https://github.com/0xfnzero/solana-streamer` | Source complémentaire pour PumpFun, PumpSwap, Bonk et Raydium CPMM. |
| `https://github.com/0xfnzero/sol-parser-sdk/tree/main/idls` | IDL complémentaires pour programmes Solana supportés par parser SDK. |
| `https://github.com/pinax-network/substreams-solana-idls/tree/main/src` | IDL et layouts additionnels à comparer au registre local. |
| `https://github.com/hodlwarden/solana-tx-parser/tree/main/src` | Décodage transactionnel complémentaire et conventions de mapping. |
| `https://github.com/openbook-dex/openbook-v2` | Source officielle OpenBook v2 : programme, IDL et logs. |
| `https://github.com/all-in-one-blockchain/phoenix-onchain-mm` | Source Phoenix/MM complémentaire pour corpus et intégration. |
| `https://docs.vybenetwork.com/docs/available-dexs-amms` | Source de découverte de DEX/AMM supportés par Vybe, à traiter comme index externe non vérifié localement. |


## 1. Objectif

L’objectif opérationnel est de construire progressivement une application capable de :

- détecter l’apparition de nouveaux tokens, pools, paires et listings sur Solana ;
- identifier en priorité les DEX effectifs sur lesquels les swaps, liquidités et événements de marché sont réellement exécutés ;
- décoder les transactions pertinentes des DEX ciblés, puis seulement ensuite les launch surfaces et origines de mint/lancement ;
- séparer strictement les swaps/candles des événements utiles seulement à l’analyse : liquidité, cycle de vie de pool, fees, rewards, administration, wallet activity, mint/burn, migration ;
- produire des métriques exploitables : prix, volume, candles/OHLCV, activité, bursts, déséquilibres buy/sell, signaux analytiques ;
- préparer ensuite des règles déterministes de filtrage, d’achat, de vente, de stop-loss et de trailing stop ;
- conserver une traçabilité locale suffisante pour rejouer, diagnostiquer et améliorer les décodeurs sans retraiter inutilement toute la base.

Le but court terme n’est pas encore le live trading. Le but court terme est de fiabiliser le décodage multi-DEX, la matérialisation des objets métier nécessaires au trading et le mécanisme de replay incrémental.

## 2. Workspace

Le workspace contient deux crates principales.

| Crate | Rôle |
|---|---|
| `kb_lib` | Bibliothèque métier : configuration, tracing, clients réseau, pool HTTP, manager WS, résolution transactionnelle, décodage DEX, détection métier, persistance SQLite, backfill, metadata, candles, signaux analytiques, validation et diagnostics. |
| `kb_demo_app` | Application Tauri V2 de démonstration et d’inspection : fenêtres `Demo Ws`, `Demo Ws Manager`, `Demo Http`, `Demo Pipeline`, `Demo Pipeline 2`, `Demo3`, graphiques candles et commandes de backfill/replay. |

La logique métier doit rester dans `kb_lib`. `kb_demo_app` doit rester une façade UI/Tauri utilisée pour inspecter, backfiller et constituer du corpus on-chain ; elle ne doit pas récupérer de logique DEX profonde.

## 3. État actuel au point de reprise `0.7.43-E5C`

### 3.1. Socle stabilisé à ne pas refactorer maintenant

Ces éléments fonctionnent et ne sont pas bloquants pour les DEX. Ils ne doivent pas être remaniés dans la phase immédiate :

- `ws_client.rs` ;
- `ws_manager.rs` ;
- `http_client.rs` ;
- `http_pool.rs` ;
- couches JSON-RPC WS/HTTP déjà stabilisées ;
- orchestration réseau utilisée par les fenêtres de démonstration.

Ils pourront être améliorés plus tard, mais la priorité actuelle est le décodage DEX, les événements métier, les tables d’analyse et le replay incrémental.

### 3.2. Pipeline métier existant

Le pipeline `0.7.x` couvre déjà les étapes suivantes :

1. réception d’observations via RPC WS ou backfill HTTP ;
2. résolution des transactions via HTTP RPC ;
3. projection transactionnelle normalisée en base ;
4. décodage DEX dans `k_sol_dex_decoded_events` ;
5. détection métier vers tokens, pools, paires, listings, origins et wallets observés ;
6. matérialisation des trades exploitables ;
7. matérialisation partielle des événements non-trade prouvés ;
8. agrégation pair metrics ;
9. génération candles/OHLCV ;
10. signaux analytiques simples ;
11. inspection via l’application de démonstration.

### 3.3. Résultat local observé avant normalisation

Un corpus local de reprise contient notamment :

| Indicateur | Valeur observée |
|---|---:|
| transactions chain | `2956` |
| decoded events | `7159` |
| trade events | `2738` |
| liquidity events | `0` |
| pool lifecycle events | `1` |
| fee events | `0` |
| reward events | `0` |
| admin events | `0` |

Cette distribution montre que les swaps sont déjà fortement présents, mais que la matérialisation non-trade n’est pas encore homogène sur le corpus courant. Les nombreux `instruction_audit`, surtout côté Meteora, doivent devenir un axe de travail DEX par DEX.

### 3.4. Connecteurs validés ou observés via l’application de démo

Les surfaces suivantes existent dans le code, dans la matrice ou dans le corpus local. Leur niveau de preuve doit rester explicite.

| Code | Statut de travail | Commentaire |
|---|---|---|
| `pump_fun` | launch surface | Surface de launch / mint initial. À traiter après les DEX effectifs sauf besoin de migration. |
| `pump_swap` | DEX effectif | Swaps `buy` / `sell` observés. Non-trade à étendre plus tard. |
| `raydium_cpmm` | DEX effectif consolidé partiellement | Swaps et premiers events non-trade prouvés sur corpus antérieur. |
| `raydium_clmm` | DEX effectif consolidé partiellement | Swaps v2/legacy, positions et liquidity events prouvés sur corpus antérieur. |
| `raydium_amm_v4` | DEX effectif legacy | Swaps AMM v4 legacy matérialisés ; non-swaps legacy conservés en audit tant que le corpus ne permet pas une promotion fiable. |
| `meteora_dlmm` | DEX effectif consolidé en `0.7.45` | Swaps, Anchor CPI swap events, liquidity, positions, fees et lifecycle principaux validés par corpus local ; deux Anchor CPI audits résiduels `e8abf2613a4d232d` restent volontairement non mappés. |
| `meteora_damm_v1` | DEX effectif en consolidation `0.7.46` | Swaps présents ; decoder étendu aux create_pool, liquidity, claim_fee et lock events DAMM v1 mappés upstream Git/corpus local. Validation DB à rejouer sur base dédiée. |
| `meteora_damm_v2` | DEX effectif à reprendre séparément | Swaps et create_pool observés ; nombreux audits à traiter. |
| `meteora_dbc` | launch/bonding + DEX effectif partiel à reprendre séparément | Gros volume d’audits ; séparer bonding/launch, swap effectif et migration. |
| `orca_whirlpools` | DEX effectif à vérifier | À revalider par corpus dédié avant promotion. |
| `fluxbeam` | DEX effectif à vérifier | Program id, corpus et events à vérifier. |
| `dexlab` | DEX effectif à vérifier | Program id, corpus et events à vérifier. |
| `metaDAO` | candidat à vérifier | Aucun `program_id` ne doit être déclaré vérifié sans preuve/corpus. |
| `printr` | candidat à vérifier | Aucun `program_id` ne doit être déclaré vérifié sans preuve/corpus. |

### 3.5. Statuts de preuve obligatoires

Aucun `program_id`, DEX ou event ne doit être documenté comme vérifié sans preuve reproductible.

| Statut | Sens |
|---|---|
| `known` | Connu/listé dans le code, une doc, une source externe ou la matrice. |
| `observed` | Vu dans une transaction, une instruction, une base locale ou un corpus on-chain. |
| `decoded` | Un decoder produit un event structuré ou un `instruction_audit` classé. |
| `materialized` | L’event alimente une table métier dédiée : trade, liquidity, lifecycle, fee, reward, admin, mint/burn, etc. |
| `verified_by_corpus` | Validé par requêtes SQL, signatures/corpus reproductibles et invariants de validation. |

### 3.6. État validé de `meteora_dlmm` en `0.7.45`

La tranche `0.7.45` clôt la normalisation séparée de `meteora_dlmm` sur le corpus DLMM élargi constitué via `Demo3`, backfill par signatures anciennes et backfill par pool address.

Éléments validés :

| Famille | Events DLMM couverts |
|---|---|
| Swaps | `swap`, `swap2`, `swap_exact_out` lorsque présents, avec enrichissement `anchorSwapEvent` pour `Swap` / `Swap2Evt`. |
| Création / lifecycle | `create_pool`, `lb_pair_create_event`, `initialize_bin_array`, `initialize_position`. |
| Positions | `position_create_event`, `position_close_event`, `close_position_if_empty`. |
| Liquidité | `add_liquidity_event`, `add_liquidity_by_strategy2`, `add_liquidity_by_weight`, `remove_liquidity_event`, `remove_liquidity`, `remove_liquidity_by_range2`. |
| Fees | `claim_fee_event`, `claim_fee2`. |
| Rewards | Décodeurs Anchor CPI présents pour `claim_reward_event` / `fund_reward_event`, mais non observés dans le corpus final `0.7.45`. |

Validation locale finale sur la base DLMM dédiée :

| Indicateur | Valeur observée |
|---|---:|
| transactions rejouées | `3027` |
| trades matérialisés | `530` |
| liquidity events matérialisés | `15` |
| lifecycle events matérialisés | `6` |
| candles upsert | `2120` |
| audits DLMM résiduels | `2` |

Les deux audits restants sont `e445a52e51cb9a1d + e8abf2613a4d232d`. Ils restent en `meteora_dlmm.instruction_audit`, car aucun mapping upstream Git/IDL suffisamment fiable n’a été confirmé. Ils ne bloquent pas la clôture de `0.7.45`.

### 3.7. État de travail de `meteora_damm_v1` en `0.7.46`

La tranche `0.7.46` étend `meteora_damm_v1` à partir du mapping upstream Git decoder source `meteora-pools-decoder` et des discriminants observés dans le corpus local. Les events ajoutés couvrent `create_pool`, `add_liquidity`, `remove_liquidity`, `claim_fee`, `create_lock_escrow` et `lock_liquidity`.

La version logique du replay local devient `dex_decode.v0.7.46.damm_v1_events1`, ce qui force le redécodage des transactions certifiées sous la version `0.7.45` pour vérifier les nouveaux events DAMM v1.

Meteora Vault est traité prudemment : le programme associé peut apparaître comme compte dans les instructions DAMM v1, mais aucun decoder `meteora_vault` ni statut `verified_by_corpus` n’est ajouté sans corpus direct séparé.

Demo3 dispose ensuite d’une correction ciblée pour la découverte `meteora_damm_v1` : les discriminants DAMM v1 connus sont classés directement côté recherche on-chain, le filtrage `target_event` est strict sur les surfaces explicites, et les transactions mixtes ne sont plus éliminées globalement quand une cible précise est demandée. Cela sert à alimenter les backfills par signature ou par pool dans Demo Pipeline 2 sans déplacer de logique métier profonde dans `kb_demo_app`.


## 4. Matrice DEX : priorité révisée

À partir du point de reprise `0.7.43-E5C`, la priorité est :

1. **DEX effectifs actuels** : programmes où les swaps, pools, liquidités, positions, fees, rewards, admin/config, burns/mints ou migrations sont réellement exécutés ;
2. **launch surfaces** : surfaces de mint, bonding, launchpad, migration ou origine ;
3. **DEX historiques / legacy / faibles priorités** : programmes anciens, peu observés, ou uniquement utiles à la compatibilité/replay historique.

Chaque DEX ou variante de DEX doit avoir sa propre étape de validation. Les familles larges restent utiles pour la navigation, mais le travail de décodage doit être fait par version/protocole : `raydium_cpmm`, `raydium_clmm`, `raydium_amm_v4`, `meteora_dlmm`, `meteora_damm_v1`, `meteora_damm_v2`, `meteora_dbc`, etc.

### 4.1. Ordre de travail DEX effectifs

| Priorité | Code cible | Rôle | Action prochaine |
|---:|---|---|---|
| 1 | `pump_swap` | AMM / swap | Maintenir les invariants swaps et chercher les non-trade prouvés. |
| 2 | `raydium_cpmm` | AMM | Garder consolidé ; ne rouvrir que sur nouveaux discriminators/corpus. |
| 3 | `raydium_clmm` | CLMM | Garder consolidé ; ne rouvrir que sur nouveaux discriminators/corpus. |
| 4 | `raydium_amm_v4` | AMM legacy actif | Garder swaps ; ne promouvoir les non-swaps qu’avec corpus. |
| 5 | `meteora_dlmm` | DLMM | Reprendre séparément : swaps, liquidity, positions, lifecycle, fees/rewards/admin. |
| 6 | `meteora_damm_v1` | AMM | Reprendre séparément : swaps exploitables, pools, liquidity, fees/admin. |
| 7 | `meteora_damm_v2` | AMM | Reprendre séparément : create_pool, swaps exploitables, configs dynamiques, non-trade. |
| 8 | `meteora_dbc` | bonding / DEX effectif partiel | Reprendre séparément : swap effectif, bonding curve, migration, launch attribution. |
| 9 | `orca_whirlpools` | CLMM | Revalider par corpus dédié. |
| 10 | `fluxbeam` | AMM | Vérifier program id, events et corpus. |
| 11 | `dexlab` | AMM | Vérifier program id, events et corpus. |
| 12 | `metaDAO` | candidat DEX | Vérifier par corpus avant toute promotion. |
| 13 | `printr` | candidat DEX | Vérifier par corpus avant toute promotion. |

### 4.2. Launch surfaces reportées

À reprendre après les DEX effectifs, sauf si une surface est indispensable pour comprendre une migration vers un pool tradable :

- `pump_fun` ;
- `raydium_launchpad` ;
- `letsbonk` / `bonk_fun` ;
- `bags` ;
- `moonshot` ;
- `moonit` ;
- `boop_fun` ;
- `believe` ;
- `heaven` ;
- autres launch origins découvertes par corpus.

### 4.3. DEX historiques ou faibles priorités

À garder dans la matrice mais sans bloquer les versions immédiates :

- `raydium_stable_swap` est désormais démontré par corpus local en `0.7.52` ; le garder comme DEX effectif supporté, avec surveillance des nouveaux discriminants ;
- vieux programmes legacy uniquement utiles pour compatibilité ou replay historique ;
- agrégateurs/routeurs comme `okx_dex` tant qu’ils ne correspondent pas à un DEX direct matérialisable ;
- entrées ambiguës comme `zora` tant qu’aucun programme Solana pertinent n’est prouvé.

## 5. Base de données et replay incrémental

SQLite reste le stockage local initial. Le fichier `config.json` peut pointer vers une base différente pour travailler par corpus, par DEX ou sur base vierge. Le schéma est créé au lancement via les `CREATE TABLE IF NOT EXISTS` existants.

Organisation actuelle à conserver :

- `kb_lib/src/db/schema.rs` crée les tables et index ;
- chaque table/index est créée dans une fonction dédiée ;
- les requêtes sont sous `kb_lib/src/db/queries/` ;
- les entités persistées sont sous `kb_lib/src/db/entities/` ;
- les DTO applicatifs sont sous `kb_lib/src/db/dtos/`.

### 5.1. Tables existantes importantes

Le modèle actuel contient déjà notamment :

- `k_sol_chain_transactions` ;
- `k_sol_chain_instructions` ;
- `k_sol_dexes` ;
- `k_sol_dex_decoded_events` ;
- `k_sol_tokens` ;
- `k_sol_pools` ;
- `k_sol_pairs` ;
- `k_sol_pool_tokens` ;
- `k_sol_trade_events` ;
- `k_sol_liquidity_events` ;
- `k_sol_pool_lifecycle_events` ;
- `k_sol_fee_events` ;
- `k_sol_reward_events` ;
- `k_sol_pool_admin_events` ;
- `k_sol_token_mint_events` ;
- `k_sol_token_burn_events` ;
- `k_sol_transaction_classifications` ;
- `k_sol_protocol_candidates`.

### 5.2. Ledger de décodage/replay implémenté en `0.7.44`

Le replay local dispose maintenant de la table `k_sol_dex_decode_replay_ledger`. Elle permet de ne pas relancer l’étape `DexDecodeService` lorsqu’une transaction a déjà été décodée avec certitude pour la même version logique de decoder. Les étapes de détection, matérialisation non-trade, trades, candles et classifications restent rejouées afin de reconstruire les tables dérivées après reset.

Objectifs maintenus :

- mémoriser qu’une transaction/instruction a déjà été traitée par un decoder donné ;
- stocker le statut de décodage : certain, partiel, inconnu, erreur, non-actionnable, multi-token ambigu ;
- associer le résultat au `decoder_code` et à une version logique de decoder ;
- permettre un mode `force` qui ignore le ledger ;
- permettre un mode de reprise ciblé lorsque le decoder change ;
- ne pas skipper automatiquement les transactions multi-token, multi-pool ou multi-event ambiguës ;
- conserver les failed transactions comme traçables mais non actionnables.

Table actuelle :

- `k_sol_dex_decode_replay_ledger`.

Champs principaux :

| Champ conceptuel | Rôle |
|---|---|
| `transaction_id` / `signature` | rattachement transactionnel stable |
| `decoder_scope` | périmètre logique du decoder, actuellement `dex_decode.local_pipeline` |
| `decoder_version` | version logique du decoder |
| `decode_status` | `decoded` ou `no_events` dans la première implémentation |
| `certainty` | `sure` ou `unsafe` |
| `event_count` | nombre total d’events persistés |
| `distinct_token_mint_count` | garde-fou multi-token |
| `force_replay_required` | indique que le décodage doit être relancé |
| `status_reason` | diagnostic lisible sans panic |
| `created_at` / `updated_at` | audit local |

## 6. Politique de replay

Règles cibles :

- par défaut, ne pas retraiter une instruction dont le ledger indique un décodage certain avec le même decoder/version et la même entrée ;
- retraiter si `force = true` ;
- retraiter si le decoder concerné change de version logique ;
- retraiter si la transaction contient plusieurs tokens/pools/events et que le ledger la classe comme ambiguë ou partielle ;
- retraiter si un event précédemment `instruction_audit` devient décodable par un nouveau decoder ;
- ne jamais créer de faux trade/candle pour un event dont les montants ne sont pas fiables ;
- conserver les audits utiles pour améliorer les decoders.

## 7. Contraintes de code

Contraintes maintenues :

- 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)]` dans les racines concernées ;
- pas de `anyhow` ;
- pas de `thiserror` ;
- pas de `?`, `unwrap`, `expect` dans le code applicatif de `kb_lib` ;
- `kb_demo_app` peut rester plus souple tant qu’elle reste une application de démonstration ;
- usage privilégié de `match`, `if let Err`, `let Err = ... else` dans `kb_lib` ;
- imports externes limités, sauf traits lorsque nécessaire ;
- tests unitaires et tests de replay maintenus.

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` si la surface publique l’exige.

## 8. Priorité immédiate

La priorité immédiate après la clôture `0.7.55 pump_fees` est la suivante :

1. reprendre `0.7.57 meteora_dlmm` sur une base SQLite neuve ;
2. décoder toutes les instructions/events DBC connus par l'IDL locale et les sources Git ;
3. matérialiser uniquement ce qui est prouvable : launch/bonding, swaps fiables, migration, liquidity, fees/admin/config ;
4. ne créer aucun trade/candle DBC sans montants, sens économique, pool/pair et mints fiables ;
5. maintenir les checks Pump.fun/PumpSwap/Pump Fees/Raydium en non-régression ;
6. garder `jupiter_swap.route_v2` en watchlist résiduelle sans ouvrir Jupiter avant phasage dédié.

Garde-fous constants :

- pas de faux trade ;
- pas de fausse candle ;
- pas de `program_id` fictif ;
- pas de promotion d’un DEX sans corpus transactionnel ;
- pas de logique métier DEX profonde dans `kb_demo_app` ;
- pas de metadata manquante bloquante ;
- pas de refactor réseau inutile tant que les clients HTTP/WS existants suffisent.

## 9. Fichiers utiles pour reprendre dans une nouvelle session

Pour reprendre rapidement le codage dans une nouvelle session, fournir au minimum :

- `README.md` ;
- `ROADMAP.md` ;
- `CHANGELOG.md` ;
- `Cargo.toml` racine ;
- `clippy.toml` ;
- `config.json` ;
- `kb_lib/Cargo.toml` ;
- `kb_lib/src/lib.rs` ;
- `kb_lib/src/constants.rs` ;
- `kb_lib/src/dex.rs` ;
- `kb_lib/src/dex/*.rs` ;
- `kb_lib/src/dex_decode.rs` ;
- `kb_lib/src/dex_detect.rs` ;
- `kb_lib/src/dex_support_matrix.rs` ;
- `kb_lib/src/dex_event_classification.rs` ;
- `kb_lib/src/non_trade_event_materialization.rs` ;
- `kb_lib/src/trade_aggregation.rs` ;
- `kb_lib/src/pair_candle_aggregation.rs` ;
- `kb_lib/src/local_pipeline_replay.rs` ;
- `kb_lib/src/local_pipeline_validation.rs` ;
- `kb_lib/src/local_pipeline_diagnostics.rs` ;
- `kb_lib/src/onchain_dex_pair_discovery.rs` ;
- `kb_lib/src/db/schema.rs` ;
- `kb_lib/src/db.rs` ;
- `kb_lib/src/db/entities.rs` et `kb_lib/src/db/entities/*` ;
- `kb_lib/src/db/dtos.rs` et `kb_lib/src/db/dtos/*` ;
- `kb_lib/src/db/queries.rs` et `kb_lib/src/db/queries/*`.

Ajouter `kb_demo_app/src/demo_pipeline*.rs`, `kb_demo_app/src/demo3.rs`, les fichiers frontend associés et les nouvelles démos seulement si la tâche concerne l’UI, la recherche de corpus, les diagnostics affichés ou le watcher temps réel.


### Demo3 multi-target discovery

Demo3 can search several event surfaces in one on-chain scan by checking multiple target event boxes. Internally this uses the existing `targetEvent` field with comma-separated normalized values, preserving compatibility with older single-target calls.


### Demo3 paged / multi-source discovery

Demo3 can now scan one or several source addresses in a single on-chain discovery run. Source addresses may be pools, vaults, positions, config accounts or mints; the program id remains an instruction filter and no discovered address is promoted as verified automatically.

The on-chain discovery form supports Solana `getSignaturesForAddress` pagination through `beforeSignature`, `untilSignature`, `maxPages` and `scanOrder`. `newest_first` preserves Solana RPC order. `oldest_first` reverses the fetched window after paging, which is useful when enough pages have been fetched to include the creation-side history of a pool. The JSON result includes `nextBeforeByAddress` cursor hints for subsequent manual windows.


### Note 0.7.46 DAMM v1 upstream Git coverage

La couverture `meteora_damm_v1` inclut désormais les surfaces upstream Git decoder source `meteora-pools-decoder` connues. Les surfaces non rencontrées dans le corpus local restent marquées `upstream_git_mapped_unverified` et doivent être validées par Demo3 + backfill + replay avant d’être considérées comme corpus-confirmed.

Sur le corpus local élargi, `swap`, `add_balance_liquidity`, `remove_balance_liquidity`, `claim_fee`, `create_lock_escrow`, `lock`, `InitializePermissionlessConstantProductPoolWithConfig` et `InitializePermissionlessConstantProductPoolWithConfig2` sont marqués `upstream_git_local_corpus_observed`.


### Note 0.7.47 Upstream Git Registry / DEX discovery preparation

La version `0.7.47` n’est plus dédiée à un seul DEX. Elle doit introduire un registre upstream Git générique pour les `program_id`, discriminants d’instructions, discriminants d’events, noms d’instructions et familles de programmes issus de dépôts Git externes de decoders Solana.

Les entrées de ce registre sont des indices de découverte, pas des preuves métier. Elles doivent être marquées `upstream_git_unverified` ou `upstream_git_mapped_unverified` tant qu’elles ne sont pas confirmées par Demo3, backfill, replay local et requêtes SQL.

Le registre sert à accélérer la constitution de corpus pour les DEX et surfaces suivantes : Meteora DAMM v2/DBC/Vault, Raydium Launchpad/Stable/Locking, Orca Whirlpools, FluxBeam, DexLab, Lifinity AMM v2, Phoenix/OpenBook, Stabble, BonkSwap, Boop, Moonshot, Heaven, Wavebreak, Vertigo, Virtuals, Pancake Swap, OKX DEX, Jupiter/Kamino/Drift et autres programmes utiles à la découverte.


## Note 0.7.47-1FE5 — Event coverage et modèle DB

La matrice DEX/version doit être complétée par une matrice événementielle exhaustive. Le projet ne vise pas seulement les swaps : les events `burn`, `mint`, `transfer`, `account_close`, `lock/unlock`, `vault_deposit/withdraw`, `admin/config`, `order_fill`, `settle_funds`, `launch` et `migration` peuvent influencer une décision de trading.

Voir :

- `docs/DEX_DECODER_MATRIX.md` pour le statut par DEX/version ;
- `docs/DEX_EVENT_COVERAGE_MATRIX.md` pour les familles d'events à couvrir ;
- `docs/DB_EVENT_MODEL_REVIEW.md` pour les ajouts DB à envisager avant `0.7.48+`.


## Note 0.7.48-pre — Event coverage DB checkpoint

La micro-tranche `0.7.48-pre` introduit la persistance de couverture événementielle avant la reprise DEX par DEX.

Ajouts côté `kb_lib` :

- table `k_sol_dex_event_coverage_entries` ;
- entity, DTO et requêtes dédiées ;
- service `DexEventCoverageService` pour synchroniser les entrées du registre upstream Git vers SQLite ;
- refresh des compteurs locaux depuis `k_sol_dex_decoded_events` et les tables déjà existantes de matérialisation non-trade / trade ;
- exposition des summaries de coverage dans les diagnostics locaux ;
- ajout du profil de validation `0.7.48-pre_event_coverage_db_checkpoint`, qui synchronise le registre upstream avant validation ;
- le profil `0.7.48-pre` garde les invariants globaux de non-régression, mais borne le contrôle bloquant des trade candidates non matérialisés aux DEX Raydium attendus pour éviter qu’un DEX partiel hors scope bloque le checkpoint DB ;
- sélection du profil `0.7.48-pre` dans Demo Pipeline 2.

Cette tranche ne modifie pas les decoders DEX, ne crée aucun trade/candle, et ne promeut aucun `program_id` comme vérifié. Elle sert uniquement à objectiver la couverture : `listed`, `decoded/audit`, `observed`, `materialized`, `trade_count` et statut de preuve.

La suite fonctionnelle reprend par Raydium avant Meteora :

1. `0.7.48` — `raydium_cpmm` ;
2. `0.7.49` — `raydium_clmm` ;
3. `0.7.50-pre-r2` — `raydium_launchpad` + clôture CPMM/CLMM ;
4. `0.7.51` — `raydium_amm_v4` ;
5. `0.7.52` — `raydium_stable_swap` — clôturé ;
6. `0.7.53` — `pump_swap` — clôturé ;
7. `0.7.54` — `pump_fun` ;
8. `0.7.55` — `pump_fees` — clôturé ;
9. `0.7.56` — `meteora_dbc` ;
10. `0.7.57+` — Meteora restants, routers/agrégateurs, Phoenix/OpenBook, Orca puis les autres DEX/surfaces.

`raydium_pool_v4.json` reste repoussé en audit conditionnel tardif, pas une tranche bloquante.

## Note 0.7.48 — Raydium CPMM event coverage

La tranche `0.7.48` reprend `raydium_cpmm` avant Meteora, en s'appuyant sur la table `k_sol_dex_event_coverage_entries` ajoutée en `0.7.48-pre`.

Le scope CPMM couvre désormais les entrées Carbon/fnzero/IDL suivantes : `close_permission_pda`, `collect_creator_fee`, `collect_fund_fee`, `collect_protocol_fee`, `create_amm_config`, `create_permission_pda`, `deposit`, `initialize`, `initialize_with_permission`, `lp_change_event`, `swap_base_input`, `swap_base_output`, `swap_event`, `update_amm_config`, `update_pool_status` et `withdraw`.

Le decoder local spécialisé remplace le fallback `upstream_git.instruction_match` pour les instructions CPMM couvertes localement. Les events Anchor self-CPI `lp_change_event` et `swap_event` sont décodés comme preuve audit/coverage, mais ne produisent pas directement `trade_events`, metrics ou candles. Les swaps matérialisables restent les chemins instruction-scoped `swap_base_input` et `swap_base_output` lorsque les montants et le sens économique sont exploitables.

Aucune nouvelle table DB n'est ajoutée en `0.7.48`. Les transfers, token account lifecycle, vaults, orderbook, launch/migration et locking restent documentés comme familles transversales futures, à promouvoir seulement après preuve multi-DEX.

Voir aussi :

- `docs/DEX_EVENT_COVERAGE_MATRIX.md` pour la couverture par familles ;
- `docs/reports/RAYDIUM_CPMM_EVENT_COVERAGE_REPORT.md` pour le rapport de tranche ;
- `validation_sql/SQL_VALIDATION_RAYDIUM_CPMM_0_7_48.sql` pour les requêtes de validation.

Complément `0.7.48-raydium-cpmm-program-data` : la coverage DB est maintenant synchronisée automatiquement quand un refresh de coverage est demandé sur une base neuve et qu'aucune ligne n'existe encore. Les backfills token/pool/signature déclenchent aussi un refresh best-effort de la coverage afin d'éviter un état incohérent où `k_sol_dex_decoded_events` est rempli mais `k_sol_dex_event_coverage_entries` reste vide.

Le decoder CPMM lit désormais les events `Program data:` émis par le programme Raydium CPMM. Les layouts `lp_change_event` et `swap_event` sont décodés depuis le payload event direct, en plus du chemin Anchor self-CPI `e445a52e51cb9a1d + event_discriminator`. `swap_event` reste `tradeCandidate=false` / `candleCandidate=false` : les seuls trades CPMM matérialisables restent `swap_base_input` et `swap_base_output`. `lp_change_event` peut alimenter la matérialisation liquidity si le corpus fournit un pool/pair fiable et si `changeType` distingue dépôt/retrait.



### Note 0.7.48-part2-fix2 — Raydium CPMM coverage finalization

La tranche CPMM reconnaît désormais tous les discriminants instruction-level listés par Carbon / Raydium CP-Swap côté classificateur local. `lp_change_event` est traité comme famille bidirectionnelle `liquidity`, avec sens add/remove résolu par `changeType`, et le refresh coverage est confirmé après replay local sans validation séparée.

## Note 0.7.48 final — Raydium CPMM clôturable

La tranche `0.7.48` clôture la couverture Raydium CPMM sur corpus local. Les entrées `deposit`, `withdraw` et `lp_change_event` matérialisent `k_sol_liquidity_events` sans créer de trade/candle ; `initialize` et `initialize_with_permission` matérialisent seulement `k_sol_pool_lifecycle_events` ; les fees matérialisent `k_sol_fee_events` ; les entrées admin/config observées matérialisent `k_sol_pool_admin_events`.

La table technique `k_sol_instruction_observations` est ajoutée pour indexer localement les instructions observées par `decoder_code`, `instruction_name` et `discriminator_hex`. Demo3 peut rechercher par instruction/discriminant, ce qui reproduit localement l’usage pratique du filtre Solscan `instruction=<discriminator>`.

État final CPMM observé : `561` trades, `50` liquidity events, `9` lifecycle events, `25/25` `lp_change_event` matérialisés, `swap_event` audit-only à `0` trade, et deux entrées connues mais non observées (`close_permission_pda`, `update_pool_status`) conservées en `upstream_git_mapped_unverified`.

## Note 0.7.49 — Raydium CLMM event coverage final

La tranche `0.7.49` clôture `raydium_clmm` comme deuxième tranche Raydium après CPMM. Elle ajoute la couverture complète des instructions CLMM observées depuis Carbon, IDL Raydium, Pinax, fnzero et corpus Solscan/backfill, ainsi que la table transversale `k_sol_orderbook_events` pour les instructions limit-order.

Points finalisés :

- `45` entrées listées dans `k_sol_dex_event_coverage_entries` ;
- `33` instructions CLMM avec `local_event_kind` spécialisé ;
- `33` instructions observées dans le corpus local ;
- `25` entrées matérialisées ;
- swaps matérialisés uniquement via `swap` / `swap_v2` ;
- limit orders `open`, `increase`, `decrease`, `close`, `settle` décodés et matérialisés en `k_sol_orderbook_events` quand la transaction réussit ;
- non-trades CLMM vers `liquidity`, `fee`, `reward`, `admin`, `lifecycle` et `orderbook` sans trade/candle ;
- transactions échouées conservées audit-only ;
- `raydium_clmm.instruction_audit` résiduel à zéro ;
- `upstream_git.instruction_match` localement couvert à zéro après replay ;
- 11 Anchor / `Program data` events CLMM préparés mais conservés `upstream_git_unverified` faute d’observation locale.

La validation finale est dans `validation_sql/SQL_VALIDATION_RAYDIUM_CLMM_0_7_49.sql`.



## Note 0.7.50 — Raydium Launchpad event coverage bootstrap

La tranche `0.7.50` ouvre `raydium_launchpad` comme troisième tranche Raydium après CPMM et CLMM. Le code local canonique est `raydium_launchpad`. Le program id canonique est `LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj`.

Points préparés dans le bootstrap :

- normalisation des entrées launch surface, DEX support matrix, catalogue et registre upstream vers `raydium_launchpad` ;
- ajout de `RAYDIUM_LAUNCHPAD_PROGRAM_ID` ;
- inventaire initial de `1` entrée programme et `26` entrées discriminées Carbon/IDL ;
- fallback `raydium_launchpad.instruction_audit` pour les instructions non mappées, avec enrichissement Anchor self-CPI (`e445a52e51cb9a1d`) ;
- mapping conservatoire des discriminants Launchpad vers `raydium_launchpad.<entry_name>` ;
- cible coverage initiale forcée à `decoded_events_only`, y compris pour buy/sell/trade/migration, afin d'éviter toute fausse trade/candle avant corpus local ;
- rapport `docs/reports/RAYDIUM_LAUNCHPAD_EVENT_COVERAGE_REPORT.md` ;
- SQL `validation_sql/SQL_VALIDATION_RAYDIUM_LAUNCHPAD_0_7_50.sql`.
- pre3 : Demo3 contient le preset `Raydium Launchpad`; les `initialize*` Launchpad peuvent créer le catalogue pool/pair local, tandis que `trade_event` reste non promu en trade/candle.

`raydium_pool_v4.json` reste un indice IDL annexe. Il n'est pas promu en surface métier tant que son program id, son rôle exact et un corpus local exploitable ne sont pas confirmés.


## Note 0.7.50-pre-r2 — CPMM/CLMM closure re-check

Cette tranche complète la clôture Raydium en ajoutant `cpi_event` pour CPMM/CLMM, `update_dynamic_fee_config` pour CLMM, le rattachement local des Program-data events CLMM et la table `k_sol_token_account_events` pour `create_support_mint_associated`.

Le discriminant CPMM `40f4bc78a7e9690a` est désormais codé comme `raydium_cpmm.anchor_idl_instruction` : les signatures inspectées correspondent aux instructions Anchor `IdlCreateAccount` / `IdlCloseAccount`, donc il reste `decoded_events_only` et ne matérialise aucune table métier.

Rapport de clôture : `docs/reports/RAYDIUM_CPMM_CLMM_RECHECK_REPORT_0_7_50_PRE_R2.md`.
## Tranche clôturée — 0.7.52 raydium_stable_swap

`0.7.52` clôture Raydium Stable Swap avec le code local canonique `raydium_stable_swap` et le program id `5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h`.

Décisions finales :

- Stable Swap est décodé en layout legacy **1 octet**.
- La surface locale observée `00..0d` est couverte : lifecycle, model setup, admin/config, liquidity, orderbook side effects, fees et swaps.
- `swap_base_in` / `swap_base_out` produisent trades/candles uniquement avec des montants exacts dérivés des deltas de vaults (`amountSource=stable_swap_vault_balance_delta`).
- Les arguments d’instruction `amountInRaw`, `minimumAmountOutRaw`, `maxAmountInRaw`, `amountOutRaw` sont conservés comme bornes d’instruction, mais ne sont pas utilisés comme prix/montants exacts.
- Les transactions failed restent decoded-only avec `skipTradeReason=failed_transaction` et `skipCandleReason=failed_transaction`.

Livrables de clôture :

- `kb_lib/src/dex/raydium_stable_swap.rs`
- `docs/reports/RAYDIUM_STABLE_SWAP_EVENT_COVERAGE_REPORT.md`
- `validation_sql/SQL_VALIDATION_RAYDIUM_STABLE_SWAP_0_7_52.sql`

Validation locale finale :

```text
cargo test -p kb_lib -> 407 passed, 0 failed
cargo clippy -p kb_lib --all-targets -- -D warnings -> ok
```

Replay final observé :

```text
replayed=298, trades=290, liquidity=16, lifecycle=4, candle_upserts=1160,
instructionObservations=5317, catalog=40 tokens / 59 pools / 59 pairs
```

Statut : **clôturé côté code et validation locale**.
