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