v0.1.0-pre.056
This commit is contained in:
@@ -1,561 +1,337 @@
|
||||
# Khadhroony Bot3 — Checklist de clôture de la migration
|
||||
|
||||
> **Périmètre :** clôturer la migration de `khadhroony-bot2` vers `khadhroony-bot3`, stabiliser `kb-app-demo-desktop` et valider l’intégration des crates consolidées.
|
||||
>
|
||||
> **Base de suivi :** `0.1.0-pre.055` et correctifs suivants.
|
||||
>
|
||||
> **Règle d’utilisation :** cocher chaque case uniquement après validation locale explicite. Les sous-cases constituent les critères d’acceptation de la tâche parente.
|
||||
|
||||
---
|
||||
|
||||
## 0. État validé à ce jour
|
||||
|
||||
- [x] Les fenêtres historiques principales ont été portées dans `kb-app-demo-desktop`.
|
||||
- [x] Les décodeurs, modèles, matérialiseurs et exécuteurs sont consommés depuis `kb-lib`.
|
||||
- [x] `kb-store-core` et `kb-store-pg` ont été fusionnés dans `kb-store`.
|
||||
- [x] `kb-program-ids` est une dépendance explicite du desktop.
|
||||
- [x] `kb-pipeline-demo-scenarios` est une dépendance explicite du desktop.
|
||||
- [x] Le pool WebSocket n’est plus initialisé au démarrage de l’application.
|
||||
- [x] Le pool WebSocket est créé paresseusement à l’ouverture/utilisation de `demo_ws`.
|
||||
- [x] La session WebSocket survit à la fermeture de la fenêtre `demo_ws`.
|
||||
- [x] La réouverture de `demo_ws` récupère l’état de la session existante.
|
||||
- [x] La clé `HELIUS_API_KEY` chargée depuis `.env` permet une connexion Helius réelle.
|
||||
- [x] Les fenêtres dynamiques sont déclarées dans `vite.config.ts` et `capabilities/default.json`, sans être ajoutées à `tauri.conf.json`.
|
||||
- [x] La permission de logging est attribuée aux fenêtres dynamiques.
|
||||
- [x] Les balises HTML mal imbriquées qui rechargeaient `main.html` ont été corrigées.
|
||||
- [x] Les routes de fichiers de logs consolidées produisent une arborescence cohérente.
|
||||
- [x] L’audit Rust global est propre sur la base testée :
|
||||
- `General Rust rule audit: clean`
|
||||
- `Rust export completeness audit: 0 candidate(s)`
|
||||
- `Khadhroony workspace rule audit: clean`
|
||||
|
||||
---
|
||||
|
||||
## 1. Corriger immédiatement les deux afficheurs non JSON
|
||||
|
||||
### 1.1 Fenêtre HTTP JSON-RPC
|
||||
|
||||
- [ ] Remplacer le `@andypf/json-viewer` du bloc **Résultat** par un `<textarea readonly>`.
|
||||
- [ ] Conserver le résultat RPC sous sa forme textuelle exacte, sans supposer qu’il s’agit toujours de JSON.
|
||||
- [ ] Ajouter exactement un bouton **Copier** utilisant le presse-papiers.
|
||||
- [ ] Ajouter exactement un bouton **Effacer**.
|
||||
- [ ] S’assurer que l’effacement vide également le buffer TypeScript interne.
|
||||
- [ ] Donner au textarea une hauteur fixe et un scroll interne.
|
||||
- [ ] Tester successivement :
|
||||
- réponse JSON structurée ;
|
||||
- valeur scalaire ;
|
||||
- chaîne simple ;
|
||||
- erreur RPC ;
|
||||
- résultat vide.
|
||||
|
||||
### 1.2 Fenêtre WebSocket
|
||||
|
||||
- [ ] Remplacer le `@andypf/json-viewer` du bloc **Messages** par un `<textarea readonly>`.
|
||||
- [ ] Conserver les messages sous forme de journal texte append-only.
|
||||
- [ ] Ajouter exactement un bouton **Copier**.
|
||||
- [ ] Ajouter exactement un bouton **Effacer**.
|
||||
- [ ] S’assurer que l’effacement vide le buffer en mémoire et le contenu visible.
|
||||
- [ ] Donner au textarea une hauteur fixe et un scroll interne.
|
||||
- [ ] Vérifier que la réouverture de la fenêtre restaure :
|
||||
- l’état de connexion ;
|
||||
- les abonnements actifs ;
|
||||
- le statut de session ;
|
||||
- le journal conservé, si cette conservation est voulue.
|
||||
|
||||
---
|
||||
|
||||
## 2. Audit global des composants Copier / Effacer
|
||||
|
||||
- [ ] Rechercher tous les boutons statiques et boutons injectés dynamiquement :
|
||||
|
||||
```bash
|
||||
find kb-app-demo-desktop/frontend \
|
||||
-type f \( -name '*.html' -o -name '*.ts' \) -print0 |
|
||||
xargs -0 grep -nE 'Copier|Effacer|clipboard|app-log-clear|attach.*controls'
|
||||
```
|
||||
|
||||
- [ ] Pour chaque bloc de journal ou résultat textuel, garantir **une seule** paire Copier/Effacer.
|
||||
- [ ] Interdire la coexistence de boutons HTML statiques et de boutons ajoutés par `frontend_log.ts` sur le même composant.
|
||||
- [ ] Vérifier au minimum :
|
||||
- `demo_backfill` ;
|
||||
- `demo_core_extraction` ;
|
||||
- `demo_http` ;
|
||||
- `demo_ws` ;
|
||||
- `demo_decode_replay` ;
|
||||
- `demo_execution_solana_core` ;
|
||||
- `demo_execution_spl` ;
|
||||
- fenêtres SQL ;
|
||||
- configuration.
|
||||
- [ ] Ajouter un test frontend ou une vérification statique qui échoue lorsqu’un conteneur reçoit plusieurs groupes de contrôles.
|
||||
|
||||
---
|
||||
|
||||
## 3. Uniformiser la position des journaux généraux
|
||||
|
||||
- [x] Le journal du Backfill HTTP est placé hors de l’accordéon.
|
||||
- [x] Le journal d’Extraction core est placé hors de l’accordéon.
|
||||
- [ ] Vérifier que tous les journaux généraux restent visibles lorsque les sections de paramètres sont repliées.
|
||||
- [ ] Déplacer hors des accordéons tout journal général encore imbriqué dans une section de paramètres.
|
||||
- [ ] Conserver dans les accordéons uniquement les sorties strictement liées à une opération ou à un sous-panneau particulier.
|
||||
- [ ] Documenter une règle UI :
|
||||
- paramètres et formulaires dans les accordéons ;
|
||||
- journal global et résultat principal sous l’accordéon ;
|
||||
- hauteur fixe avec scroll ;
|
||||
- une seule paire Copier/Effacer.
|
||||
|
||||
---
|
||||
|
||||
## 4. Politique JSON commune
|
||||
|
||||
- [ ] Utiliser `@andypf/json-viewer` uniquement lorsque la valeur affichée est garantie comme JSON.
|
||||
- [ ] Utiliser un textarea readonly pour :
|
||||
- journaux ;
|
||||
- flux de messages ;
|
||||
- texte brut ;
|
||||
- réponses dont le format varie ;
|
||||
- erreurs non structurées.
|
||||
- [ ] Centraliser la création et la mise à jour des viewers JSON dans un helper TypeScript commun.
|
||||
- [ ] Appliquer une hauteur fixe à tous les viewers JSON.
|
||||
- [ ] Appliquer un scroll interne au-delà de la hauteur maximale.
|
||||
- [ ] Éviter qu’un collapse contenant du JSON agrandisse indéfiniment `.card-body`.
|
||||
- [ ] Vérifier tous les viewers présents dans :
|
||||
- Configuration ;
|
||||
- SQL diagnostics ;
|
||||
- Decode replay ;
|
||||
- exécutions ;
|
||||
- autres vues structurées.
|
||||
- [ ] Prévoir une règle pour les valeurs JSON invalides : fallback texte, sans crash de la fenêtre.
|
||||
|
||||
---
|
||||
|
||||
## 5. Stabiliser les fenêtres SQL
|
||||
|
||||
### 5.1 Layout
|
||||
|
||||
- [ ] Restaurer une disposition pleine largeur pour :
|
||||
- SQL diagnostics ;
|
||||
- PostgreSQL raw ;
|
||||
- PostgreSQL core.
|
||||
- [ ] Ne pas splitter les tableaux principaux en deux colonnes.
|
||||
- [ ] Réserver les colonnes uniquement aux petits panneaux synthétiques si nécessaire.
|
||||
- [ ] Supprimer le scroll horizontal global de la page.
|
||||
- [ ] Autoriser un scroll horizontal local uniquement dans `.table-responsive` lorsque réellement nécessaire.
|
||||
- [ ] Vérifier que le listing des tables utilise toute la largeur disponible.
|
||||
- [ ] Comparer le rendu avec Bot2 pour éviter une régression fonctionnelle ou ergonomique.
|
||||
|
||||
### 5.2 Navigation et IPC
|
||||
|
||||
- [x] Les balises de navbar mal fermées ont été corrigées.
|
||||
- [ ] Vérifier chaque bouton et chaque onglet des quatre fenêtres SQL.
|
||||
- [ ] Confirmer qu’aucune action ne recharge `main.html`.
|
||||
- [ ] Confirmer qu’aucun clic ne déclenche une navigation implicite via un `<a>` parent.
|
||||
- [ ] Vérifier les formulaires et boutons sans `type="button"` susceptibles de soumettre un formulaire.
|
||||
- [ ] Revalider les appels IPC lors de rechargements Vite, sans considérer l’ancien défaut comme actif s’il n’est plus reproductible.
|
||||
|
||||
### 5.3 Initialisation PostgreSQL
|
||||
|
||||
- [ ] Décider définitivement quand exécuter `initialize_postgres_schema_for_startup` :
|
||||
- au démarrage avec compte rendu dans le splash ; ou
|
||||
- à la première ouverture d’une fenêtre SQL.
|
||||
- [ ] Supprimer le code mort si l’initialisation de démarrage est abandonnée.
|
||||
- [ ] Sinon, brancher réellement :
|
||||
- `initialize_postgres_schema_for_startup` ;
|
||||
- `emit_sql_startup_table_report` ;
|
||||
- `emit_sql_startup_error` ;
|
||||
- `emit_sql_startup_splash`.
|
||||
- [ ] Ne pas conserver durablement des helpers publics ou `pub(crate)` inutilisés.
|
||||
- [ ] Ajouter des tests de schéma présent, incomplet et inaccessible.
|
||||
|
||||
---
|
||||
|
||||
## 6. Corriger les échecs Metaplex Token Metadata
|
||||
|
||||
### 6.1 Constat issu des logs `pre.055`
|
||||
|
||||
- [x] Le pipeline sélectionne correctement le décodeur `metadata_metaplex_token_metadata`.
|
||||
- [x] Le programme canonique est reconnu :
|
||||
|
||||
```text
|
||||
metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s
|
||||
```
|
||||
|
||||
- [x] L’archive analysée contient **10 échecs** explicites de validation de comptes :
|
||||
- **8** `create_metadata_account_v3 account 1 has invalid signer/writable flags` ;
|
||||
- **2** `transfer account 1 has invalid signer/writable flags`.
|
||||
|
||||
### 6.2 Diagnostic à effectuer
|
||||
|
||||
- [ ] Extraire pour chaque transaction échouée :
|
||||
- signature ;
|
||||
- slot ;
|
||||
- chemin d’instruction ;
|
||||
- instruction outer/inner ;
|
||||
- données brutes ;
|
||||
- liste ordonnée des comptes ;
|
||||
- flags signer/writable réellement reconstruits.
|
||||
- [ ] Vérifier si `account 1` désigne :
|
||||
- l’index dans les comptes de l’instruction ;
|
||||
- l’index global du message ;
|
||||
- un index décalé par le program ID ;
|
||||
- un compte issu d’une Address Lookup Table.
|
||||
- [ ] Vérifier la reconstruction des flags pour :
|
||||
- comptes statiques ;
|
||||
- comptes chargés par ALT ;
|
||||
- instructions internes ;
|
||||
- comptes dupliqués ;
|
||||
- invocation CPI.
|
||||
- [ ] Comparer les contrats du décodeur avec :
|
||||
- l’IDL officiel `token_metadata.json` ;
|
||||
- les builders/generated instructions Metaplex ;
|
||||
- des transactions mainnet réelles.
|
||||
- [ ] Vérifier si les contraintes imposées sont trop strictes pour les CPI, notamment lorsqu’un programme appelant transmet un compte avec des privilèges supérieurs ou différents.
|
||||
- [ ] Distinguer clairement :
|
||||
- compte absent ;
|
||||
- nombre de comptes invalide ;
|
||||
- signer manquant ;
|
||||
- writable manquant ;
|
||||
- privilège supplémentaire acceptable ;
|
||||
- privilège incompatible.
|
||||
|
||||
### 6.3 Correctif et tests
|
||||
|
||||
- [ ] Corriger la matrice de comptes de `create_metadata_account_v3`.
|
||||
- [ ] Corriger la matrice de comptes de `transfer`.
|
||||
- [ ] Ajouter les transactions réelles de l’archive comme fixtures bornées ou vecteurs synthétiques équivalents.
|
||||
- [ ] Ajouter un test de CPI pour chaque instruction concernée.
|
||||
- [ ] Ajouter un test avec Address Lookup Table si applicable.
|
||||
- [ ] Ajouter un test où un compte possède un privilège supérieur acceptable.
|
||||
- [ ] Ajouter un test qui refuse réellement un signer/writable manquant.
|
||||
- [ ] Rejouer les signatures échouées avec `forceReplay=true`.
|
||||
- [ ] Obtenir `failed=0` pour les cas désormais supportés.
|
||||
- [ ] Classer en `Unsupported` plutôt qu’en `Failed` toute variante volontairement hors périmètre mais valide sur chaîne.
|
||||
- [ ] Vérifier la matérialisation après correction du décodage.
|
||||
|
||||
### 6.4 Observabilité du décodeur
|
||||
|
||||
- [ ] Enrichir le diagnostic avec :
|
||||
- nom du rôle attendu ;
|
||||
- index du compte ;
|
||||
- pubkey ;
|
||||
- flags attendus ;
|
||||
- flags observés ;
|
||||
- contexte outer/inner.
|
||||
- [ ] Afficher ces diagnostics dans la fenêtre Decode replay.
|
||||
- [ ] Ajouter un bouton Copier pour les diagnostics détaillés.
|
||||
- [ ] Ne pas exposer de données sensibles dans les logs.
|
||||
|
||||
---
|
||||
|
||||
## 7. IDL Metaplex Token Metadata
|
||||
|
||||
- [ ] Placer le snapshot officiel dans le workspace :
|
||||
|
||||
```text
|
||||
idls/metaplex_token_metadata.metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s.json
|
||||
```
|
||||
|
||||
- [ ] Conserver le fichier source/provenance associé.
|
||||
- [ ] Documenter :
|
||||
- URL officielle ;
|
||||
- commit ou SHA du blob ;
|
||||
- version IDL `1.14.0` ;
|
||||
- program ID canonique.
|
||||
- [ ] Ajouter un script de rafraîchissement déterministe.
|
||||
- [ ] Ajouter un test vérifiant que l’IDL est du JSON valide.
|
||||
- [ ] Ajouter un test comparant les discriminants couverts par le décodeur avec l’IDL.
|
||||
- [ ] Ne pas utiliser l’IDL comme seule source normative lorsque le programme ou les generated builders divergent.
|
||||
|
||||
---
|
||||
|
||||
## 8. Configuration `.env` et ordre de résolution
|
||||
|
||||
### 8.1 `kb-config`
|
||||
|
||||
- [x] `dotenvy` appartient à `kb-config`, pas au desktop.
|
||||
- [ ] Vérifier l’API publique finale et ses noms.
|
||||
- [ ] Appliquer et tester l’ordre :
|
||||
1. environnement déjà présent dans le processus ;
|
||||
2. fichier explicitement indiqué par `KB_ENV_FILE` ;
|
||||
3. `.env` à la racine du workspace ;
|
||||
4. fallback `${VAR:-fallback}` ;
|
||||
5. variable non résolue conservée ou erreur selon le contrat du champ.
|
||||
- [ ] Garantir qu’un `.env` ne remplace jamais une variable déjà injectée par le shell, systemd, Docker, CI ou IDE.
|
||||
- [ ] Définir le comportement si `KB_ENV_FILE` pointe vers un fichier absent.
|
||||
- [ ] Définir le comportement si `.env` est absent.
|
||||
- [ ] Définir le comportement des lignes invalides.
|
||||
- [ ] Interdire l’impression de valeurs secrètes dans les diagnostics.
|
||||
- [ ] Ajouter des tests isolés et sérialisés pour éviter les collisions d’environnement global entre tests.
|
||||
|
||||
### 8.2 `kb-app-demo-desktop`
|
||||
|
||||
- [ ] Retirer toute lecture ou tout chargement `.env` résiduel du desktop.
|
||||
- [ ] Ne conserver que l’appel à l’API de chargement de `kb-config`.
|
||||
- [ ] Afficher dans la fenêtre Configuration la provenance des sources sans afficher les secrets :
|
||||
- environnement processus ;
|
||||
- fichier `.env` chargé ;
|
||||
- fallback ;
|
||||
- non résolu.
|
||||
- [ ] Vérifier que l’application démarre sans clé Helius.
|
||||
- [ ] Vérifier que l’utilisation d’un endpoint Helius sans clé produit une erreur ciblée.
|
||||
- [x] Vérifier qu’une clé valide dans `.env` permet HTTP et WebSocket Helius.
|
||||
|
||||
### 8.3 `kb-pipeline-demo-scenarios`
|
||||
|
||||
- [ ] Ne pas dépendre directement de `dotenvy`.
|
||||
- [ ] Centraliser l’initialisation par `kb-config` lorsque les scénarios sont lancés directement.
|
||||
- [ ] Réduire progressivement les appels directs `std::env::var`.
|
||||
- [ ] Introduire des structures typées pour :
|
||||
- SPL Token classique ;
|
||||
- ATA ;
|
||||
- Token-2022 ;
|
||||
- ElGamal Registry ;
|
||||
- scénarios Solana Core.
|
||||
- [ ] Permettre l’injection des valeurs dans les tests sans modifier l’environnement global.
|
||||
- [ ] Vérifier que les variables externes historiques `TOKEN_2022_*` peuvent rester nommées ainsi, tout en utilisant `token2022` dans les modules Rust internes.
|
||||
|
||||
### 8.4 Tâche ultérieure `kb-store`
|
||||
|
||||
- [ ] **À reporter :** décider si les chemins/URLs de base sont entièrement résolus par `kb-config` avant construction de `kb-store`.
|
||||
- [ ] Ne pas faire charger `.env` directement par `kb-store`.
|
||||
- [ ] Prévoir une configuration typée déjà résolue pour PostgreSQL et les futures bases.
|
||||
- [ ] Étudier la séparation future des targets de logs `kb-store.core` et `kb-store.postgres`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Cycle de vie WebSocket
|
||||
|
||||
- [x] Aucun pool WebSocket au démarrage général.
|
||||
- [x] Création paresseuse lors du premier accès.
|
||||
- [x] Pool conservé dans `AppState`.
|
||||
- [x] Fermeture de `demo_ws` sans fermeture de la session.
|
||||
- [x] Récupération du statut à la réouverture.
|
||||
- [ ] Utiliser `disconnect_demo_ws_app_state` lors de la fermeture globale de l’application.
|
||||
- [ ] Ne pas l’appeler lors de la simple destruction de `demo_ws`.
|
||||
- [ ] Tester la fermeture explicite depuis la fenêtre.
|
||||
- [ ] Tester le timeout de session.
|
||||
- [ ] Tester la fermeture de l’application avec session et abonnements actifs.
|
||||
- [ ] Vérifier qu’aucune tâche Tokio ni relay ne reste suspendu après arrêt.
|
||||
- [ ] Éliminer le warning `dead_code` de façon fonctionnelle, sans supprimer le hook requis.
|
||||
|
||||
---
|
||||
|
||||
## 10. Menu principal et cohérence visuelle
|
||||
|
||||
- [ ] Réordonner définitivement le dropdown des fenêtres selon les groupes suivants :
|
||||
1. Configuration ;
|
||||
2. Transport : HTTP, WebSocket, Backfill ;
|
||||
3. Pipeline : Extraction core, Decode replay ;
|
||||
4. SQL : diagnostics, raw, core, replay ;
|
||||
5. Exécution : Solana Core, SPL.
|
||||
- [ ] Ajouter des séparateurs ou titres de groupes non cliquables.
|
||||
- [ ] Vérifier que chaque fenêtre possède le logo non cliquable.
|
||||
- [ ] Vérifier particulièrement `demo_execution_solana_core`.
|
||||
- [ ] Garder les descriptions longues dans le contenu principal et non dans la navbar.
|
||||
- [ ] Vérifier les deux textes :
|
||||
- « System Program uniquement — simulation-first et replay post-exécution » ;
|
||||
- « Memo, SPL Token classique, Token-2022 et ATA — simulation-first et replay post-exécution ».
|
||||
- [ ] Uniformiser titres, sous-titres, marges et hauteurs de navbar.
|
||||
|
||||
---
|
||||
|
||||
## 11. Vérifier les options de la fenêtre Exécution SPL
|
||||
|
||||
- [ ] Auditer toutes les valeurs de `demo_execution_spl.html`.
|
||||
- [ ] Vérifier leur correspondance exacte avec les parsers et enums Rust.
|
||||
- [ ] Remplacer les valeurs internes historiques `token_2022` par `token2022` lorsqu’elles ne constituent pas un contrat externe.
|
||||
- [ ] Conserver uniquement les variables d’environnement externes `TOKEN_2022_*` si elles sont déjà documentées et utilisées.
|
||||
- [ ] Vérifier chaque scénario :
|
||||
- Memo v4 ;
|
||||
- SPL Token classique ;
|
||||
- Token-2022 ;
|
||||
- ATA.
|
||||
- [ ] Vérifier que Memo v1 et v3 restent non exécutables.
|
||||
- [ ] Vérifier les scénarios publics Token-2022 réellement supportés par l’exécuteur.
|
||||
- [ ] Retirer ou désactiver toute option UI sans implémentation réelle.
|
||||
- [ ] Ajouter un test qui compare la liste HTML/TypeScript avec l’inventaire Rust exposé.
|
||||
|
||||
---
|
||||
|
||||
## 12. Façades consolidées et nomenclature
|
||||
|
||||
- [ ] Exécuter une recherche uniquement sur les fichiers Rust :
|
||||
|
||||
```bash
|
||||
find kb-app-demo-desktop -type f -name '*.rs' -print0 |
|
||||
xargs -0 grep -nE 'kb_store_pg|kb_store_core|kb_model|kb_decoder_|kb_materializer_|kb_executor_|token_2022|_2022'
|
||||
```
|
||||
|
||||
- [ ] Aucun ancien crate Bot2 ne doit subsister.
|
||||
- [ ] Tous les modèles, décodeurs, matérialiseurs et exécuteurs doivent passer par `kb-lib`.
|
||||
- [ ] Tout le stockage doit passer par `kb-store`.
|
||||
- [ ] Les modules Rust internes utilisent `token2022`, jamais `token_2022`.
|
||||
- [ ] Les constantes utilisent `SPL_TOKEN2022_*` selon la nomenclature de `kb-program-ids`.
|
||||
- [ ] Les variables d’environnement externes `TOKEN_2022_*` peuvent rester.
|
||||
- [ ] Vérifier tous les `export_to` uniquement dans les `.rs` :
|
||||
|
||||
```bash
|
||||
find kb-config kb-lib kb-app-demo-desktop \
|
||||
-type f -name '*.rs' -print0 |
|
||||
xargs -0 grep -n 'export_to'
|
||||
```
|
||||
|
||||
- [ ] Corriger les chemins TS-RS résiduels qui imitent des anciens noms de crates.
|
||||
- [ ] Supprimer les fichiers de bindings orphelins générés par les anciens chemins.
|
||||
|
||||
---
|
||||
|
||||
## 13. Logging
|
||||
|
||||
- [x] La sortie console compacte est de nouveau active.
|
||||
- [x] Les routes consolidées produisent une arborescence cohérente.
|
||||
- [ ] Vérifier la console pour chaque profil configuré.
|
||||
- [ ] Vérifier qu’aucune route n’utilise un ancien target Bot2.
|
||||
- [ ] Vérifier l’absence de dossiers vides créés pour des targets inexistants.
|
||||
- [ ] Ajouter un test de complétude des routes par rapport aux targets publics actuels.
|
||||
- [ ] Vérifier la cohérence tiret/underscore entre target et répertoire.
|
||||
- [ ] Décider ultérieurement si `kb-store` doit produire :
|
||||
- `kb-store/core` ;
|
||||
- `kb-store/postgres`.
|
||||
- [ ] Ne pas traiter cette séparation comme bloquante pour la clôture de la migration.
|
||||
|
||||
---
|
||||
|
||||
## 14. Nettoyage des warnings Rust
|
||||
|
||||
- [ ] Résoudre le warning `DemoDecodeReplayProgressPayload` inutilisé par un usage réel ou un ajustement de visibilité justifié.
|
||||
- [ ] Résoudre le warning `initialize_postgres_schema_for_startup` inutilisé après décision sur l’initialisation SQL.
|
||||
- [ ] Résoudre le warning `disconnect_demo_ws_app_state` inutilisé en le branchant sur l’arrêt global.
|
||||
- [ ] Résoudre les helpers SQL privés inutilisés en les utilisant ou en les supprimant si le flux est abandonné.
|
||||
- [ ] Ne pas supprimer une fonction prévue uniquement pour faire taire un warning sans décision architecturale.
|
||||
- [ ] Obtenir `cargo test -p kb-app-demo-desktop` sans warning propre au code applicatif.
|
||||
|
||||
---
|
||||
|
||||
## 15. Clippy et macros Tauri
|
||||
|
||||
- [ ] Traiter en dernier les erreurs `clippy::question_mark_used` provenant des expansions `#[tauri::command]` async.
|
||||
- [ ] Confirmer qu’aucun `?` interdit n’existe dans le code source métier.
|
||||
- [ ] Choisir une solution localisée et documentée :
|
||||
- allowance au niveau du module adaptateur Tauri ; ou
|
||||
- configuration ciblée pour le code généré ; ou
|
||||
- exception d’audit explicite pour les macros externes.
|
||||
- [ ] Ne pas rendre les commandes synchrones uniquement pour satisfaire Clippy.
|
||||
- [ ] Ne pas désactiver le lint à l’échelle du workspace.
|
||||
- [ ] Ajouter une note dans `RUST_RULES.md` expliquant l’exception du code généré Tauri.
|
||||
- [ ] Obtenir finalement :
|
||||
|
||||
```bash
|
||||
cargo clippy --all-targets
|
||||
```
|
||||
|
||||
sans erreur.
|
||||
|
||||
---
|
||||
|
||||
## 16. Validation fonctionnelle de chaque fenêtre
|
||||
|
||||
- [ ] Splash : affiche uniquement les composants réellement initialisés au démarrage, puis est détruit.
|
||||
- [ ] Main : menu ordonné, tous les liens fonctionnels.
|
||||
- [ ] Configuration : viewers JSON bornés, provenance de configuration lisible, secrets masqués.
|
||||
- [ ] HTTP : méthodes, paramètres, résultat texte, Copier/Effacer.
|
||||
- [ ] WebSocket : connexion, abonnements multiples, restauration, messages texte, déconnexion.
|
||||
- [ ] Backfill : anciens/nouveaux historiques, annulation, journal permanent, résultat.
|
||||
- [ ] SQL diagnostics : pleine largeur, refresh, erreurs.
|
||||
- [ ] SQL raw : pleine largeur, tables et compteurs.
|
||||
- [ ] SQL core : pleine largeur, tables et compteurs.
|
||||
- [ ] SQL replay : filtres, DataTables, CSV, onglets.
|
||||
- [ ] Extraction core : campagne, annulation, journal permanent.
|
||||
- [ ] Decode replay : 7 décodeurs, matérialiseurs, diagnostics, annotations.
|
||||
- [ ] Exécution Solana Core : simulation, envoi contrôlé, replay post-exécution.
|
||||
- [ ] Exécution SPL : Memo v4, Token, Token-2022, ATA.
|
||||
- [ ] Fermeture et réouverture répétées de toutes les fenêtres dynamiques.
|
||||
- [ ] Vérification qu’aucune fenêtre dynamique ne démarre automatiquement.
|
||||
|
||||
---
|
||||
|
||||
## 17. Tests de scénarios hors Tauri
|
||||
|
||||
- [ ] Déplacer ou dupliquer les scénarios métier importants dans `kb-pipeline-demo-scenarios`.
|
||||
- [ ] Couvrir Solana Core.
|
||||
- [ ] Couvrir Memo v4.
|
||||
- [ ] Couvrir SPL Token classique.
|
||||
- [ ] Couvrir ATA.
|
||||
- [ ] Couvrir Token-2022.
|
||||
- [ ] Couvrir ElGamal Registry lorsque validable.
|
||||
- [ ] Couvrir Metaplex Token Metadata.
|
||||
- [ ] Tester sans démarrer Tauri.
|
||||
- [ ] Tester avec configurations injectées plutôt qu’avec environnement global lorsque possible.
|
||||
|
||||
---
|
||||
|
||||
## 18. Sécurité des secrets et fichiers locaux
|
||||
|
||||
- [ ] Vérifier que `.env` est ignoré par Git.
|
||||
- [ ] Conserver `.env.example` versionné sans secret.
|
||||
- [ ] Vérifier l’historique Git pour s’assurer qu’aucune clé Helius réelle n’a été ajoutée.
|
||||
- [ ] Masquer les valeurs sensibles dans les logs et dans la fenêtre Configuration.
|
||||
- [ ] Ne jamais inclure `.env` dans les archives delta.
|
||||
- [ ] Ajouter une validation de démarrage qui signale la présence/absence d’une clé sans l’afficher.
|
||||
|
||||
---
|
||||
|
||||
## 19. Validation technique finale
|
||||
|
||||
- [ ] `cargo fmt --all`
|
||||
- [ ] `cargo check -p kb-config`
|
||||
- [ ] `cargo test -p kb-config`
|
||||
- [ ] `cargo check -p kb-pipeline-demo-scenarios`
|
||||
- [ ] `cargo test -p kb-pipeline-demo-scenarios`
|
||||
- [ ] `cargo check -p kb-app-demo-desktop`
|
||||
- [ ] `cargo test -p kb-app-demo-desktop`
|
||||
- [ ] `cargo check --workspace`
|
||||
- [ ] `cargo test --workspace`
|
||||
- [ ] `python3 scripts/audit_rust_workspace_rules.py`
|
||||
- [ ] `cargo clippy --all-targets` après traitement de l’exception Tauri.
|
||||
- [ ] `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`
|
||||
- [ ] Vérification manuelle de toutes les fenêtres.
|
||||
- [ ] Vérification réelle HTTP Helius.
|
||||
- [ ] Vérification réelle WebSocket Helius.
|
||||
- [ ] Rejeu Metaplex avec `failed=0` sur les cas corrigés.
|
||||
|
||||
---
|
||||
|
||||
## 20. Documentation et clôture
|
||||
|
||||
- [ ] Mettre à jour `README.md` avec l’architecture Bot3 finale.
|
||||
- [ ] Mettre à jour `ROADMAP.md` avec les points réellement clôturés et les reports.
|
||||
- [ ] Mettre à jour `CHANGELOG.md` avec toutes les prereleases et fixes.
|
||||
- [ ] Documenter la politique `.env` et l’ordre de résolution.
|
||||
- [ ] Documenter le cycle de vie HTTP/WebSocket.
|
||||
- [ ] Documenter les fenêtres dynamiques, Vite et capabilities.
|
||||
- [ ] Documenter les conventions de viewers JSON et de journaux texte.
|
||||
- [ ] Documenter l’IDL Metaplex et sa provenance.
|
||||
- [ ] Documenter les tâches reportées :
|
||||
- résolution de configuration de base dans `kb-store` ;
|
||||
- séparation des logs `kb-store.core` / `kb-store.postgres` ;
|
||||
- améliorations non bloquantes.
|
||||
- [ ] Préparer le prompt complet de la session suivante.
|
||||
- [ ] Livrer le dernier delta de migration.
|
||||
- [ ] Effectuer le commit Git de clôture.
|
||||
- [ ] Taguer la prerelease ou version de clôture selon la convention retenue.
|
||||
|
||||
---
|
||||
|
||||
## 21. Critères de clôture obligatoires
|
||||
|
||||
La migration ne peut être déclarée terminée que lorsque toutes les conditions suivantes sont satisfaites :
|
||||
|
||||
- [ ] Toutes les fenêtres historiques requises sont présentes et fonctionnelles.
|
||||
- [ ] Aucun ancien crate Bot2 n’est référencé.
|
||||
- [ ] Aucune erreur de compilation ou de test.
|
||||
- [ ] Audits Rust et workspace propres.
|
||||
- [ ] Aucun warning applicatif non justifié.
|
||||
- [ ] `.env` est centralisé dans `kb-config` et sa priorité est testée.
|
||||
- [ ] HTTP et WebSocket Helius fonctionnent avec une clé locale non versionnée.
|
||||
- [ ] Les erreurs Metaplex observées sont corrigées ou classées explicitement et correctement.
|
||||
- [ ] Les fenêtres SQL n’ont ni navigation involontaire ni layout régressif.
|
||||
- [ ] Chaque journal/résultat texte possède une seule paire Copier/Effacer.
|
||||
- [ ] Les viewers JSON sont bornés en hauteur et réservés au JSON réel.
|
||||
- [ ] Le cycle de vie WebSocket est validé jusqu’à l’arrêt global.
|
||||
- [ ] La documentation de clôture et le prompt suivant sont livrés.
|
||||
|
||||
<!-- file: KHADHROONY_BOT3_MIGRATION_CLOSURE_TODO.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Checklist détaillée de clôture de la migration `khadhroony-bot3`
|
||||
|
||||
## Base et principe de validation
|
||||
|
||||
- Base de travail : `khadhroony-bot3_v0.1.0-pre.055-full.zip`.
|
||||
- Références fonctionnelles : Bot2 `v0.4.6` puis Bot2 `v0.4.7-pre.035-tofix07`.
|
||||
- Prompt actif : `prompts/KHADHROONY_BOT3_MIGRATION_CONTINUATION_PROMPT_REORDERED.md`.
|
||||
- Une case n’est cochée qu’après preuve explicite : audit, compilation, test, requête SQL, contrôle runtime ou comparaison documentée.
|
||||
- L’ordre est obligatoire : règles, contrôles rapides, retour au niveau `0.4.6`, Metaplex `0.4.7`, Clippy/Tauri, documentation, versionnement.
|
||||
|
||||
## 0. Revalidation des règles et des archives
|
||||
|
||||
- [x] Inventorier l’archive Bot3 `pre.055`.
|
||||
- [x] Inventorier l’archive Bot2 `0.4.6` issue de Git.
|
||||
- [x] Inventorier l’archive Bot2 `0.4.7-pre.035-tofix07`.
|
||||
- [x] Vérifier la présence de l’IDL Metaplex local dans Bot3.
|
||||
- [x] Constater que Bot3 utilisait encore `RULES.md` et `RUST_RULES.md`.
|
||||
- [x] Créer `RULES_GENERAL.md`.
|
||||
- [x] Créer `RULES_RUST.md`.
|
||||
- [x] Créer `RULES_SPECIFIC_KHADHROONY.md`.
|
||||
- [x] Transformer `RULES.md` en index normatif.
|
||||
- [x] Corriger `docs/DELTA_WORKFLOW.md` pour Bot3, `-delta`, `delta-fix-XXX`, exclusion de `Cargo.lock` et absence de SHA256.
|
||||
- [x] Adapter le script d’audit aux nouveaux fichiers de règles.
|
||||
- [ ] Relire intégralement les quatre fichiers de règles après application du delta.
|
||||
- [ ] Comparer ligne par ligne les règles Bot2 encore applicables avec les règles Bot3.
|
||||
- [ ] Documenter chaque règle Bot2 écartée et sa justification.
|
||||
- [ ] Vérifier l’absence de contradiction sur les imports, réexports, façades, Tauri, TS-RS, logging, versionnement et archives.
|
||||
- [ ] Exécuter `cargo fmt --all`.
|
||||
- [ ] Exécuter `python3 scripts/audit_rust_workspace_rules.py`.
|
||||
|
||||
## 0.1 Classification des matrices de contrat
|
||||
|
||||
- [x] Inventorier les fichiers JSON machine auparavant placés sous `docs/`.
|
||||
- [x] Créer `test-fixtures/contract-matrices/` pour les matrices de contrat partagées.
|
||||
- [x] Déplacer les dix matrices JSON hors de `docs/`.
|
||||
- [x] Mettre à jour les dix-sept fichiers Rust contenant les `include_str!` concernés.
|
||||
- [x] Conserver le déplacement et les mises à jour de chemins dans une même livraison atomique.
|
||||
- [x] Lister chaque ancien fichier avec une commande `rm --` dans `delta.md`.
|
||||
- [ ] Exécuter les tests des crates consommatrices dans le workspace réel.
|
||||
- [ ] Vérifier qu’aucune référence résiduelle ne pointe vers les anciens chemins `docs/*.json`.
|
||||
|
||||
## 1. Contrôles rapides avant code fonctionnel
|
||||
|
||||
### 1.1 TS-RS
|
||||
|
||||
- [ ] Rechercher `export_to` uniquement dans les fichiers `.rs` de `kb-config`, `kb-lib` et `kb-app-demo-desktop`.
|
||||
- [ ] Vérifier les sorties `kb_config`.
|
||||
- [ ] Vérifier les sorties `kb_lib`.
|
||||
- [ ] Vérifier les sorties `kb_app_demo_desktop`.
|
||||
- [ ] Supprimer les chemins historiques `kb_executor_*`.
|
||||
- [ ] Supprimer les chemins historiques `kb_decoder_*`.
|
||||
- [ ] Supprimer les chemins historiques `kb_materializer_*`.
|
||||
- [ ] Supprimer les chemins historiques `kb_model`.
|
||||
- [ ] Supprimer les chemins historiques `kb_store_pg` et `kb_store_core`.
|
||||
- [ ] Régénérer les bindings via les tests TS-RS.
|
||||
- [ ] Vérifier que les fichiers générés correspondent exactement aux chemins déclarés.
|
||||
|
||||
### 1.2 Anciens chemins et nomenclature
|
||||
|
||||
- [ ] Auditer `kb-app-demo-desktop/**/*.rs` pour les anciens noms Bot2.
|
||||
- [ ] Auditer tout le workspace pour `token_2022` interne.
|
||||
- [ ] Justifier séparément chaque contrat externe `TOKEN_2022_*` conservé.
|
||||
- [ ] Vérifier que `kb-lib` et `kb-store` sont les seules façades consolidées concernées.
|
||||
- [ ] Vérifier qu’aucune ancienne crate n’a été recréée.
|
||||
|
||||
### 1.3 Frontend et menu
|
||||
|
||||
- [ ] Auditer les occurrences `Copier` et `Effacer` dans tous les HTML et TypeScript.
|
||||
- [ ] Garantir une seule paire de contrôles par sortie.
|
||||
- [ ] Vérifier l’ordre du menu : Configuration, Transport et collecte, Pipeline, SQL, Exécution.
|
||||
- [ ] Vérifier les séparateurs.
|
||||
- [ ] Supprimer les entrées mortes.
|
||||
- [ ] Identifier les fenêtres migrées mais non reliées.
|
||||
|
||||
## 2. Corrections UI rapides
|
||||
|
||||
### 2.1 HTTP JSON-RPC
|
||||
|
||||
- [ ] Remplacer le viewer JSON du résultat par un `textarea readonly`.
|
||||
- [ ] Fixer la hauteur.
|
||||
- [ ] Activer le scroll interne.
|
||||
- [ ] Garantir exactement un bouton Copier.
|
||||
- [ ] Garantir exactement un bouton Effacer.
|
||||
- [ ] Vider le buffer TypeScript lors de l’effacement.
|
||||
- [ ] Tester JSON, scalaire, texte, erreur et résultat vide.
|
||||
|
||||
### 2.2 WebSocket
|
||||
|
||||
- [ ] Afficher les messages dans un composant texte/log.
|
||||
- [ ] Fixer la hauteur et le scroll interne.
|
||||
- [ ] Garantir une seule paire Copier/Effacer.
|
||||
- [ ] Conserver les messages pendant la session active.
|
||||
- [ ] Restaurer l’affichage après fermeture/réouverture de la fenêtre.
|
||||
|
||||
### 2.3 Journaux généraux et viewers
|
||||
|
||||
- [ ] Vérifier Backfill HTTP.
|
||||
- [ ] Vérifier Extraction core.
|
||||
- [ ] Vérifier Exécution Solana Core.
|
||||
- [ ] Vérifier Exécution SPL.
|
||||
- [ ] Vérifier Decode replay.
|
||||
- [ ] Vérifier HTTP.
|
||||
- [ ] Vérifier WebSocket.
|
||||
- [ ] Placer les paramètres dans les accordéons.
|
||||
- [ ] Placer les journaux et résultats globaux sous les accordéons.
|
||||
- [ ] Réserver le viewer JSON au JSON structuré.
|
||||
- [ ] Utiliser des textareas pour texte brut, logs et diagnostics concaténés.
|
||||
- [ ] Fixer la hauteur de tous les viewers JSON.
|
||||
|
||||
### 2.4 Fenêtres SQL
|
||||
|
||||
- [ ] Mettre toutes les fenêtres SQL, sauf Replay Candidates, sur une seule colonne pleine largeur.
|
||||
- [ ] Mettre les tables sur toute la largeur.
|
||||
- [ ] Limiter le scroll horizontal au wrapper de table.
|
||||
- [ ] Vérifier toutes les balises HTML.
|
||||
- [ ] Vérifier boutons, onglets et liens.
|
||||
|
||||
## 3. Configuration et environnement
|
||||
|
||||
- [ ] Confirmer que seul `kb-config` charge `.env`.
|
||||
- [ ] Confirmer la priorité environnement du processus.
|
||||
- [ ] Confirmer `KB_ENV_FILE`.
|
||||
- [ ] Confirmer le `.env` racine par défaut.
|
||||
- [ ] Confirmer `${VAR}`.
|
||||
- [ ] Confirmer `${VAR:-fallback}`.
|
||||
- [ ] Confirmer l’absence non fatale pour les services optionnels.
|
||||
- [ ] Vérifier que les diagnostics ne révèlent aucun secret.
|
||||
- [ ] Vérifier que `kb-pipeline-demo-scenarios` ne dépend pas directement de `dotenvy`.
|
||||
- [ ] Valider réellement `HELIUS_API_KEY` depuis `.env`.
|
||||
- [ ] Garder la résolution de chemin de base `kb-store` dans le backlog documenté.
|
||||
|
||||
## 4. Logging
|
||||
|
||||
- [ ] Maintenir la console active pour `local_devnet`.
|
||||
- [ ] Maintenir la console active pour `mainnet_research`.
|
||||
- [ ] Maintenir la console active pour `mainnet`.
|
||||
- [ ] Supprimer les routes Bot2 obsolètes.
|
||||
- [ ] Vérifier les cibles `kb-lib.decoder.*`.
|
||||
- [ ] Vérifier les cibles `kb-lib.executor.*`.
|
||||
- [ ] Vérifier les cibles `kb-lib.materializer.*`.
|
||||
- [ ] Vérifier `kb-store`, `kb-config`, `kb-logging`, `kb-onchain-transport`, `kb-pipeline`, `kb-wallet` et `kb-app-demo-desktop`.
|
||||
- [ ] Vérifier qu’aucun ancien répertoire de logs de crate supprimée n’est recréé.
|
||||
|
||||
## 5. Options SPL et Token-2022
|
||||
|
||||
- [ ] Comparer chaque option de `demo_execution_spl.html` aux scénarios réellement supportés.
|
||||
- [ ] Comparer les options aux branches de `tauri.rs`.
|
||||
- [ ] Supprimer les options mortes.
|
||||
- [ ] Remplacer les valeurs internes `token_2022` par `token2022`.
|
||||
- [ ] Inventorier chaque variable `TOKEN_2022_*`.
|
||||
- [ ] Marquer les variables conservées pour compatibilité externe.
|
||||
- [ ] Marquer les variables limitées aux scénarios de démonstration.
|
||||
- [ ] Documenter les futurs remplacements par configuration ou structure typée.
|
||||
|
||||
## 6. Cycle de vie WebSocket
|
||||
|
||||
- [ ] Vérifier qu’aucun pool WebSocket n’est créé au démarrage.
|
||||
- [ ] Vérifier la création paresseuse au premier accès.
|
||||
- [ ] Vérifier le stockage du pool dans `AppState`.
|
||||
- [ ] Vérifier la survie de la session après fermeture de `demo_ws`.
|
||||
- [ ] Vérifier la récupération de l’état à la réouverture.
|
||||
- [ ] Vérifier la fermeture explicite.
|
||||
- [ ] Vérifier le timeout.
|
||||
- [ ] Vérifier l’arrêt global de l’application.
|
||||
- [ ] Vérifier que la fermeture de la fenêtre n’appelle jamais la déconnexion globale.
|
||||
|
||||
## 7. Initialisation PostgreSQL et splash
|
||||
|
||||
- [ ] Charger l’environnement.
|
||||
- [ ] Charger et valider la configuration.
|
||||
- [ ] Initialiser le logging.
|
||||
- [ ] Initialiser le pool HTTP.
|
||||
- [ ] Se connecter à PostgreSQL.
|
||||
- [ ] Appeler `initialize_postgres_schema_for_startup`.
|
||||
- [ ] Appeler `emit_sql_startup_table_report`.
|
||||
- [ ] Relier `emit_sql_startup_error`.
|
||||
- [ ] Relier `emit_sql_startup_splash`.
|
||||
- [ ] Ouvrir `main` seulement après le rapport PostgreSQL.
|
||||
- [ ] Fermer le splash après le statut final.
|
||||
- [ ] Ne pas initialiser WebSocket dans cette séquence.
|
||||
- [ ] Rendre la zone de messages du splash scrollable.
|
||||
- [ ] Garder le dernier message visible.
|
||||
- [ ] Afficher connexion, schéma, nombre de tables, tables manquantes et statut final.
|
||||
|
||||
## 8. Purge contrôlée des données dérivées
|
||||
|
||||
- [ ] Inventorier les tables via `kb-store`.
|
||||
- [ ] Classer chaque table en raw, nécessaire au replay, dérivée ou ambiguë.
|
||||
- [ ] Bloquer la purge tant qu’une table reste ambiguë.
|
||||
- [ ] Créer un script SQL versionné et idempotent.
|
||||
- [ ] Conserver transactions, signatures et payloads RPC raw.
|
||||
- [ ] Conserver toutes les données nécessaires à l’extraction et au replay.
|
||||
- [ ] Purger core dérivé, décodage, observations, coverage, diagnostics et états de replay dérivés.
|
||||
- [ ] Purger annotations, événements matérialisés, token accounts, lifecycle, admin, fees, risk, compliance et staking dérivés.
|
||||
- [ ] Exécuter la purge dans une transaction.
|
||||
- [ ] Ajouter des vérifications avant/après.
|
||||
- [ ] Documenter précisément les tables conservées.
|
||||
- [ ] Relancer l’extraction core.
|
||||
- [ ] Relancer tous les décodeurs.
|
||||
- [ ] Relancer la matérialisation.
|
||||
- [ ] Valider les compteurs et erreurs.
|
||||
- [ ] Contrôler la reconstruction de chaque projection attendue.
|
||||
|
||||
## 9. Jalon fonctionnel Bot2 `0.4.6`
|
||||
|
||||
- [ ] Solana Core équivalent et validé.
|
||||
- [ ] SPL Memo équivalent et validé.
|
||||
- [ ] SPL Token classique équivalent et validé.
|
||||
- [ ] SPL ATA équivalent et validé.
|
||||
- [ ] SPL Token-2022 équivalent et validé.
|
||||
- [ ] ElGamal Registry équivalent et validé.
|
||||
- [ ] Backfill équivalent et validé.
|
||||
- [ ] Extraction core équivalente et validée.
|
||||
- [ ] Replay équivalent et validé.
|
||||
- [ ] Matérialisation équivalente et validée.
|
||||
- [ ] Exécution supportée équivalente et validée.
|
||||
- [ ] Scénarios devnet historiques validés.
|
||||
- [ ] HTTP et WebSocket validés.
|
||||
- [ ] PostgreSQL validé.
|
||||
- [ ] Logging validé.
|
||||
- [ ] Configuration validée.
|
||||
- [ ] Produire un rapport explicite de parité `0.4.6` avant toute clôture Metaplex.
|
||||
|
||||
## 10. Inventaire IDL
|
||||
|
||||
- [ ] Créer `docs/IDL_SOURCES.md`.
|
||||
- [ ] Inventorier chaque IDL local.
|
||||
- [ ] Indiquer protocole et program ID.
|
||||
- [ ] Indiquer source officielle.
|
||||
- [ ] Indiquer version ou commit lorsqu’ils sont connus.
|
||||
- [ ] Indiquer chemin local, statut et usage.
|
||||
- [ ] Documenter les notes de compatibilité.
|
||||
- [ ] Ne pas inventer d’IDL absent.
|
||||
- [ ] Référencer l’IDL Metaplex existant sans le retélécharger.
|
||||
|
||||
## 11. Metaplex Token Metadata — décodeur
|
||||
|
||||
- [ ] Extraire toutes les erreurs Metaplex réelles.
|
||||
- [ ] Regrouper par instruction et type d’échec.
|
||||
- [ ] Isoler `create_metadata_account_v3`.
|
||||
- [ ] Isoler `transfer`.
|
||||
- [ ] Comparer runtime, IDL local, builders et interface officielle.
|
||||
- [ ] Corriger signer et writable flags.
|
||||
- [ ] Gérer comptes optionnels et variantes legacy.
|
||||
- [ ] Distinguer transactions échouées, payloads tronqués et variantes inconnues.
|
||||
- [ ] Ajouter des fixtures issues de transactions réelles.
|
||||
- [ ] Relancer le replay complet Metaplex.
|
||||
- [ ] Obtenir zéro faux échec de metas.
|
||||
|
||||
## 12. Metaplex Token Metadata — exécuteur et devnet
|
||||
|
||||
- [ ] Compléter les intents typés.
|
||||
- [ ] Compléter les builders.
|
||||
- [ ] Valider l’ordre des comptes.
|
||||
- [ ] Valider signers et writable flags.
|
||||
- [ ] Borner explicitement les variantes supportées.
|
||||
- [ ] Ajouter les politiques de sécurité.
|
||||
- [ ] Imposer simulation-first.
|
||||
- [ ] Ajouter l’estimation des coûts.
|
||||
- [ ] Ajouter la validation post-exécution.
|
||||
- [ ] Ajouter les tests unitaires.
|
||||
- [ ] Comparer aux builders officiels.
|
||||
- [ ] Compléter la matrice de couverture.
|
||||
- [ ] Ajouter des scénarios devnet explicites.
|
||||
- [ ] Interdire l’exécution par défaut sur mainnet.
|
||||
- [ ] Afficher plan, signers, simulation et résultat.
|
||||
- [ ] Effectuer un replay post-exécution.
|
||||
- [ ] Vérifier décodage et matérialisation.
|
||||
- [ ] Afficher les diagnostics.
|
||||
|
||||
## 13. Clippy et Tauri
|
||||
|
||||
- [ ] Traiter Clippy seulement après le fonctionnel Metaplex.
|
||||
- [ ] Identifier précisément les expansions de macros Tauri concernées par `question_mark_used`.
|
||||
- [ ] Éviter un `allow` global.
|
||||
- [ ] Documenter toute exception locale et sa portée.
|
||||
- [ ] Obtenir un Clippy propre ou un écart borné et reproductible.
|
||||
|
||||
## 14. Documentation finale et versionnement
|
||||
|
||||
- [ ] Rendre les README génériques et indépendants de la migration.
|
||||
- [ ] Retirer les numéros de version des README.
|
||||
- [ ] Retirer le récit Bot2 vers Bot3 des README actifs.
|
||||
- [ ] Créer `USAGES.md` pour chaque crate publique.
|
||||
- [ ] Documenter API, types, traits, fonctions, builders, exemples, invariants, erreurs, limites et intégrations.
|
||||
- [ ] Ajouter des roadmaps par crate uniquement lorsqu’elles apportent une valeur réelle.
|
||||
- [ ] Conserver au plus une courte note historique.
|
||||
- [ ] Ne passer à `0.4.7` qu’après parité `0.4.6`, Metaplex complet, replay validé et documentation terminée.
|
||||
- [ ] Mettre à jour `CHANGELOG.md` uniquement lors de cette validation explicite.
|
||||
|
||||
## 15. Validation finale
|
||||
|
||||
- [ ] `cargo fmt --all`.
|
||||
- [ ] `cargo check -p kb-config`.
|
||||
- [ ] `cargo test -p kb-config`.
|
||||
- [ ] `cargo check -p kb-pipeline-demo-scenarios`.
|
||||
- [ ] `cargo test -p kb-pipeline-demo-scenarios`.
|
||||
- [ ] `cargo check -p kb-store`.
|
||||
- [ ] `cargo test -p kb-store`.
|
||||
- [ ] `cargo check -p kb-lib`.
|
||||
- [ ] `cargo test -p kb-lib`.
|
||||
- [ ] `cargo check -p kb-app-demo-desktop`.
|
||||
- [ ] `cargo test -p kb-app-demo-desktop`.
|
||||
- [ ] `cargo check --workspace`.
|
||||
- [ ] `cargo test --workspace`.
|
||||
- [ ] `python3 scripts/audit_rust_workspace_rules.py`.
|
||||
- [ ] `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`.
|
||||
- [ ] `cargo clippy --all-targets` en dernier.
|
||||
|
||||
## 16. Critères de clôture
|
||||
|
||||
- [ ] Toutes les crates compilent.
|
||||
- [ ] Tous les tests workspace passent.
|
||||
- [ ] Audit Rust propre.
|
||||
- [ ] Audit TS-RS propre.
|
||||
- [ ] Aucun chemin Bot2 supprimé encore actif.
|
||||
- [ ] Toutes les fenêtres fonctionnent.
|
||||
- [ ] WebSocket persistant validé.
|
||||
- [ ] `.env` et Helius validés.
|
||||
- [ ] PostgreSQL et splash validés.
|
||||
- [ ] Données dérivées purgées et reconstruites.
|
||||
- [ ] Niveau `0.4.6` restauré.
|
||||
- [ ] UI JSON/texte cohérente.
|
||||
- [ ] Aucun contrôle Copier/Effacer dupliqué.
|
||||
- [ ] Journaux hors accordéon.
|
||||
- [ ] Fenêtres SQL dimensionnées.
|
||||
- [ ] Routes de logs obsolètes supprimées.
|
||||
- [ ] Console active.
|
||||
- [ ] Inventaire IDL terminé.
|
||||
- [ ] Zéro faux échec Metaplex de metas.
|
||||
- [ ] Exécuteur et démos Metaplex validés.
|
||||
- [ ] Clippy/Tauri finalisés.
|
||||
- [ ] Documentation et `USAGES.md` terminés.
|
||||
- [ ] Passage à `0.4.7` justifié.
|
||||
|
||||
261
RULES.md
261
RULES.md
@@ -1,258 +1,21 @@
|
||||
<!-- file: RULES.md -->
|
||||
<!-- version: 23 -->
|
||||
<!-- version: 24 -->
|
||||
|
||||
# Règles spécifiques à `khadhroony-bot3`
|
||||
# Index des règles `khadhroony-bot3`
|
||||
|
||||
Ce fichier contient uniquement les règles propres au projet et au workspace `khadhroony-bot3`.
|
||||
La lecture des fichiers suivants est obligatoire avant toute modification :
|
||||
|
||||
Les règles Rust générales et réutilisables dans tous les projets sont définies dans [`RUST_RULES.md`](RUST_RULES.md). Les deux fichiers sont normatifs et cumulatifs. En cas de conflit, la règle la plus stricte s'applique ; une règle spécifique au workspace ne peut jamais assouplir une règle générale sans exception explicitement documentée.
|
||||
1. [`RULES_GENERAL.md`](RULES_GENERAL.md) — gouvernance documentaire, méthode de travail et livraisons delta ;
|
||||
2. [`RULES_RUST.md`](RULES_RUST.md) — règles Rust réutilisables ;
|
||||
3. [`RULES_SPECIFIC_KHADHROONY.md`](RULES_SPECIFIC_KHADHROONY.md) — architecture et conventions propres au workspace.
|
||||
|
||||
Toute livraison doit exécuter l'audit `python3 scripts/audit_rust_workspace_rules.py`. Tant que l'audit global n'est pas propre, les écarts existants doivent être résorbés par lots de correctifs avant toute nouvelle prérelease.
|
||||
Ces règles sont cumulatives. En cas de conflit, la règle la plus stricte s’applique. Une exception doit être explicite, locale, bornée et documentée.
|
||||
|
||||
## Règles de nommage
|
||||
Toute tranche commence par :
|
||||
|
||||
- Tous les noms de fichiers et de répertoires doivent être écrits en anglais.
|
||||
- Les noms de fichiers et de répertoires ne doivent contenir aucun accent, espace ou caractère spécial inutile.
|
||||
- Les noms internes doivent utiliser le format `snake_case` lorsque c'est applicable.
|
||||
- Les packages Rust utilisent le préfixe `kb-` ; leur identifiant Rust correspondant utilise automatiquement `kb_`.
|
||||
- Les décodeurs, matérialisateurs et exécuteurs sont des modules de `kb-lib`, pas des crates séparées.
|
||||
- Le crate de journalisation s'appelle `kb-logging`.
|
||||
- Les réexports sont regroupés par visibilité : le bloc `pub use` précède le bloc séparé `pub(crate) use`, sans ligne vide interne à un bloc ; leur ordre naturel doit rester compatible avec `cargo fmt`.
|
||||
- Les familles de symboles consolidées dans `kb-lib` utilisent les préfixes `DC_`/`Dc`/`decoder_` pour les décodeurs, `MT_`/`Mt`/`materializer_` pour les matérialisateurs, `EX_`/`Ex`/`executor_` pour les exécuteurs et `MD_`/`Md`/`model_` pour les modèles.
|
||||
- Les méthodes inhérentes et helpers strictement privés peuvent conserver un nom local court ; les préfixes s’appliquent aux constantes, types, traits et fonctions libres exposés à la crate ou hors de la crate.
|
||||
- Les constantes temporaires `*_LEGACY_CRATE`, `*_MIGRATION_STATUS` et `*_MIGRATION_BOUNDARIES` doivent disparaître d’une famille dès que ses squelettes typés sont restaurés ; elles ne constituent jamais une API durable.
|
||||
|
||||
## Règles Tauri et TypeScript
|
||||
|
||||
- Toute structure ou énumération Rust exposée au frontend TypeScript doit importer le trait `TS` avec `use ts_rs::TS;` puis dériver `TS`.
|
||||
- Les types Rust exportés vers TypeScript doivent utiliser des noms stables et explicites.
|
||||
- Les bindings générés doivent être produits dans un dossier dédié, généralement `../frontend/ts/bindings` ou `#[ts(export, export_to = "../frontend/ts/bindings/MyStruct.ts")]`.
|
||||
- Les types purement internes au backend ne doivent pas être exportés vers TypeScript par défaut.
|
||||
- Un payload de commande ou d’événement Tauri traverse une frontière JSON et ne doit jamais exiger un `bigint` JavaScript. Pour un entier Rust borné et représentable par l’UI, utiliser un override TS-rs `number`; si l’exactitude au-delà de `Number.MAX_SAFE_INTEGER` est nécessaire, sérialiser explicitement une chaîne décimale côté Rust et exporter `string`. Ne jamais construire un `BigInt` dans un objet passé à `invoke` ou `emit`.
|
||||
- Corriger le type Rust/TS-rs source puis régénérer les bindings ; ne pas considérer une modification manuelle isolée d’un fichier généré comme un correctif durable.
|
||||
|
||||
## Règles d'architecture
|
||||
|
||||
- Les décodeurs ne dépendent pas de PostgreSQL, SQLite, RPC, Tauri, wallet, stratégie ou matérialisateurs.
|
||||
- Les matérialisateurs ne dépendent pas du RPC, du wallet, de Tauri ou des décodeurs spécifiques.
|
||||
- Pour chaque programme Solana, quelle que soit sa famille, un décodeur doit couvrir maximalement tout wire officiellement identifiable de sa surface, qu'il soit historique, courant, récent, expérimental ou publié avant son déploiement généralisé. Ces statuts doivent rester explicites et ne constituent pas un motif pour supprimer le décodage.
|
||||
- Une observation lisible issue d'une transaction échouée peut conserver une intention non commitée ; elle ne doit jamais être présentée comme une mutation réussie.
|
||||
- Pour chaque programme Solana, les matérialisateurs doivent projeter maximalement tous les faits métier stables et prouvés par le décodage, y compris les états historiques, obsolètes, dépréciés ou seulement rencontrables pendant un backfill. Le statut historique interdit l'exécution, mais ne constitue jamais à lui seul un motif de non-matérialisation.
|
||||
- Toute projection historique doit conserver explicitement son lifecycle, sa version de layout, sa provenance, son slot ou ordre d'observation lorsqu'ils sont connus, et ne doit jamais écraser silencieusement un état actif plus récent.
|
||||
- Une même réalité métier doit avoir une seule projection canonique. Les snapshots de comptes sont la source autoritative de l'état final lorsqu'ils sont disponibles ; les instructions et événements corrélés restent des observations de mutation et ne doivent pas produire un doublon concurrent du même état.
|
||||
- Les matérialisateurs doivent refuser les transactions non commitées pour les mutations d'état, tout en pouvant conserver séparément une intention non commitée lorsque le modèle métier le prévoit explicitement.
|
||||
- Toute absence volontaire de projection doit être documentée avec une justification technique précise. Un matérialisateur ne doit inventer ni état final, ni montant, ni autorité, ni frais, ni agrégation que l'observation ne prouve pas.
|
||||
- Pour chaque programme Solana, les exécuteurs doivent couvrir maximalement les opérations officiellement appelables et les opérations expérimentales publiées lorsque leurs contrats exacts et garde-fous sont prouvés. Les opérations historiques, dépréciées ou obsolètes doivent rester décodables et matérialisables, mais ne doivent jamais être exposées à l'exécution ; cette exclusion doit être explicite dans la matrice et le README.
|
||||
- `kb-store` possède les contrats de persistance neutres et les adaptateurs de base de données.
|
||||
- PostgreSQL est l'adaptateur de production de `kb-store`.
|
||||
- Un futur adaptateur SQLite doit rester interne à `kb-store` et limité aux tests, imports et corpus locaux.
|
||||
- `kb-wallet` reste isolé du reste du système.
|
||||
- Les transactions raw sont immuables et restent la source d'audit.
|
||||
- Les replays doivent être ciblés par module, version, programme, surface, discriminator, slot ou signatures.
|
||||
- La documentation active du projet ne doit pas présenter l'ancien workspace comme architecture courante. Les documents de migration et copies de référence peuvent le nommer explicitement.
|
||||
|
||||
## Règles de documentation projet
|
||||
|
||||
- `README.md` décrit le projet, son rôle, ses objectifs et son organisation.
|
||||
- `ROADMAP.md` contient les futures étapes, versions et changements prévus.
|
||||
- `ROADMAP.md` conserve une structure documentaire normale par phases, cases cochées et journal de préversions ; les étiquettes conversationnelles de priorité ne doivent pas y être ajoutées.
|
||||
- Les réponses de livraison doivent reprendre la liste exhaustive des tâches avec les rubriques conversationnelles **Validé**, **En cours**, **Next** et **Planifié**, sans réduire le suivi à un résumé ambigu.
|
||||
- `CHANGELOG.md` n'est modifié qu'après validation d'une version, avec un paragraphe ajouté à la fin décrivant ce qui a été fait ou ajouté.
|
||||
- Chaque crate Rust doit avoir un `README.md` ou `001.README.md` expliquant son rôle dans l'écosystème.
|
||||
- Le README d'une crate opérationnelle doit inventorier ses types, traits, constantes et fonctions publics utiles, expliquer leurs paramètres, résultats, effets et frontières, puis fournir au moins un exemple d'utilisation lorsque l'API est destinée à être appelée directement.
|
||||
- Une API publique ajoutée ou modifiée n'est pas considérée comme documentée tant que le README de sa crate n'a pas été synchronisé ; les bindings générés seuls ne remplacent pas cette documentation.
|
||||
|
||||
## Nomenclature métier
|
||||
|
||||
- `protocol_code` désigne la famille : `pump`, `raydium`, `meteora`, `orca`, `jupiter`, etc.
|
||||
- `surface_code` désigne la surface concrète : `pump_swap`, `raydium_amm_v4`, `meteora_dlmm`, etc.
|
||||
- `event_code` suit le format `<surface_code>.<event_name>`.
|
||||
- Les familles d'événements principales sont : `trade`, `liquidity`, `lifecycle`, `fee`, `admin`, `reward`, `orderbook`, `token_account`, `pool_state`, `routing`, `risk`, `audit`, `unknown`.
|
||||
|
||||
## Base de données
|
||||
|
||||
- Les schémas PostgreSQL cibles sont : `raw`, `core`, `obs`, `decode`, `mat`, `catalog`, `agg`, `ops`, `wallet`.
|
||||
- Les colonnes JSONB doivent se terminer par `_jsonb`.
|
||||
- Les montants bruts on-chain doivent se terminer par `_raw`.
|
||||
- La transaction canonique raw reste la source rejouable et ne doit pas être supprimée après traitement sans politique de rétention explicite.
|
||||
|
||||
## Nommage canonique des surfaces
|
||||
|
||||
Les nouvelles surfaces de programmes doivent utiliser un nom canonique basé sur la fonction réelle du programme :
|
||||
|
||||
```text
|
||||
<function_code>_<family_code>_<identifier_code>[_vN]
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
```
|
||||
|
||||
Les modules internes de décodage doivent utiliser la hiérarchie de fichiers :
|
||||
|
||||
```text
|
||||
kb-lib/src/decoder/<function_code>/<family_code>_<identifier_code>[_vN].rs
|
||||
```
|
||||
|
||||
Exemples :
|
||||
|
||||
- `kb-lib/src/decoder/amm/raydium_cpmm.rs` ;
|
||||
- `kb-lib/src/decoder/clmm/raydium.rs` ;
|
||||
- `kb-lib/src/decoder/dlmm/meteora.rs` ;
|
||||
- `kb-lib/src/decoder/router/jupiter_aggregator_v6.rs` ;
|
||||
- `kb-lib/src/decoder/orderbook/openbook_v2.rs` ;
|
||||
- `kb-lib/src/decoder/metadata/metaplex_token_metadata.rs` ;
|
||||
- `kb-lib/src/decoder/nft/metaplex_bubblegum.rs`.
|
||||
|
||||
Ces modules restent privés. Les consommateurs externes utilisent exclusivement les types et fonctions réexportés directement par `kb_lib`.
|
||||
|
||||
Les noms historiques ou issus d'IDL doivent être conservés dans le registre, mais ne doivent pas créer de nouveau module si un module canonique existe déjà.
|
||||
|
||||
Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédiée et sans validation Cargo.
|
||||
|
||||
## Règles de nommage des surfaces Solana
|
||||
|
||||
- Le nom canonique d'une surface doit commencer par une fonction réelle : `amm`, `clmm`, `dlmm`, `router`, `orderbook`, `launchpad`, `lending`, `vault`, `staking`, `bridge`, `perpetuals`, `oracle`, `nft`, `metadata`, `admin`, etc.
|
||||
- Le préfixe `program_` est interdit pour les nouveaux noms canoniques.
|
||||
- Les surfaces non classifiées doivent utiliser `unknown_*` et ne doivent pas avoir de crate cible tant que leur fonction n'est pas validée.
|
||||
- Les programmes Solana/SPL primitifs doivent rester séparés des surfaces DEX/router dans la documentation de contrôle.
|
||||
- `damm` ne doit pas être utilisé comme préfixe fonctionnel ; utiliser `amm_meteora_damm_v1` ou `amm_meteora_damm_v2`.
|
||||
|
||||
## Registre des identifiants core
|
||||
|
||||
- Les identifiants Solana/SPL primitifs doivent être tenus à jour dans `registry/core_program_id_seed.toml`.
|
||||
- Les sysvars et comptes natifs connus ne doivent pas être classés comme surfaces DEX/router.
|
||||
- `spl_token`, `spl_token2022` et `associated_token_account` restent des surfaces spécialisées ; les noms historiques de crates externes conservent leur graphie officielle.
|
||||
- `stake_pool` doit être réservé à un futur crate spécialisé plutôt que mélangé avec le programme `stake`.
|
||||
|
||||
## Index court de programme
|
||||
|
||||
- Les noms de modules ne doivent pas commencer par un index hexadécimal.
|
||||
- Un champ `registry_code` optionnel peut être ajouté au registre pour l'UI, PostgreSQL ou les matrices.
|
||||
- Le nom canonique reste la source principale : fonction + famille + identifiant + version.
|
||||
|
||||
## Comptes non exécutables
|
||||
|
||||
- Une adresse de compte, de pool, de PDA ou de vault ne doit pas générer un module de décodeur.
|
||||
- Le vrai `program_id` propriétaire doit être prouvé avant création d'une surface canonique.
|
||||
|
||||
## Constantes Rust
|
||||
|
||||
- Les fichiers `program_ids.rs` sont interdits dans les nouveaux crates. Utiliser `constants.rs`.
|
||||
- Les `program_id` publics doivent être réexportés depuis `lib.rs`.
|
||||
- Dans une crate, les modules internes doivent appeler les constantes réexportées via `crate::CONSTANT_NAME`.
|
||||
- Les discriminants, sélecteurs, longueurs Borsh et constantes internes futures doivent être placés dans `constants.rs` et rester `pub(crate)` sauf besoin d'API publique explicite.
|
||||
|
||||
## Règles de tracing
|
||||
|
||||
- Une crate ou un composant de `kb-lib` est opérationnel lorsqu’il effectue des I/O, orchestre un pipeline, décode, matérialise, exécute, applique une politique runtime ou prend une décision mutable observable.
|
||||
- Toute crate opérationnelle ajoutée ou modifiée doit dépendre de `tracing` depuis le workspace et déclarer exactement un `pub(crate) const TRACING_TARGET` dans `src/constants.rs`.
|
||||
- Hors `kb-lib`, la valeur canonique de `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` est le nom exact du package Cargo.
|
||||
- Dans `kb-lib`, chaque composant opérationnel possède son propre `constants.rs` et un target hiérarchique stable fondé sur son identifiant de décodeur, matérialiseur ou exécuteur ; un target unique `kb-lib` ne doit pas effacer l'identité du composant.
|
||||
- Les targets historiques `khbot.*` et les targets de fenêtre sont interdits dans les nouvelles modifications.
|
||||
- Les macros `tracing` doivent utiliser `target: crate::TRACING_TARGET` et des champs structurés stables. La granularité interne passe par `action`, `stage`, `window`, `campaign_id`, `signature`, `instruction_path`, `program_id`, `processor_name`, `processor_version`, `status` et `error_code`.
|
||||
- Les crates passives de types, contrats, DTO, API sans exécution, registres ou constantes restent sans dépendance `tracing`. `kb-config` reste une exception de bootstrap tant que sa validation précède l’installation du subscriber.
|
||||
- Il est interdit d’ajouter `tracing` sans événement réel ou de conserver un faux target uniquement consommé par `let _target`.
|
||||
- Une décision interne doit être journalisée par la crate responsable ; `kb-app-demo` ne journalise que les frontières Tauri/UI, les actions utilisateur et les résumés d’orchestration.
|
||||
- Tout input sélectionné sans décodeur compatible, tout résultat de décodage `failed` ou `unsupported`, tout résultat de matérialisation `failed`, toute validation de résultat invalide et toute erreur de persistance doivent émettre un événement `error` avant le retour ou la persistance terminale.
|
||||
- Une transaction Solana échouée mais correctement décodée n’est pas une erreur du logiciel. Une décision `ignored`, un refus de matérialisation conforme à la politique ou une annulation coopérative ne doivent pas être promus artificiellement au niveau `error`.
|
||||
- Les erreurs de décodage et de matérialisation doivent conserver au minimum, lorsque disponibles : `campaign_id`, `signature`, `slot`, `instruction_path`, `program_id`, processor ou materializer avec version, `input_key`, `input_hash` ou hash du payload, statut, code et diagnostic borné.
|
||||
- Les payloads complets, DSN non masqués, secrets, clés privées et données non bornées sont interdits dans les logs.
|
||||
- Chaque profil doit router les événements vers les sorties globales `debug.log`, `info.log`, `error.jsonl` et `app.log`, puis vers `debug.log`, `info.log` et `error.jsonl` dans un répertoire propre à chaque crate utilisant `tracing`.
|
||||
- L’ajout ou la suppression de `tracing.workspace = true` dans une crate impose la mise à jour simultanée de la matrice de routes, de ses tests et de `docs/TRACING_CONTRACT.md`.
|
||||
- Le contrat détaillé est défini dans `docs/TRACING_CONTRACT.md`.
|
||||
- L’audit mécanique spécifique au projet est exécuté par `python3 scripts/audit_khadhroony_workspace_rules.py`. Il couvre notamment `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` et l’usage obligatoire de `solana_pubkey::Pubkey` à la place de `solana_address::Address`.
|
||||
|
||||
## Règles de réutilisation des interfaces Solana et SPL
|
||||
|
||||
- Les dépendances déclarées dans `[workspace.dependencies]` forment un catalogue de versions et de features autorisées ; elles ne doivent être ajoutées à une crate consommatrice que lorsqu’un type, un encodeur, un décodeur ou un identifiant officiel est réellement utilisé.
|
||||
|
||||
- Dans un `Cargo.toml`, placer dans `[dependencies]` toute crate référencée par le code de bibliothèque compilé en production. Réserver `[dev-dependencies]` aux références contenues exclusivement dans `#[cfg(test)]`, les tests d’intégration, benches ou exemples. Une dépendance de test vers un décodeur ou matérialiseur concret est légitime lorsqu’elle sert uniquement à éprouver une orchestration générique fondée sur les traits API ; elle ne prouve pas qu’une capacité de production manque. Toute promotion de `dev-dependencies` vers `dependencies` doit être motivée par un appel runtime réel, et toute dépendance runtime inutilisée doit être supprimée.
|
||||
- Les registres de composition runtime des applications doivent énumérer explicitement chaque décodeur et matérialiseur concret activé. Toute nouvelle surface instructionnelle dotée d’un `MtApiEventMaterializer` doit être ajoutée au registre applicatif et couverte par un test d’inventaire ordonné ; une crate présente dans le workspace ou dans `kb_pipeline` n’est pas activée automatiquement. Les matérialiseurs exclusivement stateful qui n’implémentent pas `MtApiEventMaterializer` restent routés par leurs APIs de snapshots dédiées.
|
||||
- Les corrélations instruction/état doivent produire une issue explicite (`confirmed`, `contradicted` ou `not_applicable`) et ne doivent jamais transformer automatiquement une configuration observée en violation, score ou conclusion métier.
|
||||
- Une interface officielle Solana ou SPL étroite doit être préférée à `solana-sdk` lorsque son contrat suffit.
|
||||
- L’ordre de préférence des formats est : schéma officiel `wincode`, schéma officiel Borsh, puis parseur local borné reproduisant exactement le runtime lorsque l’interface officielle n’expose que `bincode`.
|
||||
- Aucun nouveau code ne doit dépendre directement de `bincode`. Une interface officielle uniquement disponible derrière une feature `bincode` ne justifie pas l’activation de cette feature ; le layout doit alors être prouvé depuis les sources officielles et implémenté localement avec des bornes et des tests.
|
||||
- Les exécuteurs doivent utiliser les builders officiels disponibles, préserver l’ordre exact des metas, borner toute liste de comptes variable avant l’appel au builder et refuser les doublons lorsque leur répétition n’a pas de sémantique publiée.
|
||||
- Les features des interfaces doivent rester minimales et explicites. Une feature `serde`, `wincode`, `borsh`, `std`, `alloc` ou équivalente n’est activée que si la crate consommatrice l’utilise réellement.
|
||||
- Les crates applicatives ne doivent pas dépendre d’interfaces RPC ou transactionnelles uniquement pour relayer des types ; ces dépendances appartiennent à `kb_onchain_transport`, aux modèles communs justifiés ou à la crate opérationnelle propriétaire.
|
||||
- Toute exception et toute implémentation locale doivent être documentées dans `docs/SOLANA_INTERFACE_DEPENDENCIES.md` avec la raison, la source officielle et la stratégie de test.
|
||||
- Tant que les types Solana consommés implémentent les traits de `wincode 0.5.x`, le catalogue
|
||||
workspace conserve `wincode = "^0.5"` et le `Cargo.lock` versionné conserve exactement
|
||||
`wincode 0.5.5` avec `solana-wincode-varint 1.0.0`. Une entrée inutilisée ne doit pas être
|
||||
ajoutée artificiellement aux dépendances d’une crate pour influencer le résolveur. L’audit
|
||||
spécifique du workspace refuse toute dérive de ce couple avant compilation.
|
||||
|
||||
## Règles des exécuteurs
|
||||
|
||||
- Les exécuteurs résident dans `kb_lib::executor`.
|
||||
- Une surface classifiée peut avoir un module décodeur et un module exécuteur distincts dans `kb-lib`.
|
||||
- Les exécuteurs ne doivent pas dépendre des décodeurs.
|
||||
- Les exécuteurs utilisent les contrats `ExApi*` réexportés directement par la façade `kb_lib`.
|
||||
- Un squelette d’exécuteur doit exposer un type `Ex*Executor`, référencer uniquement des Program IDs de `kb-program-ids`, annoncer `Maybe` pour sa surface et construire exclusivement un plan réservé à zéro instruction.
|
||||
- La migration fonctionnelle d’un exécuteur doit remplacer ce comportement réservé par des capacités exactes `Supported` ou `Unsupported(reason)` ; aucun statut temporaire `LEGACY_CRATE` ou `MIGRATION_STATUS` ne doit subsister.
|
||||
- Les garde-fous communs doivent être placés dans les modules de sécurité partagés de `kb-lib`.
|
||||
- Aucun exécuteur ne doit envoyer de transaction sans simulation et validation explicite.
|
||||
- Les surfaces non classifiées ne doivent pas avoir de crate exécuteur.
|
||||
- Pour chaque programme Solana et contrairement aux décodeurs, les exécuteurs ne construisent pas les opérations obsolètes ou purement historiques. Ils couvrent uniquement les opérations courantes et expérimentales officiellement constructibles, avec un statut exact `Supported` ou `Unsupported(reason)`.
|
||||
- Le statut expérimental, récent ou non encore déployé partout n'interdit pas un builder universel lorsqu'un wire officiel exact existe. Le déploiement, la simulation et l'autorisation d'envoi restent trois décisions séparées ; la bibliothèque ne doit pas imposer artificiellement un cluster.
|
||||
|
||||
|
||||
- Les champs JSON exposés à TypeScript ne doivent pas utiliser directement `serde_json::Value` avec `TS-rs`; utiliser une chaîne JSON sérialisée (`std::string::String`) ou un type Rust typé exportable.
|
||||
- Les APIs qui gardent des payloads dynamiques doivent fournir des helpers explicites basés sur `serde_json::to_string` et `serde_json::to_string_pretty`.
|
||||
|
||||
## Règles de configuration
|
||||
|
||||
- La configuration applicative commune doit passer par `kb-config`.
|
||||
- Les fichiers JSON de configuration ne doivent pas contenir de commentaires.
|
||||
- Les secrets ne doivent pas être écrits en clair dans le dépôt.
|
||||
- Les valeurs sensibles doivent utiliser des variables d'environnement ou un stockage chiffré dédié.
|
||||
- Les structures de configuration exposées à Tauri doivent dériver `TS`.
|
||||
|
||||
## Ordre de développement cible
|
||||
|
||||
- `kb-logging` doit être stabilisé avant les logs avancés des autres crates.
|
||||
- `kb-config` doit être stabilisé avant les stores, RPC, wallet et applications.
|
||||
- Les contrats SQL et de matérialisation doivent être définis avant les gros décodeurs DEX.
|
||||
- Les implémentations détaillées des matérialisateurs doivent suivre les sorties réelles des décodeurs correspondants.
|
||||
- `kb-app-demo` doit fournir des validations live après chaque capacité majeure, sans créer une application Tauri séparée par crate.
|
||||
|
||||
## Règles de livraison ChatGPT
|
||||
|
||||
- Après le squelette initial, ChatGPT doit fournir uniquement des zips delta sauf demande explicite de zip complet.
|
||||
- Un delta qui modifie la racine du workspace ou plusieurs modules doit être nommé `khadhroony-bot3_vX.Y.Z-pre.abc-delta.zip`.
|
||||
- Un delta qui ne modifie qu'un seul module Rust doit être nommé `kb_modulename_vX.Y.Z-pre.abc-delta.zip`.
|
||||
- Lorsqu'un delta `pre.abc` a déjà été livré et qu'un correctif est nécessaire, le numéro `abc` ne doit pas être incrémenté. Le correctif doit être nommé `khadhroony-bot3_vX.Y.Z-pre.abc-delta-fix-001.zip`, puis `-fix-002.zip`, etc. Pour un seul module, utiliser la même règle avec le nom de package.
|
||||
- Un correctif doit indiquer dans `delta.md` le delta de base et les correctifs antérieurs à appliquer. Il ne doit pas réutiliser silencieusement le nom ou l'empreinte d'une archive déjà livrée.
|
||||
- Le numéro `pre.abc` suivant est réservé à une nouvelle tranche fonctionnelle, pas à la réparation d'une archive existante.
|
||||
- Chaque zip delta ou correctif doit contenir un fichier `delta.md` non versionné à la racine du zip.
|
||||
- `delta.md` doit lister les fichiers ajoutés, les fichiers modifiés, les fichiers à supprimer manuellement, les validations exécutées et les validations non exécutées.
|
||||
- Le zip delta ne doit pas contenir de fichiers inchangés.
|
||||
- Le zip delta ne doit pas modifier `CHANGELOG.md` sauf validation explicite d'une version.
|
||||
- Les suppressions de fichiers ou dossiers doivent être indiquées dans `delta.md`, car l'extraction d'un zip ne supprime pas automatiquement les anciens fichiers.
|
||||
- Les prompts de session doivent rappeler ce format de livraison et la règle `delta-fix-NNN`.
|
||||
|
||||
## Constantes des composants de `kb-lib`
|
||||
|
||||
- Chaque composant classifié avec un `program_id` doit avoir son propre fichier `constants.rs`.
|
||||
- `constants.rs` contient les discriminators, sélecteurs, opcodes, constantes Borsh et constantes de décodage quand elles sont connues.
|
||||
- Le module parent puis `kb-lib/src/lib.rs` réexportent les constantes publiques nécessaires.
|
||||
- Les fichiers d'implémentation utilisent le chemin public le plus court réexporté par `kb-lib`.
|
||||
- Les literals de `program_id` ne doivent pas rester dans `program_ids()`, sauf dans un fichier `constants.rs`.
|
||||
|
||||
## Identifiants de programmes
|
||||
|
||||
Les `program_id` connus doivent être définis une seule fois dans `kb-program-ids`. Les composants de décodeur, d’exécuteur, de store, d’application ou d’outil doivent référencer directement `kb_program_ids::XXX_PROGRAM_ID`. Les fichiers `constants.rs` locaux ne doivent pas redéfinir ces chaînes ; ils restent réservés aux constantes internes du module, par exemple discriminators, opcodes, seeds, index de comptes ou layouts.
|
||||
|
||||
## Validation frontend Tauri
|
||||
|
||||
- Pour `kb-app-demo`, ne pas lancer `npm --prefix kb-app-demo run build` séparément : la validation frontend de développement est réalisée par `cargo tauri dev -c kb-app-demo/tauri.conf.json`, qui démarre et pilote le serveur Vite.
|
||||
|
||||
## Architecture `khadhroony-bot3`
|
||||
|
||||
- Les décodeurs, exécuteurs et matérialisateurs résident exclusivement dans `kb-lib`.
|
||||
- Les modules peuvent posséder leur propre fichier de constantes.
|
||||
- Toute API publique portée depuis une ancienne crate doit être réexportée au crate root de `kb-lib`.
|
||||
- `kb-store` regroupe les contrats store-neutral et les adaptateurs de persistance, avec PostgreSQL comme adaptateur de production initial.
|
||||
- `kb-store/src/lib.rs` reste une façade : les DTO, entités, traits, requêtes et implémentations résident dans des modules privés dédiés et toute API publique est réexportée au crate root.
|
||||
- Les modèles source-neutral partagés avec les décodeurs, notamment `MdCoreInstructionReplayInput`, appartiennent à `kb-lib`; `kb-store` les consomme et les réexporte sans les dupliquer.
|
||||
- `kb-lib` ne dépend jamais de `kb-store`. Cette direction de dépendance évite tout cycle entre modèles, décodage et persistance.
|
||||
- `kb-store` ne dépend pas de `kb-config`. La frontière applicative transforme une configuration résolue en options de store explicitement validées.
|
||||
- Les adaptateurs concrets implémentent les mêmes traits neutres et ne font pas fuiter leurs types de connexion dans les contrats.
|
||||
- Seul `kb-app-demo` est conservé comme binaire pendant la migration initiale.
|
||||
La migration ne peut être déclarée terminée qu’après validation de la checklist active et des critères de clôture.
|
||||
|
||||
87
RULES_GENERAL.md
Normal file
87
RULES_GENERAL.md
Normal file
@@ -0,0 +1,87 @@
|
||||
<!-- file: RULES_GENERAL.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Règles générales du projet
|
||||
|
||||
## Hiérarchie normative
|
||||
|
||||
- Les règles sont réparties entre `RULES_GENERAL.md`, `RULES_RUST.md` et `RULES_SPECIFIC_KHADHROONY.md`.
|
||||
- Les trois fichiers sont normatifs et cumulatifs.
|
||||
- En cas de conflit, la règle la plus stricte s’applique.
|
||||
- Une règle spécifique ne peut jamais assouplir une règle générale sans exception explicite, bornée et documentée.
|
||||
- `RULES.md` est l’index de lecture obligatoire et ne duplique pas les règles détaillées.
|
||||
- Avant toute tranche de travail, relire les quatre fichiers de règles, le prompt actif, `README.md`, `ROADMAP.md` et `CHANGELOG.md`.
|
||||
- Toute divergence documentaire est corrigée avant le code.
|
||||
|
||||
## Fichiers et nomenclature documentaire
|
||||
|
||||
- Tous les noms de fichiers et de répertoires sont en anglais, sans accent, espace ou caractère spécial inutile.
|
||||
- Les fichiers Markdown du projet sont rédigés en français, sauf contrat externe ou documentation technique devant rester en anglais.
|
||||
- Tout fichier texte qui supporte des commentaires commence par son chemin relatif et une version entière.
|
||||
- Chaque fichier texte se termine par exactement une fin de ligne.
|
||||
- Les documents livrés sont au format Markdown lorsqu’un format textuel suffit.
|
||||
|
||||
## Responsabilités documentaires
|
||||
|
||||
- `README.md` décrit le projet, son rôle, ses objectifs et son organisation ; il ne sert pas de changelog.
|
||||
- `ROADMAP.md` contient les futures étapes, versions et changements prévus.
|
||||
- `CHANGELOG.md` n’est modifié qu’après validation explicite d’une version.
|
||||
- Les documents de session et checklists conservent des critères d’acceptation vérifiables.
|
||||
- Chaque crate publique possède un `README.md` ou `001.README.md` et, à la clôture de la migration, un `USAGES.md`.
|
||||
- Une API publique ajoutée ou modifiée n’est pas considérée comme documentée tant que la documentation de sa crate n’est pas synchronisée.
|
||||
|
||||
## Travail par tranches
|
||||
|
||||
- Commencer par les règles et les audits structurels.
|
||||
- Travailler par deltas courts et cohérents.
|
||||
- Corriger immédiatement les erreurs locales remontées.
|
||||
- Ne pas masquer les erreurs métier par des exceptions globales.
|
||||
- Ne pas déclarer une tâche validée sans commande, test, audit ou contrôle runtime correspondant.
|
||||
- Une validation non exécutée doit être indiquée comme telle.
|
||||
|
||||
## Frontières JSON et JavaScript
|
||||
|
||||
- Tout payload de commande, d’événement ou d’IPC traversant une frontière JSON ne doit jamais exiger un `bigint` JavaScript.
|
||||
- Pour un entier Rust borné et garanti représentable par l’interface, utiliser un override TS-rs `number`.
|
||||
- Lorsque l’exactitude au-delà de `Number.MAX_SAFE_INTEGER` est nécessaire, sérialiser explicitement une chaîne décimale côté Rust et exporter `string`.
|
||||
- Ne jamais construire un `BigInt` dans un objet transmis à une commande, un événement ou une API sérialisée en JSON.
|
||||
|
||||
## Helpers de contrôle
|
||||
|
||||
- Les scripts Python, shell ou autres helpers d’audit sont strictement en lecture seule vis-à-vis du code et de la documentation contrôlés.
|
||||
- Un helper peut rechercher, analyser et signaler des erreurs ou motifs potentiellement suspects, mais ne doit jamais réécrire, reformater, renommer, supprimer ou corriger automatiquement un fichier du workspace.
|
||||
- Les résultats des helpers sont des diagnostics à vérifier ; une recherche heuristique ou regex ne constitue pas à elle seule une preuve de non-conformité.
|
||||
- Les helpers peuvent inclure des recherches regex ciblées, notamment sur les chemins Rust longs comme `crate::module::Item`, afin de faciliter une revue manuelle des façades et réexports.
|
||||
- Toute modification du code reste une action explicite, séparée de l’audit, et doit apparaître dans le delta correspondant.
|
||||
|
||||
## Livraisons delta
|
||||
|
||||
- Après le squelette initial, livrer uniquement des ZIP delta sauf demande explicite d’archive complète.
|
||||
- Un delta touchant la racine ou plusieurs modules se nomme `khadhroony-bot3_vX.Y.Z-pre.abc-delta.zip`.
|
||||
- Un delta limité à un package Rust se nomme `kb-modulename_vX.Y.Z-pre.abc-delta.zip`.
|
||||
- Un correctif d’un delta déjà livré conserve le même numéro de prerelease et utilise `-delta-fix-001.zip`, puis `-fix-002.zip`, etc.
|
||||
- La numérotation des correctifs recommence à `fix-001` pour chaque nouvelle prerelease.
|
||||
- Le numéro de prerelease suivant est réservé à une nouvelle tranche fonctionnelle.
|
||||
- Chaque archive contient un `delta.md` à sa racine. Son titre et son en-tête ne contiennent aucun numéro de version, de prerelease ou de correctif.
|
||||
- `delta.md` liste : base requise, correctifs antérieurs requis, fichiers ajoutés, fichiers modifiés, fichiers à supprimer, validations exécutées, validations non exécutées et remarques d’application.
|
||||
- Chaque fichier à supprimer est accompagné d’une commande indépendante `rm -- <chemin>` directement copiable depuis la racine du workspace.
|
||||
- Le ZIP ne contient que les fichiers ajoutés ou modifiés et `delta.md`.
|
||||
- Les suppressions sont documentées dans `delta.md`, car l’extraction d’un ZIP ne supprime rien.
|
||||
- Toute livraison exclut les fichiers locaux, secrets, caches, sorties de compilation et artefacts régénérables, même lorsqu’ils existent dans le workspace de développement.
|
||||
- Sont notamment exclus : `Cargo.lock`, `package-lock.json`, `node_modules/`, `target/`, `dist/`, `gen/`, les bindings TS-RS générés, `__pycache__/`, les logs, les PID, les bases locales, `data/`, `dbdata/`, les fichiers d’IDE et les fichiers de configuration locale.
|
||||
- Les fichiers `.env` et `.env.*` sont exclus, sauf exemples explicitement publiables tels que `.env.example` et profils sans secret expressément autorisés.
|
||||
- `Cargo.lock` peut être nécessaire dans le workspace local pour stabiliser une résolution transitive, mais il reste non versionné et non livrable dans ce projet.
|
||||
- `package-lock.json` reste non versionné et non livrable ; les dépendances frontend sont restaurées depuis `package.json`.
|
||||
- `delta.md` constitue l’unique exception aux motifs locaux `delta*.md` : il est généré pour la livraison et doit être placé à la racine du ZIP.
|
||||
- Aucun manifeste de livraison n’est généré ou inclus : ni `manifest.json`, ni manifeste SHA, ni liste de checksums.
|
||||
- Aucune empreinte SHA256 n’est produite ou incluse dans les livraisons.
|
||||
- Une archive déjà livrée ne doit jamais être remplacée silencieusement sous le même nom.
|
||||
|
||||
## Contrôle minimal avant livraison
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
```
|
||||
|
||||
Les validations supplémentaires dépendent du périmètre du delta et sont consignées dans `delta.md`.
|
||||
@@ -1,9 +1,9 @@
|
||||
<!-- file: RUST_RULES.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- file: RULES_RUST.md -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Règles Rust générales
|
||||
|
||||
Ce fichier contient les règles normatives applicables à tous les projets Rust. Elles sont indépendantes de `khadhroony-bot2` et doivent pouvoir être réutilisées telles quelles dans un autre workspace.
|
||||
Ce fichier contient les règles normatives applicables à tous les projets Rust. Elles sont indépendantes de `khadhroony-bot3` et doivent pouvoir être réutilisées telles quelles dans un autre workspace.
|
||||
|
||||
## En-têtes et versions de fichiers
|
||||
|
||||
232
RULES_SPECIFIC_KHADHROONY.md
Normal file
232
RULES_SPECIFIC_KHADHROONY.md
Normal file
@@ -0,0 +1,232 @@
|
||||
<!-- file: RULES_SPECIFIC_KHADHROONY.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Règles spécifiques à `khadhroony-bot3`
|
||||
|
||||
Ce fichier contient uniquement les règles d’architecture, de nomenclature et d’exploitation propres à `khadhroony-bot3`. Il est cumulatif avec [`RULES_GENERAL.md`](RULES_GENERAL.md) et [`RULES_RUST.md`](RULES_RUST.md).
|
||||
|
||||
Toute divergence avec une règle générale doit être explicitement documentée et ne peut jamais affaiblir une interdiction de sécurité ou de qualité.
|
||||
|
||||
## Règles de nommage
|
||||
|
||||
- Tous les noms de fichiers et de répertoires doivent être écrits en anglais.
|
||||
- Les noms de fichiers et de répertoires ne doivent contenir aucun accent, espace ou caractère spécial inutile.
|
||||
- Les noms internes doivent utiliser le format `snake_case` lorsque c'est applicable.
|
||||
- Les packages Rust utilisent le préfixe `kb-` ; leur identifiant Rust correspondant utilise automatiquement `kb_`.
|
||||
- Les décodeurs, matérialisateurs et exécuteurs sont des modules de `kb-lib`, pas des crates séparées.
|
||||
- Le crate de journalisation s'appelle `kb-logging`.
|
||||
- Les réexports sont regroupés par visibilité : le bloc `pub use` précède le bloc séparé `pub(crate) use`, sans ligne vide interne à un bloc ; leur ordre naturel doit rester compatible avec `cargo fmt`.
|
||||
- Les familles de symboles consolidées dans `kb-lib` utilisent les préfixes `DC_`/`Dc`/`decoder_` pour les décodeurs, `MT_`/`Mt`/`materializer_` pour les matérialisateurs, `EX_`/`Ex`/`executor_` pour les exécuteurs et `MD_`/`Md`/`model_` pour les modèles.
|
||||
- Les méthodes inhérentes et helpers strictement privés peuvent conserver un nom local court ; les préfixes s’appliquent aux constantes, types, traits et fonctions libres exposés à la crate ou hors de la crate.
|
||||
- Les constantes temporaires `*_LEGACY_CRATE`, `*_MIGRATION_STATUS` et `*_MIGRATION_BOUNDARIES` doivent disparaître d’une famille dès que ses squelettes typés sont restaurés ; elles ne constituent jamais une API durable.
|
||||
|
||||
## Règles Tauri et TypeScript
|
||||
|
||||
- Toute structure ou énumération Rust exposée au frontend TypeScript doit importer le trait `TS` avec `use ts_rs::TS;` puis dériver `TS`.
|
||||
- Les types Rust exportés vers TypeScript doivent utiliser des noms stables et explicites.
|
||||
- Les bindings générés doivent être produits dans un dossier dédié, généralement `../frontend/ts/bindings` ou `#[ts(export, export_to = "../frontend/ts/bindings/MyStruct.ts")]`.
|
||||
- Les types purement internes au backend ne doivent pas être exportés vers TypeScript par défaut.
|
||||
- Corriger le type Rust/TS-rs source puis régénérer les bindings ; ne pas considérer une modification manuelle isolée d’un fichier généré comme un correctif durable.
|
||||
|
||||
## Règles d'architecture
|
||||
|
||||
- Les décodeurs ne dépendent pas de PostgreSQL, SQLite, RPC, Tauri, wallet, stratégie ou matérialisateurs.
|
||||
- Les matérialisateurs ne dépendent pas du RPC, du wallet, de Tauri ou des décodeurs spécifiques.
|
||||
- Pour chaque programme Solana, quelle que soit sa famille, un décodeur doit couvrir maximalement tout wire officiellement identifiable de sa surface, qu'il soit historique, courant, récent, expérimental ou publié avant son déploiement généralisé. Ces statuts doivent rester explicites et ne constituent pas un motif pour supprimer le décodage.
|
||||
- Une observation lisible issue d'une transaction échouée peut conserver une intention non commitée ; elle ne doit jamais être présentée comme une mutation réussie.
|
||||
- Pour chaque programme Solana, les matérialisateurs doivent projeter maximalement tous les faits métier stables et prouvés par le décodage, y compris les états historiques, obsolètes, dépréciés ou seulement rencontrables pendant un backfill. Le statut historique interdit l'exécution, mais ne constitue jamais à lui seul un motif de non-matérialisation.
|
||||
- Toute projection historique doit conserver explicitement son lifecycle, sa version de layout, sa provenance, son slot ou ordre d'observation lorsqu'ils sont connus, et ne doit jamais écraser silencieusement un état actif plus récent.
|
||||
- Une même réalité métier doit avoir une seule projection canonique. Les snapshots de comptes sont la source autoritative de l'état final lorsqu'ils sont disponibles ; les instructions et événements corrélés restent des observations de mutation et ne doivent pas produire un doublon concurrent du même état.
|
||||
- Les matérialisateurs doivent refuser les transactions non commitées pour les mutations d'état, tout en pouvant conserver séparément une intention non commitée lorsque le modèle métier le prévoit explicitement.
|
||||
- Toute absence volontaire de projection doit être documentée avec une justification technique précise. Un matérialisateur ne doit inventer ni état final, ni montant, ni autorité, ni frais, ni agrégation que l'observation ne prouve pas.
|
||||
- Pour chaque programme Solana, les exécuteurs doivent couvrir maximalement les opérations officiellement appelables et les opérations expérimentales publiées lorsque leurs contrats exacts et garde-fous sont prouvés. Les opérations historiques, dépréciées ou obsolètes doivent rester décodables et matérialisables, mais ne doivent jamais être exposées à l'exécution ; cette exclusion doit être explicite dans la matrice et le README.
|
||||
- `kb-store` possède les contrats de persistance neutres et les adaptateurs de base de données.
|
||||
- PostgreSQL est l'adaptateur de production de `kb-store`.
|
||||
- Un futur adaptateur SQLite doit rester interne à `kb-store` et limité aux tests, imports et corpus locaux.
|
||||
- `kb-wallet` reste isolé du reste du système.
|
||||
- Les transactions raw sont immuables et restent la source d'audit.
|
||||
- Les replays doivent être ciblés par module, version, programme, surface, discriminator, slot ou signatures.
|
||||
- La documentation active du projet ne doit pas présenter l'ancien workspace comme architecture courante. Les documents de migration et copies de référence peuvent le nommer explicitement.
|
||||
|
||||
## Nomenclature métier
|
||||
|
||||
- `protocol_code` désigne la famille : `pump`, `raydium`, `meteora`, `orca`, `jupiter`, etc.
|
||||
- `surface_code` désigne la surface concrète : `pump_swap`, `raydium_amm_v4`, `meteora_dlmm`, etc.
|
||||
- `event_code` suit le format `<surface_code>.<event_name>`.
|
||||
- Les familles d'événements principales sont : `trade`, `liquidity`, `lifecycle`, `fee`, `admin`, `reward`, `orderbook`, `token_account`, `pool_state`, `routing`, `risk`, `audit`, `unknown`.
|
||||
|
||||
## Base de données
|
||||
|
||||
- Les schémas PostgreSQL cibles sont : `raw`, `core`, `obs`, `decode`, `mat`, `catalog`, `agg`, `ops`, `wallet`.
|
||||
- Les colonnes JSONB doivent se terminer par `_jsonb`.
|
||||
- Les montants bruts on-chain doivent se terminer par `_raw`.
|
||||
- La transaction canonique raw reste la source rejouable et ne doit pas être supprimée après traitement sans politique de rétention explicite.
|
||||
|
||||
## Nommage canonique des surfaces
|
||||
|
||||
Les nouvelles surfaces de programmes doivent utiliser un nom canonique basé sur la fonction réelle du programme :
|
||||
|
||||
```text
|
||||
<function_code>_<family_code>_<identifier_code>[_vN]
|
||||
```
|
||||
|
||||
Les modules internes de décodage doivent utiliser la hiérarchie de fichiers :
|
||||
|
||||
```text
|
||||
kb-lib/src/decoder/<function_code>/<family_code>_<identifier_code>[_vN].rs
|
||||
```
|
||||
|
||||
Exemples :
|
||||
|
||||
- `kb-lib/src/decoder/amm/raydium_cpmm.rs` ;
|
||||
- `kb-lib/src/decoder/clmm/raydium.rs` ;
|
||||
- `kb-lib/src/decoder/dlmm/meteora.rs` ;
|
||||
- `kb-lib/src/decoder/router/jupiter_aggregator_v6.rs` ;
|
||||
- `kb-lib/src/decoder/orderbook/openbook_v2.rs` ;
|
||||
- `kb-lib/src/decoder/metadata/metaplex_token_metadata.rs` ;
|
||||
- `kb-lib/src/decoder/nft/metaplex_bubblegum.rs`.
|
||||
|
||||
Ces modules restent privés. Les consommateurs externes utilisent exclusivement les types et fonctions réexportés directement par `kb_lib`.
|
||||
|
||||
Les noms historiques ou issus d'IDL doivent être conservés dans le registre, mais ne doivent pas créer de nouveau module si un module canonique existe déjà.
|
||||
|
||||
Aucun renommage massif de modules n'est autorisé sans étape de contrôle dédiée et sans validation Cargo.
|
||||
|
||||
## Règles de nommage des surfaces Solana
|
||||
|
||||
- Le nom canonique d'une surface doit commencer par une fonction réelle : `amm`, `clmm`, `dlmm`, `router`, `orderbook`, `launchpad`, `lending`, `vault`, `staking`, `bridge`, `perpetuals`, `oracle`, `nft`, `metadata`, `admin`, etc.
|
||||
- Le préfixe `program_` est interdit pour les nouveaux noms canoniques.
|
||||
- Les surfaces non classifiées doivent utiliser `unknown_*` et ne doivent pas avoir de crate cible tant que leur fonction n'est pas validée.
|
||||
- Les programmes Solana/SPL primitifs doivent rester séparés des surfaces DEX/router dans la documentation de contrôle.
|
||||
- `damm` ne doit pas être utilisé comme préfixe fonctionnel ; utiliser `amm_meteora_damm_v1` ou `amm_meteora_damm_v2`.
|
||||
|
||||
## Registre des identifiants core
|
||||
|
||||
- Les identifiants Solana/SPL primitifs doivent être tenus à jour dans `registry/core_program_id_seed.toml`.
|
||||
- Les sysvars et comptes natifs connus ne doivent pas être classés comme surfaces DEX/router.
|
||||
- `spl_token`, `spl_token2022` et `associated_token_account` restent des surfaces spécialisées ; les noms historiques de crates externes conservent leur graphie officielle.
|
||||
- `stake_pool` doit être réservé à un futur crate spécialisé plutôt que mélangé avec le programme `stake`.
|
||||
|
||||
## Index court de programme
|
||||
|
||||
- Les noms de modules ne doivent pas commencer par un index hexadécimal.
|
||||
- Un champ `registry_code` optionnel peut être ajouté au registre pour l'UI, PostgreSQL ou les matrices.
|
||||
- Le nom canonique reste la source principale : fonction + famille + identifiant + version.
|
||||
|
||||
## Comptes non exécutables
|
||||
|
||||
- Une adresse de compte, de pool, de PDA ou de vault ne doit pas générer un module de décodeur.
|
||||
- Le vrai `program_id` propriétaire doit être prouvé avant création d'une surface canonique.
|
||||
|
||||
## Constantes Rust
|
||||
|
||||
- Les fichiers `program_ids.rs` sont interdits dans les nouveaux crates. Utiliser `constants.rs`.
|
||||
- Les `program_id` publics doivent être réexportés depuis `lib.rs`.
|
||||
- Dans une crate, les modules internes doivent appeler les constantes réexportées via `crate::CONSTANT_NAME`.
|
||||
- Les discriminants, sélecteurs, longueurs Borsh et constantes internes futures doivent être placés dans `constants.rs` et rester `pub(crate)` sauf besoin d'API publique explicite.
|
||||
|
||||
## Règles de tracing
|
||||
|
||||
- Une crate ou un composant de `kb-lib` est opérationnel lorsqu’il effectue des I/O, orchestre un pipeline, décode, matérialise, exécute, applique une politique runtime ou prend une décision mutable observable.
|
||||
- Toute crate opérationnelle ajoutée ou modifiée doit dépendre de `tracing` depuis le workspace et déclarer exactement un `pub(crate) const TRACING_TARGET` dans `src/constants.rs`.
|
||||
- Hors `kb-lib`, la valeur canonique de `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` est le nom exact du package Cargo.
|
||||
- Dans `kb-lib`, chaque composant opérationnel possède son propre `constants.rs` et un target hiérarchique stable fondé sur son identifiant de décodeur, matérialiseur ou exécuteur ; un target unique `kb-lib` ne doit pas effacer l'identité du composant.
|
||||
- Les targets historiques `khbot.*` et les targets de fenêtre sont interdits dans les nouvelles modifications.
|
||||
- Les macros `tracing` doivent utiliser `target: crate::TRACING_TARGET` et des champs structurés stables. La granularité interne passe par `action`, `stage`, `window`, `campaign_id`, `signature`, `instruction_path`, `program_id`, `processor_name`, `processor_version`, `status` et `error_code`.
|
||||
- Les crates passives de types, contrats, DTO, API sans exécution, registres ou constantes restent sans dépendance `tracing`. `kb-config` reste une exception de bootstrap tant que sa validation précède l’installation du subscriber.
|
||||
- Il est interdit d’ajouter `tracing` sans événement réel ou de conserver un faux target uniquement consommé par `let _target`.
|
||||
- Une décision interne doit être journalisée par la crate responsable ; `kb-app-demo-desktop` ne journalise que les frontières Tauri/UI, les actions utilisateur et les résumés d’orchestration.
|
||||
- Tout input sélectionné sans décodeur compatible, tout résultat de décodage `failed` ou `unsupported`, tout résultat de matérialisation `failed`, toute validation de résultat invalide et toute erreur de persistance doivent émettre un événement `error` avant le retour ou la persistance terminale.
|
||||
- Une transaction Solana échouée mais correctement décodée n’est pas une erreur du logiciel. Une décision `ignored`, un refus de matérialisation conforme à la politique ou une annulation coopérative ne doivent pas être promus artificiellement au niveau `error`.
|
||||
- Les erreurs de décodage et de matérialisation doivent conserver au minimum, lorsque disponibles : `campaign_id`, `signature`, `slot`, `instruction_path`, `program_id`, processor ou materializer avec version, `input_key`, `input_hash` ou hash du payload, statut, code et diagnostic borné.
|
||||
- Les payloads complets, DSN non masqués, secrets, clés privées et données non bornées sont interdits dans les logs.
|
||||
- Chaque profil doit router les événements vers les sorties globales `debug.log`, `info.log`, `error.jsonl` et `app.log`, puis vers `debug.log`, `info.log` et `error.jsonl` dans un répertoire propre à chaque crate utilisant `tracing`.
|
||||
- L’ajout ou la suppression de `tracing.workspace = true` dans une crate impose la mise à jour simultanée de la matrice de routes, de ses tests et de `docs/TRACING_CONTRACT.md`.
|
||||
- Le contrat détaillé est défini dans `docs/TRACING_CONTRACT.md`.
|
||||
- L’audit mécanique spécifique au projet est exécuté par `python3 scripts/audit_khadhroony_workspace_rules.py`. Il couvre notamment `TRACING_TARGET_DECODER_METADATA_METAPLEX_TOKEN_METADATA` et l’usage obligatoire de `solana_pubkey::Pubkey` à la place de `solana_address::Address`.
|
||||
|
||||
## Règles de réutilisation des interfaces Solana et SPL
|
||||
|
||||
- Les dépendances déclarées dans `[workspace.dependencies]` forment un catalogue de versions et de features autorisées ; elles ne doivent être ajoutées à une crate consommatrice que lorsqu’un type, un encodeur, un décodeur ou un identifiant officiel est réellement utilisé.
|
||||
|
||||
- Dans un `Cargo.toml`, placer dans `[dependencies]` toute crate référencée par le code de bibliothèque compilé en production. Réserver `[dev-dependencies]` aux références contenues exclusivement dans `#[cfg(test)]`, les tests d’intégration, benches ou exemples. Une dépendance de test vers un décodeur ou matérialiseur concret est légitime lorsqu’elle sert uniquement à éprouver une orchestration générique fondée sur les traits API ; elle ne prouve pas qu’une capacité de production manque. Toute promotion de `dev-dependencies` vers `dependencies` doit être motivée par un appel runtime réel, et toute dépendance runtime inutilisée doit être supprimée.
|
||||
- Les registres de composition runtime des applications doivent énumérer explicitement chaque décodeur et matérialiseur concret activé. Toute nouvelle surface instructionnelle dotée d’un `MtApiEventMaterializer` doit être ajoutée au registre applicatif et couverte par un test d’inventaire ordonné ; une crate présente dans le workspace ou dans `kb_pipeline` n’est pas activée automatiquement. Les matérialiseurs exclusivement stateful qui n’implémentent pas `MtApiEventMaterializer` restent routés par leurs APIs de snapshots dédiées.
|
||||
- Les corrélations instruction/état doivent produire une issue explicite (`confirmed`, `contradicted` ou `not_applicable`) et ne doivent jamais transformer automatiquement une configuration observée en violation, score ou conclusion métier.
|
||||
- Une interface officielle Solana ou SPL étroite doit être préférée à `solana-sdk` lorsque son contrat suffit.
|
||||
- L’ordre de préférence des formats est : schéma officiel `wincode`, schéma officiel Borsh, puis parseur local borné reproduisant exactement le runtime lorsque l’interface officielle n’expose que `bincode`.
|
||||
- Aucun nouveau code ne doit dépendre directement de `bincode`. Une interface officielle uniquement disponible derrière une feature `bincode` ne justifie pas l’activation de cette feature ; le layout doit alors être prouvé depuis les sources officielles et implémenté localement avec des bornes et des tests.
|
||||
- Les exécuteurs doivent utiliser les builders officiels disponibles, préserver l’ordre exact des metas, borner toute liste de comptes variable avant l’appel au builder et refuser les doublons lorsque leur répétition n’a pas de sémantique publiée.
|
||||
- Les features des interfaces doivent rester minimales et explicites. Une feature `serde`, `wincode`, `borsh`, `std`, `alloc` ou équivalente n’est activée que si la crate consommatrice l’utilise réellement.
|
||||
- Les crates applicatives ne doivent pas dépendre d’interfaces RPC ou transactionnelles uniquement pour relayer des types ; ces dépendances appartiennent à `kb_onchain_transport`, aux modèles communs justifiés ou à la crate opérationnelle propriétaire.
|
||||
- Toute exception et toute implémentation locale doivent être documentées dans `docs/SOLANA_INTERFACE_DEPENDENCIES.md` avec la raison, la source officielle et la stratégie de test.
|
||||
- Tant que les types Solana consommés implémentent les traits de `wincode 0.5.x`, le catalogue
|
||||
workspace conserve `wincode = "^0.5"`. Le `Cargo.lock` local du workspace doit résoudre exactement
|
||||
`wincode 0.5.5` avec `solana-wincode-varint 1.0.0` afin d’éviter l’incompatibilité observée entre
|
||||
les familles transitives `wincode 0.5` et `wincode 0.6`. Ce lockfile est un garde-fou local de
|
||||
résolution : il n’est ni versionné, ni inclus dans les archives. Une entrée inutilisée ne doit pas
|
||||
être ajoutée artificiellement aux dépendances d’une crate pour influencer le résolveur. L’audit
|
||||
spécifique du workspace refuse toute dérive de ce couple avant compilation lorsqu’un `Cargo.lock`
|
||||
local a été généré ou restauré.
|
||||
|
||||
## Règles des exécuteurs
|
||||
|
||||
- Les exécuteurs résident dans `kb_lib::executor`.
|
||||
- Une surface classifiée peut avoir un module décodeur et un module exécuteur distincts dans `kb-lib`.
|
||||
- Les exécuteurs ne doivent pas dépendre des décodeurs.
|
||||
- Les exécuteurs utilisent les contrats `ExApi*` réexportés directement par la façade `kb_lib`.
|
||||
- Un squelette d’exécuteur doit exposer un type `Ex*Executor`, référencer uniquement des Program IDs de `kb-program-ids`, annoncer `Maybe` pour sa surface et construire exclusivement un plan réservé à zéro instruction.
|
||||
- La migration fonctionnelle d’un exécuteur doit remplacer ce comportement réservé par des capacités exactes `Supported` ou `Unsupported(reason)` ; aucun statut temporaire `LEGACY_CRATE` ou `MIGRATION_STATUS` ne doit subsister.
|
||||
- Les garde-fous communs doivent être placés dans les modules de sécurité partagés de `kb-lib`.
|
||||
- Aucun exécuteur ne doit envoyer de transaction sans simulation et validation explicite.
|
||||
- Les surfaces non classifiées ne doivent pas avoir de crate exécuteur.
|
||||
- Pour chaque programme Solana et contrairement aux décodeurs, les exécuteurs ne construisent pas les opérations obsolètes ou purement historiques. Ils couvrent uniquement les opérations courantes et expérimentales officiellement constructibles, avec un statut exact `Supported` ou `Unsupported(reason)`.
|
||||
- Le statut expérimental, récent ou non encore déployé partout n'interdit pas un builder universel lorsqu'un wire officiel exact existe. Le déploiement, la simulation et l'autorisation d'envoi restent trois décisions séparées ; la bibliothèque ne doit pas imposer artificiellement un cluster.
|
||||
|
||||
|
||||
- Les champs JSON exposés à TypeScript ne doivent pas utiliser directement `serde_json::Value` avec `TS-rs`; utiliser une chaîne JSON sérialisée (`std::string::String`) ou un type Rust typé exportable.
|
||||
- Les APIs qui gardent des payloads dynamiques doivent fournir des helpers explicites basés sur `serde_json::to_string` et `serde_json::to_string_pretty`.
|
||||
|
||||
## Règles de configuration
|
||||
|
||||
- La configuration applicative commune doit passer par `kb-config`.
|
||||
- Les fichiers JSON de configuration ne doivent pas contenir de commentaires.
|
||||
- Les secrets ne doivent pas être écrits en clair dans le dépôt.
|
||||
- Les valeurs sensibles doivent utiliser des variables d'environnement ou un stockage chiffré dédié.
|
||||
- Les structures de configuration exposées à Tauri doivent dériver `TS`.
|
||||
|
||||
## Ordre de développement cible
|
||||
|
||||
- `kb-logging` doit être stabilisé avant les logs avancés des autres crates.
|
||||
- `kb-config` doit être stabilisé avant les stores, RPC, wallet et applications.
|
||||
- Les contrats SQL et de matérialisation doivent être définis avant les gros décodeurs DEX.
|
||||
- Les implémentations détaillées des matérialisateurs doivent suivre les sorties réelles des décodeurs correspondants.
|
||||
- `kb-app-demo-desktop` doit fournir des validations live après chaque capacité majeure, sans créer une application Tauri séparée par crate.
|
||||
|
||||
## Constantes des composants de `kb-lib`
|
||||
|
||||
- Chaque composant classifié avec un `program_id` doit avoir son propre fichier `constants.rs`.
|
||||
- `constants.rs` contient les discriminators, sélecteurs, opcodes, constantes Borsh et constantes de décodage quand elles sont connues.
|
||||
- Le module parent puis `kb-lib/src/lib.rs` réexportent les constantes publiques nécessaires.
|
||||
- Les fichiers d'implémentation utilisent le chemin public le plus court réexporté par `kb-lib`.
|
||||
- Les literals de `program_id` ne doivent pas rester dans `program_ids()`, sauf dans un fichier `constants.rs`.
|
||||
|
||||
## Identifiants de programmes
|
||||
|
||||
Les `program_id` connus doivent être définis une seule fois dans `kb-program-ids`. Les composants de décodeur, d’exécuteur, de store, d’application ou d’outil doivent référencer directement `kb_program_ids::XXX_PROGRAM_ID`. Les fichiers `constants.rs` locaux ne doivent pas redéfinir ces chaînes ; ils restent réservés aux constantes internes du module, par exemple discriminators, opcodes, seeds, index de comptes ou layouts.
|
||||
|
||||
## Validation frontend Tauri
|
||||
|
||||
- Pour `kb-app-demo-desktop`, ne pas lancer `npm --prefix kb-app-demo run build` séparément : la validation frontend de développement est réalisée par `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`, qui démarre et pilote le serveur Vite.
|
||||
|
||||
## Architecture `khadhroony-bot3`
|
||||
|
||||
- Les décodeurs, exécuteurs et matérialisateurs résident exclusivement dans `kb-lib`.
|
||||
- Les modules peuvent posséder leur propre fichier de constantes.
|
||||
- Toute API publique portée depuis une ancienne crate doit être réexportée au crate root de `kb-lib`.
|
||||
- `kb-store` regroupe les contrats store-neutral et les adaptateurs de persistance, avec PostgreSQL comme adaptateur de production initial.
|
||||
- `kb-store/src/lib.rs` reste une façade : les DTO, entités, traits, requêtes et implémentations résident dans des modules privés dédiés et toute API publique est réexportée au crate root.
|
||||
- Les modèles source-neutral partagés avec les décodeurs, notamment `MdCoreInstructionReplayInput`, appartiennent à `kb-lib`; `kb-store` les consomme et les réexporte sans les dupliquer.
|
||||
- `kb-lib` ne dépend jamais de `kb-store`. Cette direction de dépendance évite tout cycle entre modèles, décodage et persistance.
|
||||
- `kb-store` ne dépend pas de `kb-config`. La frontière applicative transforme une configuration résolue en options de store explicitement validées.
|
||||
- Les adaptateurs concrets implémentent les mêmes traits neutres et ne font pas fuiter leurs types de connexion dans les contrats.
|
||||
- Seul `kb-app-demo-desktop` est conservé comme binaire pendant la migration initiale.
|
||||
@@ -1,58 +1,74 @@
|
||||
<!-- file: docs/DELTA_WORKFLOW.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Workflow delta
|
||||
# Workflow de livraison delta
|
||||
|
||||
Après le squelette initial, les livraisons doivent être faites sous forme de zip delta.
|
||||
Les règles normatives de livraison sont définies dans [`../RULES_GENERAL.md`](../RULES_GENERAL.md). Ce document décrit leur application pratique.
|
||||
|
||||
## Nommage des zips
|
||||
## Nommage
|
||||
|
||||
Un delta qui touche la racine du workspace ou plusieurs modules doit utiliser :
|
||||
Delta multi-module ou racine :
|
||||
|
||||
```text
|
||||
khadhroony-bot2_vX.Y.Z-pre.abc.zip
|
||||
khadhroony-bot3_vX.Y.Z-pre.abc-delta.zip
|
||||
```
|
||||
|
||||
Un delta qui ne touche qu'un seul module Rust doit utiliser :
|
||||
Delta limité à un package :
|
||||
|
||||
```text
|
||||
kb_modulename_vX.Y.Z-pre.abc.zip
|
||||
kb-modulename_vX.Y.Z-pre.abc-delta.zip
|
||||
```
|
||||
|
||||
Exemples :
|
||||
Correctif d’une prerelease déjà livrée :
|
||||
|
||||
```text
|
||||
khadhroony-bot2_v0.1.0-pre.001.zip
|
||||
kb_logging_v0.1.0-pre.002.zip
|
||||
khadhroony-bot3_vX.Y.Z-pre.abc-delta-fix-001.zip
|
||||
```
|
||||
|
||||
## Fichier `delta.md`
|
||||
La numérotation des correctifs recommence à `fix-001` pour chaque nouvelle prerelease.
|
||||
|
||||
Chaque zip delta doit contenir un fichier `delta.md` non versionné à la racine du zip.
|
||||
## Contenu
|
||||
|
||||
`delta.md` doit indiquer :
|
||||
Chaque archive contient uniquement :
|
||||
|
||||
- les fichiers ajoutés ;
|
||||
- les fichiers modifiés ;
|
||||
- un `delta.md` non versionné à la racine.
|
||||
|
||||
Elle exclut :
|
||||
|
||||
- les fichiers inchangés ;
|
||||
- `Cargo.lock` ;
|
||||
- `package-lock.json` ;
|
||||
- `node_modules/`, `target/`, `dist/` et les autres sorties de build ;
|
||||
- `gen/`, les bindings TS-RS générés et tout autre code régénérable ;
|
||||
- les logs, caches, PID, bases et données locales ;
|
||||
- les fichiers `.env` réels et toute configuration contenant des secrets ;
|
||||
- les fichiers d’IDE ou propres à la machine ;
|
||||
- les empreintes SHA256 ;
|
||||
- les fichiers supprimés, qui doivent être indiqués comme suppressions manuelles.
|
||||
|
||||
`.env.example`, `.gitignore` et les autres fichiers source explicitement maintenus peuvent être livrés. `delta.md` est généré spécialement pour le ZIP et reste obligatoire même si les documents `delta*.md` sont ignorés dans le dépôt.
|
||||
|
||||
## Contrat de `delta.md`
|
||||
|
||||
`delta.md` indique obligatoirement :
|
||||
|
||||
- la base requise ;
|
||||
- les correctifs antérieurs requis ;
|
||||
- les fichiers ajoutés ;
|
||||
- les fichiers modifiés ;
|
||||
- les fichiers à supprimer manuellement ;
|
||||
- les validations exécutées ;
|
||||
- les validations non exécutées ;
|
||||
- les remarques de compatibilité ou d'application du delta.
|
||||
- les remarques d’application et de compatibilité.
|
||||
|
||||
## Contenu d'un delta
|
||||
## Application
|
||||
|
||||
Un delta contient uniquement :
|
||||
1. Partir de la base indiquée.
|
||||
2. Appliquer les deltas et correctifs antérieurs dans l’ordre indiqué.
|
||||
3. Extraire l’archive à la racine du workspace.
|
||||
4. Effectuer les suppressions manuelles listées dans `delta.md`.
|
||||
5. Lancer les validations demandées.
|
||||
|
||||
- les fichiers ajoutés ;
|
||||
- les fichiers modifiés ;
|
||||
- `delta.md`.
|
||||
|
||||
Il ne doit pas contenir de fichiers inchangés.
|
||||
|
||||
## Règles
|
||||
|
||||
- Ne pas renvoyer un zip complet sauf demande explicite.
|
||||
- Ne pas modifier `CHANGELOG.md` avant validation d'une version.
|
||||
- Placer les évolutions prévues dans `ROADMAP.md`.
|
||||
- Garder `README.md` descriptif.
|
||||
- Documenter les suppressions dans `delta.md`, car un zip ne supprime pas les anciens fichiers à l'extraction.
|
||||
Une archive déjà livrée ne doit jamais être remplacée silencieusement sous le même nom.
|
||||
|
||||
39
docs/TEST_FIXTURE_CLASSIFICATION.md
Normal file
39
docs/TEST_FIXTURE_CLASSIFICATION.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Classification des fixtures de test
|
||||
|
||||
## Objet
|
||||
|
||||
Ce document inventorie les données structurées actuellement stockées sous `docs/` alors qu'elles sont consommées par le code ou les tests. Le répertoire `docs/` reste réservé à la documentation destinée à une lecture humaine.
|
||||
|
||||
## Destination retenue
|
||||
|
||||
Les matrices partagées doivent être déplacées sous :
|
||||
|
||||
```text
|
||||
test-fixtures/contract-matrices/
|
||||
```
|
||||
|
||||
Le déplacement sera effectué dans une tranche fonctionnelle atomique avec la mise à jour de tous les chemins `include_str!`, des références documentaires et des tests concernés.
|
||||
|
||||
## Inventaire
|
||||
|
||||
| Fichier actuel | Consommateurs Rust détectés | Classification cible |
|
||||
|---|---:|---|
|
||||
| `docs/METAPLEX_TOKEN_METADATA_MATRIX.json` | 2 | fixture contractuelle partagée |
|
||||
| `docs/NATIVE_SOLANA_DECODER_MATRIX.json` | 1 | fixture contractuelle partagée |
|
||||
| `docs/NATIVE_SOLANA_EXECUTION_MATRIX.json` | 1 | fixture contractuelle partagée |
|
||||
| `docs/SOLANA_STANDARD_RPC_MATRIX.json` | 1 | fixture contractuelle partagée |
|
||||
| `docs/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json` | 4 | fixture contractuelle partagée |
|
||||
| `docs/SPL_ELGAMAL_REGISTRY_MATRIX.json` | 0 | usage à confirmer avant déplacement |
|
||||
| `docs/SPL_MEMO_MATRIX.json` | 3 | fixture contractuelle partagée |
|
||||
| `docs/SPL_TOKEN2022_MATRIX.json` | 2 | fixture contractuelle partagée |
|
||||
| `docs/SPL_TOKEN2022_VALIDATION_MATRIX.json` | 1 | fixture contractuelle partagée |
|
||||
| `docs/SPL_TOKEN_MATRIX.json` | 2 | fixture contractuelle partagée |
|
||||
|
||||
## Contraintes de migration
|
||||
|
||||
- Ne pas déplacer un fichier sans mettre à jour tous ses consommateurs dans le même delta.
|
||||
- Ne pas laisser une copie durable sous `docs/`.
|
||||
- Conserver les noms actuels sauf justification explicite.
|
||||
- Ajouter les suppressions sous forme de commandes `rm -- ...` dans `delta.md`.
|
||||
- Exécuter les tests de chaque crate consommatrice après le déplacement.
|
||||
- Les helpers d'audit restent en lecture seule et signalent uniquement les emplacements suspects.
|
||||
@@ -2773,7 +2773,7 @@ mod tests {
|
||||
}
|
||||
}
|
||||
let matrix: serde_json::Value = match serde_json::from_str(include_str!(
|
||||
"../../../../../docs/METAPLEX_TOKEN_METADATA_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/METAPLEX_TOKEN_METADATA_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("matrix parse failed: {error}"),
|
||||
|
||||
@@ -144,8 +144,9 @@ impl crate::DcApiInstructionDecoder for crate::DcMetadataMetaplexTokenMetadataDe
|
||||
mod tests {
|
||||
use base64::Engine; // rust-rules: trait-import
|
||||
|
||||
const AUDIT_MATRIX_JSON: &str =
|
||||
include_str!("../../../../../docs/METAPLEX_TOKEN_METADATA_MATRIX.json");
|
||||
const AUDIT_MATRIX_JSON: &str = include_str!(
|
||||
"../../../../../test-fixtures/contract-matrices/METAPLEX_TOKEN_METADATA_MATRIX.json"
|
||||
);
|
||||
const MAX_SDK_INSTRUCTION_MODULES: usize = 128;
|
||||
const MIN_SDK_INSTRUCTION_MODULES: usize = 90;
|
||||
const MIN_PDA_FAMILIES: usize = 8;
|
||||
|
||||
@@ -508,7 +508,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn native_decoder_matrix_matches_registry_surfaces_and_coverage() {
|
||||
let raw = include_str!("../../../../../docs/NATIVE_SOLANA_DECODER_MATRIX.json");
|
||||
let raw = include_str!(
|
||||
"../../../../../test-fixtures/contract-matrices/NATIVE_SOLANA_DECODER_MATRIX.json"
|
||||
);
|
||||
let parsed = match serde_json::from_str::<serde_json::Value>(raw) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
|
||||
@@ -143,7 +143,7 @@ impl crate::DcApiInstructionDecoder for crate::DcSplAssociatedTokenAccountDecode
|
||||
mod tests {
|
||||
fn matrix() -> serde_json::Value {
|
||||
return match serde_json::from_str(include_str!(
|
||||
"../../../../../docs/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("SPL ATA matrix is invalid: {error}"),
|
||||
|
||||
@@ -421,7 +421,7 @@ mod tests {
|
||||
#[test]
|
||||
fn matrix_is_machine_readable_and_covers_required_cases() {
|
||||
let parsed = serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"../../../../../docs/SPL_MEMO_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_MEMO_MATRIX.json"
|
||||
));
|
||||
let matrix = match parsed {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -246,8 +246,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn coverage_matrix_and_compiled_entries_are_equal() {
|
||||
let matrix: serde_json::Value =
|
||||
match serde_json::from_str(include_str!("../../../../../docs/SPL_TOKEN_MATRIX.json")) {
|
||||
let matrix: serde_json::Value = match serde_json::from_str(include_str!(
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_TOKEN_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("SPL Token matrix is invalid: {error}"),
|
||||
};
|
||||
@@ -274,8 +275,9 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn cluster_evidence_scopes_recent_instruction_deployment_exactly() {
|
||||
let matrix: serde_json::Value =
|
||||
match serde_json::from_str(include_str!("../../../../../docs/SPL_TOKEN_MATRIX.json")) {
|
||||
let matrix: serde_json::Value = match serde_json::from_str(include_str!(
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_TOKEN_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("SPL Token matrix is invalid: {error}"),
|
||||
};
|
||||
|
||||
@@ -491,7 +491,7 @@ mod tests {
|
||||
|
||||
fn matrix() -> serde_json::Value {
|
||||
return match serde_json::from_str(include_str!(
|
||||
"../../../../../docs/SPL_TOKEN2022_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_TOKEN2022_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("invalid Token-2022 matrix JSON: {error}"),
|
||||
|
||||
@@ -2484,7 +2484,9 @@ mod matrix_tests {
|
||||
|
||||
#[test]
|
||||
fn native_execution_matrix_matches_compiled_operation_registry() {
|
||||
let raw = include_str!("../../../../../docs/NATIVE_SOLANA_EXECUTION_MATRIX.json");
|
||||
let raw = include_str!(
|
||||
"../../../../../test-fixtures/contract-matrices/NATIVE_SOLANA_EXECUTION_MATRIX.json"
|
||||
);
|
||||
let parsed = match serde_json::from_str::<serde_json::Value>(raw) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
|
||||
@@ -260,7 +260,7 @@ mod tests {
|
||||
#[test]
|
||||
fn machine_readable_matrix_matches_compiled_executor_capabilities() {
|
||||
let matrix: serde_json::Value = serde_json::from_str(include_str!(
|
||||
"../../../../../docs/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
))
|
||||
.unwrap_or_else(|error| panic!("ATA matrix parsing failed: {error}"));
|
||||
let instructions = matrix["instructions"]
|
||||
|
||||
@@ -467,7 +467,7 @@ pub(crate) mod tests {
|
||||
#[test]
|
||||
fn machine_readable_matrix_matches_executor_policy() {
|
||||
let parsed = serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"../../../../../docs/SPL_MEMO_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_MEMO_MATRIX.json"
|
||||
))
|
||||
.unwrap_or_else(|error| panic!("Memo matrix parsing failed: {error}"));
|
||||
let contract = parsed
|
||||
|
||||
@@ -213,7 +213,7 @@ mod tests {
|
||||
#[test]
|
||||
fn machine_readable_matrix_matches_executor_policy() {
|
||||
let matrix = serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"../../../../../docs/SPL_TOKEN_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_TOKEN_MATRIX.json"
|
||||
))
|
||||
.unwrap_or_else(|error| panic!("matrix parsing failed: {error}"));
|
||||
let instructions = matrix["instructions"]
|
||||
|
||||
@@ -222,7 +222,7 @@ mod tests {
|
||||
#[test]
|
||||
fn machine_readable_matrix_matches_executor_policy() {
|
||||
let matrix = serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"../../../../../docs/SPL_TOKEN2022_MATRIX.json"
|
||||
"../../../../../test-fixtures/contract-matrices/SPL_TOKEN2022_MATRIX.json"
|
||||
))
|
||||
.unwrap_or_else(|error| panic!("matrix parsing failed: {error}"));
|
||||
let instructions = matrix["instructions"]
|
||||
|
||||
@@ -508,7 +508,7 @@ mod tests {
|
||||
#[test]
|
||||
fn ata_matrix_declares_the_single_compiled_risk_fact() {
|
||||
let matrix: serde_json::Value = match serde_json::from_str(include_str!(
|
||||
"../../../../docs/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
"../../../../test-fixtures/contract-matrices/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("ATA matrix is invalid: {error}"),
|
||||
|
||||
@@ -722,7 +722,7 @@ mod tests {
|
||||
#[test]
|
||||
fn ata_matrix_and_compiled_token_account_projection_ownership_are_equal() {
|
||||
let matrix: serde_json::Value = match serde_json::from_str(include_str!(
|
||||
"../../../../docs/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
"../../../../test-fixtures/contract-matrices/SPL_ASSOCIATED_TOKEN_ACCOUNT_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("ATA matrix is invalid: {error}"),
|
||||
|
||||
@@ -594,7 +594,7 @@ mod tests {
|
||||
#[test]
|
||||
fn machine_readable_matrix_declares_transaction_annotation_policy() {
|
||||
let parsed = serde_json::from_str::<serde_json::Value>(include_str!(
|
||||
"../../../../docs/SPL_MEMO_MATRIX.json"
|
||||
"../../../../test-fixtures/contract-matrices/SPL_MEMO_MATRIX.json"
|
||||
));
|
||||
let matrix = match parsed {
|
||||
std::result::Result::Ok(value) => value,
|
||||
|
||||
@@ -598,7 +598,8 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn standard_rpc_matrix_matches_compiled_inventory() {
|
||||
let raw = include_str!("../../docs/SOLANA_STANDARD_RPC_MATRIX.json");
|
||||
let raw =
|
||||
include_str!("../../test-fixtures/contract-matrices/SOLANA_STANDARD_RPC_MATRIX.json");
|
||||
let parsed = match serde_json::from_str::<serde_json::Value>(raw) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => panic!("rpc matrix parsing failed: {error}"),
|
||||
|
||||
@@ -112,7 +112,7 @@ pub struct Token2022ValidationMatrixScenario {
|
||||
/// Loads and validates the canonical Token-2022 validation matrix.
|
||||
pub fn load_token2022_validation_matrix() -> kb_core::Result<crate::Token2022ValidationMatrix> {
|
||||
let parsed = match serde_json::from_str::<crate::Token2022ValidationMatrix>(include_str!(
|
||||
"../../docs/SPL_TOKEN2022_VALIDATION_MATRIX.json"
|
||||
"../../test-fixtures/contract-matrices/SPL_TOKEN2022_VALIDATION_MATRIX.json"
|
||||
)) {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => {
|
||||
|
||||
@@ -20,7 +20,9 @@ Avant toute modification de code :
|
||||
|
||||
1. relire intégralement :
|
||||
- `RULES.md`
|
||||
- `RUST_RULES.md`
|
||||
- `RULES_GENERAL.md`
|
||||
- `RULES_RUST.md`
|
||||
- `RULES_SPECIFIC_KHADHROONY.md`
|
||||
- `README.md`
|
||||
- `ROADMAP.md`
|
||||
- `CHANGELOG.md`
|
||||
|
||||
@@ -466,6 +466,9 @@ def audit_token2022_naming(root: pathlib.Path) -> list[Violation]:
|
||||
root / "README.md",
|
||||
root / "ROADMAP.md",
|
||||
root / "RULES.md",
|
||||
root / "RULES_GENERAL.md",
|
||||
root / "RULES_RUST.md",
|
||||
root / "RULES_SPECIFIC_KHADHROONY.md",
|
||||
root / "kb-lib/README.md",
|
||||
]
|
||||
candidates.extend(sorted((root / "docs").glob("*.md")))
|
||||
@@ -495,6 +498,9 @@ def audit_private_kb_lib_paths_in_active_docs(root: pathlib.Path) -> list[Violat
|
||||
root / "README.md",
|
||||
root / "ROADMAP.md",
|
||||
root / "RULES.md",
|
||||
root / "RULES_GENERAL.md",
|
||||
root / "RULES_RUST.md",
|
||||
root / "RULES_SPECIFIC_KHADHROONY.md",
|
||||
root / "kb-lib/README.md",
|
||||
root / "kb-program-ids/README.md",
|
||||
]
|
||||
@@ -545,7 +551,7 @@ def audit_wincode_resolution(root: pathlib.Path) -> list[Violation]:
|
||||
"KH_DEP002",
|
||||
"Cargo.lock",
|
||||
1,
|
||||
"versioned application workspace lockfile is required",
|
||||
"local workspace Cargo.lock is required to verify the pinned wincode resolution",
|
||||
)
|
||||
)
|
||||
return violations
|
||||
|
||||
Reference in New Issue
Block a user