Files
khadhroony-bot3/docs/TRACING_CONTRACT.md
2026-07-23 16:37:12 +02:00

6.9 KiB
Raw Blame History

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 dorchestration ; il ne recopie pas les décisions internes du RPC, du pipeline, du store, dun décodeur, dun matérialiseur ou dun exécuteur.

Classification des crates

Une crate est opérationnelle lorsquelle 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 dun plan dexé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 linstallation 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 :

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 :

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 dune 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 dadmission 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 laction et le contexte :

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 dinput 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 linput et la cause. Il conserve, lorsque disponibles, la campagne, la signature, le slot, le chemin dinstruction, le program ID, lidentité et la version du processor, la clé/hash dinput, 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 lopérateur.

Ils sont journalisés en debug, info ou warn selon leur impact.

Responsabilité

  • kb_rpc : sélection dendpoint, 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 laudit du payload est nécessaire.

Évolution

Lajout 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.