Files
khadhroony-bot3/RULES.md
2026-07-24 15:59:00 +02:00

26 KiB
Raw Blame History

Règles spécifiques à khadhroony-bot3

Ce fichier contient uniquement les règles propres au projet et au workspace khadhroony-bot3.

Les règles Rust générales et réutilisables dans tous les projets sont définies dans 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.

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.

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 blocs consécutifs de réexports pub use et pub(crate) use ne contiennent aucune ligne vide interne et restent ordonnés alphabétiquement lorsque cargo fmt ne les réordonne pas.
  • 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 sappliquent 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 dune 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 lUI, utiliser un override TS-rs number; si lexactitude 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 dun 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 :

<function_code>_<family_code>_<identifier_code>[_vN]

Les modules internes de décodage doivent utiliser la hiérarchie de fichiers :

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 lorsquil 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 DC_METADATA_MTM_TRACING_TARGET 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 linstallation du subscriber.
  • Il est interdit dajouter 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 dorchestration.
  • 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 nest 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.
  • Lajout 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.
  • Laudit mécanique spécifique au projet est exécuté par python3 scripts/audit_khadhroony_workspace_rules.py. Il couvre notamment DC_METADATA_MTM_TRACING_TARGET et lusage 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 lorsquun 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 dintégration, benches ou exemples. Une dépendance de test vers un décodeur ou matérialiseur concret est légitime lorsquelle sert uniquement à éprouver une orchestration générique fondée sur les traits API ; elle ne prouve pas quune 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 dun MtApiEventMaterializer doit être ajoutée au registre applicatif et couverte par un test dinventaire ordonné ; une crate présente dans le workspace ou dans kb_pipeline nest pas activée automatiquement. Les matérialiseurs exclusivement stateful qui nimplé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.

  • Lordre de préférence des formats est : schéma officiel wincode, schéma officiel Borsh, puis parseur local borné reproduisant exactement le runtime lorsque linterface officielle nexpose 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 lactivation 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 lordre exact des metas, borner toute liste de comptes variable avant lappel au builder et refuser les doublons lorsque leur répétition na pas de sémantique publiée.

  • Les features des interfaces doivent rester minimales et explicites. Une feature serde, wincode, borsh, std, alloc ou équivalente nest activée que si la crate consommatrice lutilise réellement.

  • Les crates applicatives ne doivent pas dépendre dinterfaces RPC ou transactionnelles uniquement pour relayer des types ; ces dépendances appartiennent à kb_rpc, 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 dune crate pour influencer le résolveur. Laudit 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.

  • 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, dexécuteur, de store, dapplication ou doutil 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.