0.1.0
This commit is contained in:
168
migration/khadhroony-bot2-reference/docs/TRACING_CONTRACT.md
Normal file
168
migration/khadhroony-bot2-reference/docs/TRACING_CONTRACT.md
Normal file
@@ -0,0 +1,168 @@
|
||||
<!-- file: docs/TRACING_CONTRACT.md -->
|
||||
<!-- version: 12 -->
|
||||
|
||||
# Contrat de tracing par crate
|
||||
|
||||
## Objectif
|
||||
|
||||
Chaque événement est émis par la crate qui prend réellement la décision. `kb_app_demo` journalise les frontières Tauri, les actions utilisateur, l’état des fenêtres et les résumés d’orchestration ; il ne recopie pas les décisions internes du RPC, du pipeline, du store, d’un décodeur, d’un matérialiseur ou d’un exécuteur.
|
||||
|
||||
## Classification des crates
|
||||
|
||||
Une crate est opérationnelle lorsqu’elle réalise au moins une des actions suivantes :
|
||||
|
||||
- I/O réseau ou base de données ;
|
||||
- orchestration concurrente, retry, pacing ou annulation ;
|
||||
- décodage ou matérialisation ;
|
||||
- construction ou simulation d’un plan d’exécution ;
|
||||
- décision runtime mutable ayant un effet observable.
|
||||
|
||||
Une crate passive contient uniquement des types, contrats, DTO, traits sans implémentation, registres ou constantes. Elle ne dépend pas de `tracing`. `kb_config` reste une exception de bootstrap : son chargement et sa validation précèdent l’installation du subscriber.
|
||||
|
||||
## Cible canonique
|
||||
|
||||
Toute crate qui déclare `tracing.workspace = true` doit :
|
||||
|
||||
- posséder `src/constants.rs` ;
|
||||
- définir exactement une constante `pub(crate) const TRACING_TARGET` ;
|
||||
- utiliser comme valeur le nom exact du package Cargo ;
|
||||
- appeler les macros avec `target: crate::constants::TRACING_TARGET` ;
|
||||
- déplacer la granularité interne dans des champs structurés.
|
||||
|
||||
Exemple :
|
||||
|
||||
```rust
|
||||
tracing::error!(
|
||||
target: crate::constants::TRACING_TARGET,
|
||||
action = "decoder_outcome_failure",
|
||||
campaign_id = %campaign_id,
|
||||
signature = %input.signature,
|
||||
instruction_path = %input.instruction_path,
|
||||
program_id = %input.program_id,
|
||||
processor_name = %identity.name,
|
||||
processor_version = %identity.version,
|
||||
status = ?result.status,
|
||||
diagnostics = ?result.diagnostics,
|
||||
"contextual instruction was not decoded successfully"
|
||||
);
|
||||
```
|
||||
|
||||
Les targets `khbot.*`, les targets suffixés par module et les targets de fenêtre ne sont plus utilisés par les crates opérationnelles migrées. Les identifiants frontend historiques restent acceptés comme valeurs du champ `frontend_target`, mais l’événement Rust est émis sous `kb_app_demo`.
|
||||
|
||||
## Crates actuellement routées
|
||||
|
||||
La configuration couvre toutes les crates qui déclarent actuellement `tracing.workspace = true` :
|
||||
|
||||
```text
|
||||
kb_app_demo
|
||||
kb_decoder_solana_core
|
||||
kb_decoder_spl_associated_token_account
|
||||
kb_decoder_spl_memo
|
||||
kb_decoder_spl_token
|
||||
kb_decoder_spl_token_2022
|
||||
kb_executor_metadata_spl_name_service
|
||||
kb_execution_solana
|
||||
kb_executor_solana_core
|
||||
kb_executor_spl_account_compression
|
||||
kb_executor_spl_associated_token_account
|
||||
kb_executor_spl_memo
|
||||
kb_executor_spl_noop
|
||||
kb_executor_spl_single_pool
|
||||
kb_logging
|
||||
kb_materializer_admin
|
||||
kb_materializer_compliance_audit
|
||||
kb_materializer_lifecycle
|
||||
kb_materializer_staking
|
||||
kb_materializer_transaction_annotations
|
||||
kb_pipeline
|
||||
kb_rpc
|
||||
kb_store_pg
|
||||
kb_wallet
|
||||
```
|
||||
|
||||
Le test `every_tracing_crate_has_one_canonical_target_constant` détecte automatiquement toute crate avec `tracing.workspace = true` et vérifie la présence d’une unique constante canonique. Le test de `kb_config` vérifie parallèlement la matrice de routes de chaque profil.
|
||||
|
||||
Les routes sont filtrées au niveau de leur writer plutôt que par un `Filtered` layer distinct. Un seul filtre d’admission agrégé empêche en amont le formatage des événements refusés par toutes les routes. Cette architecture préserve toutes les sorties globales et par crate au-delà de la limite interne de 64 identifiants de filtres de `tracing-subscriber`. Le test `more_than_64_routes_compose_without_filtered_layer_ids` protège explicitement ce contrat.
|
||||
|
||||
## Granularité et corrélation
|
||||
|
||||
Le target identifie la crate. Les champs décrivent l’action et le contexte :
|
||||
|
||||
```text
|
||||
action
|
||||
stage
|
||||
window
|
||||
campaign_id
|
||||
capture_session_id
|
||||
signature
|
||||
slot
|
||||
instruction_path
|
||||
program_id
|
||||
processor_name
|
||||
processor_version
|
||||
materializer_name
|
||||
materializer_version
|
||||
input_key
|
||||
input_hash
|
||||
status
|
||||
decision
|
||||
error_code
|
||||
```
|
||||
|
||||
Les spans de campagne et d’input utilisent eux aussi le target canonique `kb_pipeline`. Les événements des autres crates conservent leur propre target et reprennent les identifiants de corrélation utiles dans leurs champs.
|
||||
|
||||
## Politique des erreurs de décodage et de matérialisation
|
||||
|
||||
Un événement `error` est obligatoire pour :
|
||||
|
||||
- un input sélectionné sans décodeur compatible ;
|
||||
- un résultat de décodeur `failed` ;
|
||||
- un résultat de décodeur `unsupported` après dispatch vers une surface déclarée compatible ;
|
||||
- un résultat de décodeur invalide au regard du contrat API ;
|
||||
- un résultat de matérialiseur `failed` ;
|
||||
- une erreur de persistance decode, couverture, ledger ou matérialisation ;
|
||||
- une campagne qui termine avec `unmatched > 0` ou `failed_inputs > 0`.
|
||||
|
||||
L’événement doit permettre de retrouver rapidement l’input et la cause. Il conserve, lorsque disponibles, la campagne, la signature, le slot, le chemin d’instruction, le program ID, l’identité et la version du processor, la clé/hash d’input, le statut et les diagnostics structurés.
|
||||
|
||||
Les cas suivants ne sont pas des erreurs logicielles :
|
||||
|
||||
- transaction Solana échouée mais payload correctement décodé ;
|
||||
- observation non commitée conformément au statut on-chain ;
|
||||
- matérialisation `refused` par la politique de transaction ;
|
||||
- entrée volontairement `ignored` avec justification ;
|
||||
- annulation coopérative demandée par l’opérateur.
|
||||
|
||||
Ils sont journalisés en `debug`, `info` ou `warn` selon leur impact.
|
||||
|
||||
## Responsabilité
|
||||
|
||||
- `kb_rpc` : sélection d’endpoint, requêtes, réponses bornées, retry, rate limit et transport.
|
||||
- `kb_execution_solana` : assemblage du message, contrôle du contrat de signataires, liaison de simulation et signature transactionnelle.
|
||||
- `kb_store_pg` : transactions SQL, commit/rollback, compteurs et erreurs de persistance.
|
||||
- `kb_pipeline` : sélection, dispatch, concurrence, annulation, backfill et agrégation.
|
||||
- décodeur : reconnaissance, validation du format, décision et diagnostic borné.
|
||||
- matérialiseur : applicabilité exacte, politique de transaction et sorties produites.
|
||||
- exécuteur : support, construction, simulation et garde-fous.
|
||||
- application : invocation Tauri, fenêtre, progression utilisateur et résumé final.
|
||||
|
||||
## Données interdites
|
||||
|
||||
Ne jamais journaliser :
|
||||
|
||||
- clé privée, seed phrase ou transaction à signer ;
|
||||
- DSN ou URL contenant un secret non masqué ;
|
||||
- payload brut complet ou réponse RPC volumineuse ;
|
||||
- donnée dynamique non bornée.
|
||||
|
||||
Conserver à la place la taille, un préfixe borné et un SHA-256 lorsque l’audit du payload est nécessaire.
|
||||
|
||||
## Évolution
|
||||
|
||||
L’ajout ou la suppression de `tracing.workspace = true` impose dans le même delta :
|
||||
|
||||
1. la constante canonique ou sa suppression ;
|
||||
2. les événements réels de la crate ;
|
||||
3. la mise à jour de `config/example.config.json` ;
|
||||
4. la mise à jour des tests de contrat ;
|
||||
5. la mise à jour de la liste ci-dessus.
|
||||
Reference in New Issue
Block a user