v0.1.0-pre.066
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/DOCUMENTATION_REFACTOR_AUDIT.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Audit de refonte documentaire
|
||||
|
||||
@@ -19,9 +19,9 @@ Les fichiers suivants existent à la racine :
|
||||
- `CHANGELOG.md` ;
|
||||
- `ROADMAP.md` ;
|
||||
- `RULES.md` ;
|
||||
- `RULES_GENERAL.md` ;
|
||||
- `RULES_RUST.md` ;
|
||||
- `RULES_SPECIFIC_KHADHROONY.md` ;
|
||||
- `docs/rules/RULES_GENERAL.md` ;
|
||||
- `docs/rules/RULES_RUST.md` ;
|
||||
- `docs/rules/RULES_SPECIFIC_KHADHROONY.md` ;
|
||||
- `KHADHROONY_BOT3_MIGRATION_CLOSURE_TODO.md`.
|
||||
|
||||
### 2.2 Documentation active bot3
|
||||
@@ -123,7 +123,7 @@ Le workspace déclare 11 crates :
|
||||
|
||||
Aucune crate ne satisfait donc le contrat complet `README.md`, `TODO.md`, `USAGE.md`, `CHANGELOG.md`.
|
||||
|
||||
Une contradiction normative existe dans `RULES_GENERAL.md` : le fichier exige encore un `README.md` ou `001.README.md` et, à terme, un `USAGES.md`. La convention retenue est `USAGE.md`, nom singulier couramment utilisé pour un guide d’utilisation. La règle doit imposer exactement `README.md`, `TODO.md`, `USAGE.md` et `CHANGELOG.md`.
|
||||
La contradiction `USAGES.md` contre `USAGE.md` est résolue en faveur de `USAGE.md`. `001.README.md` reste autorisé uniquement comme index lexical de répertoire très fourni, notamment sous `idls/`, et ne remplace jamais le `README.md` obligatoire d’une crate.
|
||||
|
||||
### 4.4 Frontière de l’archive documentaire
|
||||
|
||||
@@ -162,8 +162,8 @@ Le déplacement des règles secondaires vers `docs/rules/` ne doit pas être eff
|
||||
Références actives identifiées :
|
||||
|
||||
- `RULES.md` lie directement les trois fichiers secondaires à la racine ;
|
||||
- `RULES_GENERAL.md` cite leurs chemins racine et le contrat documentaire obsolète `USAGES.md` ;
|
||||
- `RULES_SPECIFIC_KHADHROONY.md` lie `RULES_GENERAL.md` et `RULES_RUST.md` par chemins relatifs racine ;
|
||||
- les scripts, prompts et documents actifs doivent employer les chemins `docs/rules/...` ;
|
||||
- `docs/rules/RULES_SPECIFIC_KHADHROONY.md` lie `docs/rules/RULES_GENERAL.md` et `docs/rules/RULES_RUST.md` par chemins relatifs racine ;
|
||||
- `scripts/audit_khadhroony_workspace_rules.py` vérifie explicitement les quatre chemins racine à deux endroits ;
|
||||
- les deux prompts bot3 citent les chemins racine ;
|
||||
- `KHADHROONY_BOT3_MIGRATION_CLOSURE_TODO.md` décrit l’organisation actuelle.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/DOCUMENTATION_REFACTOR_PLAN.md -->
|
||||
<!-- version: 3 -->
|
||||
<!-- version: 4 -->
|
||||
|
||||
# Plan de refonte documentaire
|
||||
|
||||
@@ -164,8 +164,8 @@ Aucun document bot3 actif ne doit encore être supprimé.
|
||||
|
||||
Travail :
|
||||
|
||||
1. corriger `RULES_GENERAL.md` pour imposer les quatre fichiers exacts par crate ;
|
||||
2. supprimer les variantes obsolètes `001.README.md` et `USAGES.md`, et retenir définitivement `USAGE.md` ;
|
||||
1. corriger `docs/rules/RULES_GENERAL.md` pour imposer les quatre fichiers exacts par crate ;
|
||||
2. interdire `USAGES.md`, retenir définitivement `USAGE.md` et encadrer l’exception `001.README.md` pour les index lexicaux ;
|
||||
3. créer `docs/rules/CRATE_DOCUMENTATION_RULES.md` ;
|
||||
4. définir la frontière entre README, TODO, USAGE, CHANGELOG général et changelogs de crates ;
|
||||
5. imposer que `USAGE.md` documente uniquement les APIs publiques réellement accessibles ;
|
||||
@@ -182,7 +182,7 @@ Les règles secondaires restent temporairement à la racine dans ce delta.
|
||||
Travail :
|
||||
|
||||
1. créer `docs/rules/` ;
|
||||
2. déplacer `RULES_GENERAL.md`, `RULES_RUST.md` et `RULES_SPECIFIC_KHADHROONY.md` ;
|
||||
2. déplacer `docs/rules/RULES_GENERAL.md`, `docs/rules/RULES_RUST.md` et `docs/rules/RULES_SPECIFIC_KHADHROONY.md` ;
|
||||
3. mettre à jour `RULES.md` ;
|
||||
4. corriger les liens internes ;
|
||||
5. adapter `scripts/audit_khadhroony_workspace_rules.py` ;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/CRATE_DOCUMENTATION_RULES.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Règles documentaires des crates
|
||||
|
||||
@@ -16,7 +16,7 @@ USAGE.md
|
||||
CHANGELOG.md
|
||||
```
|
||||
|
||||
Les variantes `001.README.md`, `USAGES.md` ou tout autre nom concurrent sont interdites dans la documentation active.
|
||||
`USAGES.md` et les autres noms concurrents sont interdits. `001.README.md` reste autorisé comme index de répertoire lorsque le tri lexical au début d’un répertoire très fourni est utile, par exemple sous `idls/`; il ne remplace jamais le `README.md` obligatoire à la racine d’une crate.
|
||||
|
||||
Ces fichiers doivent être écrits pour l’architecture actuelle de `khadhroony-bot3`. Les documents de `olddocs/archivekbot2/` sont des sources historiques : leur contenu peut être étudié, vérifié, réinterprété et adapté, mais ne doit jamais être déplacé, copié automatiquement ou rendu normatif sans réécriture explicite.
|
||||
|
||||
@@ -114,6 +114,8 @@ Une réexportation publique doit être vérifiée jusqu’à son chemin d’acc
|
||||
|
||||
Chaque API publique significative doit disposer d’au moins un exemple ou être couverte par un exemple de scénario explicitement identifié. Les APIs triviales ou regroupées peuvent partager un exemple lorsqu’il démontre réellement leur usage.
|
||||
|
||||
Les tests unitaires peuvent être documentés lorsqu’ils illustrent un contrat public, un invariant, un format canonique ou une régression importante. `USAGE.md` doit alors les référencer et expliquer ce qu’ils démontrent, sans transformer les helpers internes en API publique.
|
||||
|
||||
### 4.4 Crates sans API bibliothèque publique
|
||||
|
||||
Une crate principalement binaire ou interne conserve un `USAGE.md`. Le document décrit alors ses commandes, entrées, sorties, configuration, contrats d’intégration et limites, sans inventer une API Rust publique.
|
||||
@@ -164,7 +166,7 @@ Une idée encore exploratoire reste dans `docs/IDEA_REMINDERS.md` ou dans un doc
|
||||
|
||||
Le TODO ne doit pas :
|
||||
|
||||
- répéter les travaux déjà terminés ;
|
||||
- conserver ou répéter les travaux déjà terminés ;
|
||||
- contenir l’historique des corrections ;
|
||||
- recopier le ROADMAP général ;
|
||||
- transformer une hypothèse en obligation ;
|
||||
@@ -186,7 +188,7 @@ Chaque changelog de crate doit contenir au minimum :
|
||||
- l’adoption des nouvelles règles Rust et Khadhroony applicables ;
|
||||
- les validations réellement exécutées et les limitations encore connues.
|
||||
|
||||
La section `0.1.0` peut regrouper les prereleases de migration lorsque leur détail exhaustif n’apporte pas de valeur. Les prereleases ou correctifs importants peuvent être conservés lorsqu’ils expliquent une rupture, une correction notable ou une validation structurante.
|
||||
La section `0.1.0` synthétise la migration initiale. À partir de cette base, le changelog de crate conserve le détail des prereleases et correctifs `fix` qui ont touché la crate, afin de reprendre durablement les informations pertinentes de chaque `delta.md`.
|
||||
|
||||
### 6.3 Catégories
|
||||
|
||||
@@ -206,13 +208,15 @@ Ne pas créer des sections vides.
|
||||
|
||||
### 6.4 Versions et corrections
|
||||
|
||||
Le changelog distingue clairement :
|
||||
Le changelog de crate distingue clairement :
|
||||
|
||||
- version publiée ;
|
||||
- prerelease ;
|
||||
- correctif `fix` ;
|
||||
- changement non publié.
|
||||
|
||||
Le changelog général suit une granularité différente : il décrit les changements entre versions fonctionnelles, par exemple de `0.4.6` à `0.4.7`, sans détailler les prereleases ni les correctifs `fix`. Les détails de livraison restent dans les changelogs des crates concernées.
|
||||
|
||||
Une modification fonctionnelle de la crate impose une mise à jour de son changelog. Une modification documentaire pure peut être regroupée sous `Non publié / Documentation`.
|
||||
|
||||
### 6.5 Provenance bot2
|
||||
@@ -237,7 +241,7 @@ Les matrices actives maintenues sous :
|
||||
test-fixtures/contract-matrices/
|
||||
```
|
||||
|
||||
restent les références canoniques. Elles ne doivent pas être dupliquées dans `docs/`.
|
||||
restent les références canoniques. Elles servent à la fois de contrats documentaires et de fixtures exécutées par des tests unitaires ou d’intégration. Elles ne doivent pas être dupliquées dans `docs/`.
|
||||
|
||||
Les documents de crate et de protocole doivent les référencer par lien et expliquer leur rôle, leur portée et leur statut de validation.
|
||||
|
||||
|
||||
98
docs/rules/RULES_GENERAL.md
Normal file
98
docs/rules/RULES_GENERAL.md
Normal file
@@ -0,0 +1,98 @@
|
||||
<!-- file: docs/rules/RULES_GENERAL.md -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# Règles générales du projet
|
||||
|
||||
## Hiérarchie normative
|
||||
|
||||
- Les règles détaillées sont regroupées sous `docs/rules/` et indexées par `RULES.md` à la racine.
|
||||
- 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 membre du workspace possède exactement `README.md`, `TODO.md`, `USAGE.md` et `CHANGELOG.md` à sa racine.
|
||||
- Le contrat détaillé de ces quatre documents est défini dans `docs/rules/CRATE_DOCUMENTATION_RULES.md`.
|
||||
- `USAGES.md` est interdit au profit de `USAGE.md`.
|
||||
- `001.README.md` est autorisé uniquement comme index de répertoire lorsque le tri lexical au début d’un répertoire très fourni apporte une valeur réelle, notamment sous `idls/`; il ne remplace jamais le `README.md` obligatoire à la racine d’une crate.
|
||||
- Les documents actifs de bot3 sont réécrits pour l’architecture actuelle ; aucun document de `olddocs/archivekbot2/` ne doit être déplacé ou repris automatiquement.
|
||||
- Les matrices canoniques de `test-fixtures/contract-matrices/` doivent être référencées, non dupliquées dans `docs/`.
|
||||
- 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`.
|
||||
|
||||
### Fin de fichier et formatters
|
||||
|
||||
- La contrainte de fin de fichier avec exactement un saut de ligne terminal s’applique aux sources Rust, TypeScript, JavaScript, Python, shell, TOML, YAML et Markdown lorsqu’elle est vérifiée par les outils du projet.
|
||||
- Elle ne s’applique pas aux fichiers HTML ni JSON : leur formatter peut supprimer automatiquement la ligne vide terminale.
|
||||
- Aucun audit ne doit réintroduire artificiellement une ligne vide dans un fichier HTML ou JSON après formatage.
|
||||
145
docs/rules/RULES_RUST.md
Normal file
145
docs/rules/RULES_RUST.md
Normal file
@@ -0,0 +1,145 @@
|
||||
<!-- file: docs/rules/RULES_RUST.md -->
|
||||
<!-- version: 7 -->
|
||||
|
||||
# Règles Rust générales
|
||||
|
||||
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
|
||||
|
||||
- Tout fichier texte qui supporte des commentaires commence par une ligne indiquant son chemin relatif dans le projet, puis une ligne `version` entière.
|
||||
- La version d'un fichier est incrémentée à chaque modification après validation de sa version précédente.
|
||||
- Les fichiers Rust utilisent `// file: ...` et `// version: N`.
|
||||
- Les fichiers Markdown utilisent `<!-- file: ... -->` et `<!-- version: N -->`.
|
||||
- Tous les fichiers texte se terminent par exactement une fin de ligne.
|
||||
|
||||
## Langue et documentation
|
||||
|
||||
- Les commentaires et rustdocs du code sont rédigés en anglais.
|
||||
- Les documents Markdown du projet sont rédigés dans la langue documentaire choisie par le projet.
|
||||
- Tout élément `pub` ou `pub(crate)` possède une rustdoc utile au point de déclaration.
|
||||
- Toute réexportation `pub use` ou `pub(crate) use` dans `lib.rs` ou `main.rs` possède également sa propre rustdoc copiée ou reformulée de manière équivalente. La documentation du point d'entrée doit permettre de comprendre l'API sans ouvrir le module interne.
|
||||
|
||||
## Édition et lints obligatoires
|
||||
|
||||
- L'édition Rust cible est Rust 2024, sauf contrainte explicitement documentée.
|
||||
- Chaque `lib.rs` et `main.rs` contient :
|
||||
- `#![warn(missing_docs)]` ;
|
||||
- `#![deny(unreachable_pub)]` ;
|
||||
- `#![forbid(unsafe_code)]`.
|
||||
- Les lints Clippy obligatoires sont déclarés au niveau workspace et hérités par toutes les crates.
|
||||
- Les règles minimales sont : interdiction de `unwrap`, `expect`, `?`, retours implicites, code `unsafe`, APIs publiques inaccessibles et imports globaux non justifiés.
|
||||
- Les tests peuvent disposer d'exceptions limitées pour `unwrap` et `expect` uniquement lorsqu'elles sont explicitement autorisées par la configuration Clippy.
|
||||
|
||||
La configuration workspace doit au minimum déclarer :
|
||||
|
||||
```toml
|
||||
[workspace.lints.rust]
|
||||
missing_docs = "warn"
|
||||
unreachable_pub = "deny"
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[workspace.lints.clippy]
|
||||
unwrap_used = "deny"
|
||||
expect_used = "deny"
|
||||
implicit_return = "deny"
|
||||
needless_return = "allow"
|
||||
useless_vec = "deny"
|
||||
question_mark = "deny"
|
||||
question_mark_used = "deny"
|
||||
needless_match = "allow"
|
||||
manual_ok_err = "allow"
|
||||
manual_unwrap_or = "allow"
|
||||
manual_map = "allow"
|
||||
match_like_matches_macro = "allow"
|
||||
single_match = "allow"
|
||||
manual_unwrap_or_default = "allow"
|
||||
manual_find = "allow"
|
||||
explicit_counter_loop = "allow"
|
||||
get_first = "allow"
|
||||
implicit_saturating_sub = "allow"
|
||||
```
|
||||
|
||||
## Formatage
|
||||
|
||||
- `cargo fmt --all` est exécuté après application de chaque delta ou correctif et avant les tests.
|
||||
- Les fichiers Rust ne contiennent pas de lignes vides à l'intérieur d'une fonction, d'une structure, d'une énumération ou d'une implémentation courte.
|
||||
- Les lignes vides séparent uniquement les fonctions, blocs `impl`, types et sections logiques.
|
||||
- Les exports de `lib.rs` ou `main.rs` ne contiennent aucune ligne vide à l'intérieur d'une série homogène de `pub use` ou `pub(crate) use`.
|
||||
- Les séries `pub use` et `pub(crate) use` forment deux groupes séparés lorsqu'elles coexistent.
|
||||
- Le groupe `pub use` précède le groupe `pub(crate) use` dans une même façade.
|
||||
- L’ordre interne suit l’ordre naturel produit par `rustfmt` : les segments et mots séparés sont comparés avant leurs suffixes numériques, par exemple `U8` avant `U16` et `TOKEN` avant `TOKEN2022`.
|
||||
|
||||
## Assertions sur les collections
|
||||
|
||||
- Un test qui vérifie uniquement l’appartenance à un ensemble peut trier la valeur obtenue et la valeur attendue avant `assert_eq!`, afin de ne pas dépendre d’un ordre d’enregistrement non contractuel.
|
||||
- Le tri doit être explicite dans le test et appliqué aux deux collections comparées.
|
||||
- Ne jamais trier une collection lorsque l’ordre fait partie du contrat : comptes Solana, metas, instructions, signers, événements, étapes de pipeline, priorités, journaux ou toute autre séquence ordonnée.
|
||||
|
||||
## Imports et chemins
|
||||
|
||||
- `use` est interdit pour les constantes, fonctions, structures, énumérations, unions, alias de types, modules et macros.
|
||||
- `use` est autorisé uniquement pour un trait lorsque la résolution de méthode, une macro de dérivation ou une contrainte de langage l'exige réellement.
|
||||
- Un import de trait doit rester étroit et ne doit jamais importer simultanément des éléments non-traits par accolades.
|
||||
- Les imports globaux, glob imports et imports groupés par accolades sont interdits.
|
||||
- Pour un élément fourni par une crate externe au workspace, utiliser directement le chemin public le plus court exposé par cette crate. Exemple : utiliser `external_crate::Struct`, jamais `external_crate::module::Struct` si `external_crate::Struct` existe, et jamais `use external_crate::Struct`.
|
||||
- Pour un élément `pub` déclaré dans le workspace :
|
||||
- il est réexporté depuis le `lib.rs` ou `main.rs` de sa crate propriétaire ;
|
||||
- depuis une autre crate, il est appelé via `owner_crate::Item` ;
|
||||
- depuis sa propre crate, il est appelé via `crate::Item`, même depuis son module de déclaration.
|
||||
- Pour un élément `pub(crate)` :
|
||||
- il est réexporté depuis le `lib.rs` ou `main.rs` via `pub(crate) use` ;
|
||||
- il est appelé via `crate::Item`, même depuis son module de déclaration.
|
||||
- Un élément strictement privé à un module n'est pas réexporté et est appelé par son nom local uniquement. Il est interdit d'utiliser un chemin long comme `crate::module::helper` ou `owner_crate::module::helper` pour un helper privé du module courant.
|
||||
- Dans un sous-module de tests, un élément privé du module parent est appelé via `super::Item`. Un élément `pub` ou `pub(crate)` continue d’être appelé via le point d’entrée de crate le plus court, par exemple `crate::Item`.
|
||||
- Les exports ne sont jamais groupés avec des accolades. Un type, une fonction, une constante ou un alias correspond à une ligne de réexport distincte.
|
||||
- Un réexport d’un module interne commence par `self::`, y compris dans `lib.rs` ; `use crate::...` est réservé aux références qualifiées dans le code et ne sert pas à construire une façade.
|
||||
- Les alias `as` sont interdits dans les réexports : le symbole reçoit son nom canonique dans son module propriétaire avant d’être réexporté sans transformation.
|
||||
- Un bloc homogène de `pub use` ou `pub(crate) use` ne contient aucune ligne vide et reste ordonné alphabétiquement par symbole réexporté lorsque `rustfmt` ne le réordonne pas.
|
||||
|
||||
## Visibilité et API de crate
|
||||
|
||||
- Aucun `pub mod` n'est autorisé. Les modules restent privés et l'API est constituée exclusivement par des réexports explicites depuis le point d’entrée de la crate.
|
||||
- Un élément `pub` inaccessible depuis le point d'entrée de sa crate est une erreur de conception, pas un simple avertissement.
|
||||
- Un élément `pub(crate)` utilisé hors de son module est réexporté au niveau du point d'entrée de la crate.
|
||||
- Les chemins internes de modules ne font pas partie de l'API stable.
|
||||
- Les méthodes inhérentes publiques restent appelées via le type réexporté ; les fonctions libres publiques sont appelées via le point d'entrée de crate.
|
||||
|
||||
## Helpers et réutilisation
|
||||
|
||||
- Un helper répété dans plusieurs modules d'une même crate est déplacé dans un module commun explicite, généralement `helper.rs` ou un module spécialisé plus précis.
|
||||
- Le nom `helpers.rs` ou `helper.rs` n'est utilisé que si aucune responsabilité métier plus précise ne convient.
|
||||
- Un helper général réutilisable par plusieurs crates est déplacé dans une crate commune appropriée et exposé publiquement.
|
||||
- Les types d'erreur généraux, identifiants de programme, primitives de validation et fonctions de sérialisation communes ne doivent pas être dupliqués entre crates.
|
||||
- La mutualisation ne doit pas créer de dépendance cyclique ni déplacer un comportement métier spécifique dans une crate générique.
|
||||
|
||||
## Gestion des erreurs et contrôle de flux
|
||||
|
||||
- `unwrap`, `expect` et `panic` sont interdits dans le code de production.
|
||||
- L'opérateur `?` est interdit dans les chemins de production ; utiliser des `match` explicites avec erreurs contextualisées.
|
||||
- `anyhow` et `thiserror` ne sont pas utilisés par défaut.
|
||||
- Les erreurs publiques sont typées lorsque leur contrat est stable ; les diagnostics dynamiques restent bornés.
|
||||
- Les retours sont explicites conformément au lint `clippy::implicit_return`.
|
||||
|
||||
## Sécurité et dépendances
|
||||
|
||||
- Le code `unsafe` est interdit.
|
||||
- Une dépendance n'est ajoutée que si elle est réellement utilisée dans le chemin de compilation concerné.
|
||||
- Une dépendance utilisée uniquement dans les tests reste dans `[dev-dependencies]`.
|
||||
- Les features sont minimales et explicites.
|
||||
|
||||
## Contrôle avant livraison
|
||||
|
||||
Chaque livraison Rust exécute au minimum, dans cet ordre :
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
python3 scripts/audit_rust_general_rules.py
|
||||
python3 scripts/audit_khadhroony_workspace_rules.py
|
||||
cargo test --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
```
|
||||
|
||||
Un projet peut utiliser une sélection de tests plus étroite pendant le développement, mais la fermeture d'une version exige le contrôle global.
|
||||
|
||||
Le wrapper `python3 scripts/audit_rust_workspace_rules.py` exécute les deux audits sans fusionner leurs responsabilités.
|
||||
245
docs/rules/RULES_SPECIFIC_KHADHROONY.md
Normal file
245
docs/rules/RULES_SPECIFIC_KHADHROONY.md
Normal file
@@ -0,0 +1,245 @@
|
||||
<!-- file: docs/rules/RULES_SPECIFIC_KHADHROONY.md -->
|
||||
<!-- version: 5 -->
|
||||
|
||||
# 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.
|
||||
- `kb-app-demo-desktop/src/tauri.rs` contient les attributs `#[tauri::command]`, l’enregistrement des commandes et des wrappers privés minces ; la logique complète doit vivre dans le module fonctionnel correspondant sous une fonction `pub(crate)` testable.
|
||||
- Un wrapper Tauri ne doit effectuer que l’adaptation des handles/states/arguments, l’appel de la fonction de module et le retour du résultat ; toute validation métier, orchestration ou construction de payload doit rester hors de `tauri.rs`.
|
||||
- Les helpers privés de `tauri.rs` sont autorisés lorsqu’ils mutualisent exclusivement une adaptation Tauri, par exemple l’ouverture, l’affichage, le focus ou l’émission vers une fenêtre ; ils ne doivent contenir aucune logique métier, requête SQL ou orchestration de pipeline.
|
||||
|
||||
## 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 jamais exécuter `npm run build`, `npm --prefix kb-app-demo-desktop run build` ni une commande équivalente de build frontend autonome.
|
||||
- L’installation manuelle d’une dépendance frontend est limitée aux commandes npm d’ajout nécessaires, notamment `npm i -D <package>` pour une dépendance de développement ; `node_modules/` et `package-lock.json` restent locaux, générés et non livrables.
|
||||
- La validation frontend de développement est réalisée uniquement par `cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json`, qui démarre et pilote Vite selon la configuration Tauri.
|
||||
|
||||
## 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.
|
||||
|
||||
## Nomenclature des identités et opérations persistées
|
||||
|
||||
- Les identités runtime, `processor_name`, `protocol_code`, `surface_code`, `operation_code` et `event_code` sont des contrats persistés et utilisent des segments hiérarchiques séparés par `.`.
|
||||
- Chaque segment utilise `snake_case`; un underscore ne remplace jamais un niveau hiérarchique. Exemples : `solana.core.system.transfer`, `spl.memo.v4.add_memo`, `spl.token_2022.transfer_checked`.
|
||||
- Les anciennes formes préfixées par `solana_core`, `solana_native`, `spl_memo`, `spl_token`, `spl_token_2022`, `spl_associated_token_account` ou `metadata_metaplex_token_metadata` sont interdites pour ces valeurs contractuelles.
|
||||
- Toute nouvelle surface ou opération doit respecter `docs/OPERATION_NAMING_CONVENTION.md` et être ajoutée à `test-fixtures/contract-matrices/OPERATION_NAMING_MATRIX.json` avant son premier remplissage persistant.
|
||||
- Un renommage de ces valeurs après remplissage d’une base est une migration de données et exige une migration SQL ou une reconstruction explicite des tables dérivées.
|
||||
6
docs/templates/CRATE_CHANGELOG_TEMPLATE.md
vendored
6
docs/templates/CRATE_CHANGELOG_TEMPLATE.md
vendored
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/templates/CRATE_CHANGELOG_TEMPLATE.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Modèle de changelog de crate
|
||||
|
||||
@@ -28,3 +28,7 @@
|
||||
### Limitations connues
|
||||
|
||||
- Indiquer les fonctionnalités partielles, non raccordées ou non validées.
|
||||
|
||||
## Historique détaillé des livraisons
|
||||
|
||||
Ajouter les prereleases et correctifs `fix` ayant réellement modifié cette crate, en reprenant les informations pertinentes des `delta.md`.
|
||||
|
||||
4
docs/templates/CRATE_TODO_TEMPLATE.md
vendored
4
docs/templates/CRATE_TODO_TEMPLATE.md
vendored
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/templates/CRATE_TODO_TEMPLATE.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Modèle de TODO de crate
|
||||
|
||||
@@ -22,3 +22,5 @@
|
||||
## Hors périmètre
|
||||
|
||||
> Ne reprendre une idée de `docs/IDEA_REMINDERS.md` qu’après confirmation, attribution à cette crate et reformulation en tâche vérifiable.
|
||||
|
||||
> Supprimer toute tâche dès que sa réalisation est confirmée et la reporter dans le changelog de la crate.
|
||||
|
||||
6
docs/templates/CRATE_USAGE_TEMPLATE.md
vendored
6
docs/templates/CRATE_USAGE_TEMPLATE.md
vendored
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/templates/CRATE_USAGE_TEMPLATE.md -->
|
||||
<!-- version: 1 -->
|
||||
<!-- version: 2 -->
|
||||
|
||||
# Modèle de guide d’utilisation de crate
|
||||
|
||||
@@ -39,6 +39,10 @@ Pour chaque API ou groupe cohérent :
|
||||
|
||||
Supprimer cette section si aucun binaire public n’existe.
|
||||
|
||||
## Tests de référence
|
||||
|
||||
Documenter les tests unitaires particulièrement instructifs qui démontrent un contrat public, un invariant, un format canonique ou une non-régression.
|
||||
|
||||
## Limites connues
|
||||
|
||||
## Références
|
||||
|
||||
Reference in New Issue
Block a user