# Règles des dépendances KSP ## Portée Les règles `DEP-*` définissent quelles dépendances externes et internes peuvent traverser les frontières KSP et quelles couches en sont propriétaires. Elles complètent les règles Rust générales et le graphe de `docs/architecture/005-DEPENDENCY_GRAPH.md`. ## Firewall des exécutables - **DEP-EXEC-001** — Les applications, demos, workers et jobs KSP ne dépendent directement d'aucune crate externe relative à Solana ou à un protocole Solana. Ils consomment exclusivement les composants KSP propriétaires de ces contrats. - **DEP-EXEC-002** — Un exécutable peut dépendre directement de bibliothèques générales non-Solana nécessaires à son interface ou à son runtime, à condition qu'elles ne portent pas une opération métier/protocolaire appartenant à KSP. - **DEP-EXEC-003** — Si un exécutable a besoin d'un type, d'une fonction ou d'un contrat Solana, le composant KSP propriétaire doit l'exposer ou fournir le wrapper/contrat approprié. ## Direction des dépendances internes - **DEP-KSP-001** — Une crate `ksp--api` ne dépend jamais de l'implémentation officielle `ksp--lib`. - **DEP-KSP-002** — Une bibliothèque basse de transformation/sémantique ne dépend pas d'un worker, job, application ou orchestrateur qui la consomme. - **DEP-KSP-003** — Les conversions entre modèles de transport, processing et persistence sont réalisées par les composants de composition appropriés plutôt que par des dépendances croisées entre domaines. - **DEP-KSP-004** — Aucun `ksp-data-api` global n'est introduit uniquement pour éviter des conversions explicites entre modèles appartenant à des responsabilités différentes. - **DEP-KSP-005** — Une dépendance autorisée par le graphe n'est ajoutée au manifeste que lorsqu'un usage réel la justifie. ## Déclaration Cargo et centralisation workspace - **DEP-CARGO-001** — Toute dépendance externe utilisée par une crate membre du workspace est déclarée une seule fois dans le `Cargo.toml` racine sous `[workspace.dependencies]`. - **DEP-CARGO-002** — Une crate membre consomme une dépendance centralisée avec `.workspace = true` et ne redéclare pas localement sa version. - **DEP-CARGO-003** — Les options communes de résolution telles que `default-features` et la contrainte de version sont définies au niveau `[workspace.dependencies]`. Les features d'usage ne sont pas activées dans cette table commune : chaque crate membre active localement uniquement les features nécessaires à son propre code avec ` = { workspace = true, features = [...] }`. - **DEP-CARGO-004** — Lorsqu'une génération majeure/mineure compatible est retenue, KSP exprime explicitement l'intention sous forme caret `^M.m` (par exemple `^4.3`) plutôt qu'avec une écriture patch telle que `4.3.0`. Même si Cargo interprète aussi par défaut cette dernière comme une contrainte compatible caret, KSP normalise la syntaxe pour rendre l'intention manifeste. Un pin exact `=M.m.p` ou un bornage différent requiert une justification explicite. - **DEP-CARGO-005** — Le `Cargo.lock` résout la version patch concrète à l'intérieur de la contrainte du workspace ; cette résolution ne remplace pas la politique de version déclarée dans le manifeste racine. - **DEP-CARGO-006** — Lorsqu'une feature externe n'est nécessaire qu'aux tests/benchmarks/examples d'une crate, son activation appartient à la section de dépendances de développement correspondante plutôt qu'aux dépendances de production. L'unification des features effectuée par Cargo lors d'un build ne transfère pas cet ownership vers le `Cargo.toml` racine. - **DEP-CARGO-007** — Les canaries qui inspectent une politique générale du workspace ou plusieurs manifests membres appartiennent à une surface de gouvernance/fondation (actuellement les tests de `ksp-core-lib` tant qu'aucun outil d'audit dédié n'existe). Une crate métier spécialisée conserve uniquement les tests de frontière propres à son domaine et ne devient pas propriétaire d'une règle globale du workspace. ## Codecs wire et cohérence des versions - **DEP-WIRE-001** — Pour les surfaces wire officielles KSP, les dépendances directes vers `borsh`, `wincode` ou codecs équivalents appartiennent normalement à `ksp-interface-lib`. - **DEP-WIRE-002** — `ksp-program-lib` ne redécode pas directement une surface possédée par `ksp-interface-lib` avec sa propre dépendance codec. - **DEP-WIRE-003** — Une crate d'interface externe est retenue seulement si sa source/API et son graphe de dépendances sont suffisamment compatibles avec le stack KSP actuel. - **DEP-WIRE-004** — Une crate protocolaire externe qui impose une génération ancienne/incompatible d'une dépendance fondamentale peut être remplacée par une réimplémentation KSP bornée aux contrats wire nécessaires. - **DEP-WIRE-005** — Les doublons de générations de dépendances fondamentales sont audités et les doublons évitables doivent être éliminés ; un doublon inévitable requiert une justification. - **DEP-WIRE-006** — KSP cherche des versions récentes compatibles et ne fixe pas arbitrairement une ancienne version uniquement pour conserver une crate protocolaire remplaçable. - **DEP-WIRE-007** — Une extension Program externe peut posséder temporairement son propre wire lorsqu'aucune interface officielle KSP correspondante n'existe encore. ## Logging - **DEP-LOG-001** — `ksp-logging-lib` est le propriétaire KSP direct de `tracing`, `tracing-appender`, `tracing-subscriber` et de l'initialisation/configuration runtime logging. - **DEP-LOG-002** — `ksp-logging-lib` peut dépendre de `ksp-core-lib` pour le contrat commun `Error` / `Result`. - **DEP-LOG-003** — `ksp-core-lib` ne dépend pas de `ksp-logging-lib` dans l'architecture actuelle. - **DEP-LOG-004** — Les crates KSP comportant du runtime dépendent de `ksp-logging-lib` lorsqu'elles instrumentent leur comportement et n'utilisent pas directement `tracing`, `tracing-subscriber` ou `tracing-appender` pour émettre leurs propres événements/spans. - **DEP-LOG-005** — Les crates `*-api` purement déclaratives n'ajoutent pas une dépendance logging sans comportement réel à instrumenter. - **DEP-LOG-006** — Le subscriber KSP rend silencieux par défaut les targets externes ; une information tierce utile est réémise explicitement par la crate KSP propriétaire sous son propre target au lieu de renommer/réécrire l'événement tiers. - **DEP-LOG-007** — Une application/framework peut exceptionnellement intégrer directement un plugin/dépendance tracing imposé par son framework, notamment Tauri, sans créer une seconde politique de logging parallèle à `ksp-logging-lib`; les événements KSP restent émis via la façade KSP. - **DEP-LOG-008** — `ksp-logging-lib` possède ses settings runtime et son hot reload ; `ksp-config-lib` peut plus tard construire ces settings et demander une reconfiguration sans créer de dépendance inverse Logging -> Config. - **DEP-LOG-009** — Tout bridge `tracing` public mais caché de la documentation rendu techniquement nécessaire par l’expansion des macros de `ksp-logging-lib` est un détail d’implémentation réservé à ces macros ; une crate consommatrice ne l’utilise jamais directement et reste limitée à la façade KSP documentée. - **DEP-LOG-010** — Toute crate KSP comportementale qui émet des événements/spans via `ksp-logging-lib` possède un target principal explicite `pub(crate) const TRACING_TARGET: &str` dans `src/constants.rs`, égal au nom Cargo de la crate. Les appels utilisent ce symbole (ou un target spécialisé possédé par le même `constants.rs`) plutôt qu’un littéral dispersé. - **DEP-LOG-011** — `env!("CARGO_PKG_NAME")` ne sert pas de target de tracing/logging KSP : le target appartient au contrat d’observabilité et doit rester explicite dans le code. Les metadata Cargo restent autorisées lorsqu’elles sont réellement la donnée recherchée, par exemple pour un User-Agent ou une information de build. - **DEP-LOG-012** — Lorsqu’une seule crate/target KSP nécessite temporairement une verbosité `debug` ou `trace`, le profil Logging général n’est pas relevé par défaut : un `target_filter` autorise cette verbosité uniquement pour le target concerné et un sink dédié la route avec son propre `OutputFilter`. Les sinks généraux peuvent ainsi rester à `info`/`warn`. Un relèvement global du profil n’est retenu que lorsqu’un diagnostic transversal le justifie explicitement. ## Program / Execution - **DEP-PROGRAM-001** — `ksp-program-api` peut dépendre de `ksp-core-lib` et `ksp-interface-lib`. - **DEP-PROGRAM-002** — `ksp-program-lib` dépend de `ksp-program-api` et peut dépendre de `ksp-interface-lib`/`ksp-core-lib`. - **DEP-PROGRAM-003** — `ksp-program-api` et `ksp-program-lib` ne dépendent pas du wallet, du transport, du store ou des materializers. - **DEP-PROGRAM-004** — Une implémentation externe `ksp-program--lib` peut dépendre directement de `ksp-program-api` sans dépendre de `ksp-program-lib`. - **DEP-EXECUTION-001** — `ksp-execution-policy-api` dépend du contrat public Program et de Core, pas de `ksp-program-lib`, wallet, transport, store ou UI. - **DEP-EXECUTION-002** — `ksp-execution-lib` dépend de `ksp-program-api`, `ksp-execution-policy-api`, `ksp-wallet-lib`, `ksp-onchain-transport-lib`, `ksp-logging-lib` et Core ; il ne dépend pas de `ksp-program-lib`. - **DEP-EXECUTION-003** — Une implémentation de policy reste située dans une crate de scénario/domaine/produit appropriée et ne devient pas une responsabilité de `ksp-program-lib`. - **DEP-EXECUTION-004** — Une exécution réelle reçoit explicitement une policy ; aucun fallback permissif implicite n'est prévu. - **DEP-EXECUTION-005** — La policy décide/refuse/contraint mais ne réalise pas la simulation, la signature, le transport réseau ou l'interaction UI. - **DEP-EXECUTION-006** — Wallet/signers et provider/transport sont fournis/sélectionnés par la composition supérieure ; `ksp-execution-lib` les orchestre sans définir leur policy de sélection. - **DEP-EXECUTION-007** — Le retry réseau d'un appel identique appartient au transport ; un retry modifiant le lifecycle d'exécution appartient à `ksp-execution-lib`. - **DEP-EXECUTION-008** — `ksp-execution-lib` ne dépend ni de `ksp-store-api` ni de `ksp-store-lib`; la persistence d'un résultat appartient à une composition supérieure. ## Materializer / Store - **DEP-MAT-001** — `ksp-materializer-api` peut dépendre de `ksp-program-api` lorsque les contrats de matérialisation consomment des sorties canoniques de processing. - **DEP-MAT-002** — `ksp-materializer-api` et `ksp-materializer-lib` ne dépendent pas de `ksp-store-api` ou `ksp-store-lib`. - **DEP-MAT-003** — Une matérialisation générique doit pouvoir produire un output compatible avec le journal D3 sans imposer une table PostgreSQL spécialisée par materializer. - **DEP-STORE-001** — `ksp-store-api` ne dépend pas de Program, Materializer ou Transport. - **DEP-STORE-002** — `ksp-store-lib` dépend de `ksp-store-api` et contient l'implémentation PostgreSQL de référence ; il ne dépend pas des implémentations Program/Materializer/Transport. - **DEP-STORE-003** — Les workers/jobs spécialisés sont propriétaires des conversions entre modèles runtime et DTO persistants. - **DEP-STORE-004** — Les niveaux durables sont D1 Raw, D2 Core canonique, D3 journal de matérialisation générique et D4 projections spécialisées. - **DEP-STORE-005** — Les replays D1 -> D2, D2 -> D3 et D3 -> D4 doivent pouvoir être exécutés indépendamment. - **DEP-STORE-006** — Une notification de donnée persistée ne constitue jamais la source de vérité du backlog ; les queries Store et marqueurs durables d'idempotence/version de processor font autorité. - **DEP-STORE-007** — Une notification de donnée est publiée seulement après persistence/commit réussis. - **DEP-STORE-008** — D4 est organisé par faits canoniques quand les invariants le permettent, et non par familles de tables propres aux protocoles. ## Transport - **DEP-TRANSPORT-001** — `ksp-onchain-transport-lib` ne dépend pas de `ksp-store-api` ou `ksp-store-lib`. - **DEP-TRANSPORT-002** — Les providers on-chain normalisent leurs réponses dans des modèles KSP homogènes par catégorie de données avant exposition aux consommateurs. - **DEP-TRANSPORT-003** — Les modèles de transport ne réalisent pas de décodage métier/protocolaire et doivent rester facilement convertibles en DTO raw persistants. - **DEP-TRANSPORT-004** — Aucun `ksp-onchain-transport-api` ou `ksp-offchain-transport-api` global n'est créé dans l'architecture actuelle. - **DEP-TRANSPORT-005** — `ksp-onchain-transport-lib` et `ksp-offchain-transport-lib` ne dépendent pas de `ksp-config-lib` : ils possèdent leurs settings/runtime contracts publics, tandis qu'une couche de composition ou un adaptateur appartenant à Config traduit les documents de configuration vers ces contrats. ## Pipelines spécialisés - **DEP-PIPE-001** — KSP ne crée pas de `ksp-pipeline-lib` monolithique. - **DEP-PIPE-002** — Les frontières canoniques de processing sont `RAW -> CORE -> DECODE -> SPECIALIZED`. Une crate pipeline dédiée n'est créée que lorsqu'une logique doit réellement être réutilisée entre plusieurs lifecycle hosts (worker/job/app/test) ; aucune liste globale de quatre crates pipeline n'est imposée par symétrie. - **DEP-PIPE-003** — Un pipeline de processing dépend des APIs nécessaires à sa frontière et non des implémentations officielles correspondantes lorsque l'API permet l'injection/composition. - **DEP-PIPE-004** — Les pipelines spécialisés ne dépendent pas de `ksp-worker-api` ou `ksp-job-api`; worker et job possèdent le lifecycle. - **DEP-PIPE-005** — Worker live et job de replay/backfill réutilisent le même pipeline pour une même frontière durable afin d'éviter la duplication de logique. - **DEP-PIPE-006** — Le pipeline raw ingestion peut dépendre des modèles homogènes de `ksp-onchain-transport-lib` et de `ksp-store-api`, mais pas de `ksp-store-lib`. - **DEP-PIPE-007** — La transformation `RAW -> CORE` est Solana-générique et ne dépend ni de `ksp-program-api`, ni de `ksp-program-lib`, ni de `ksp-materializer-api`; les premiers contrats Program interviennent seulement à partir de `CORE -> DECODE`. - **DEP-PIPE-008** — À partir de `CORE -> DECODE`, les pipelines/processors verticaux peuvent dépendre de `ksp-program-api` et de `ksp-materializer-api` selon leur rôle, sans dépendre par défaut des implémentations officielles correspondantes lorsque l'injection/composition suffit. `DECODE -> SPECIALIZED` utilise de même les contrats de matérialisation/projection nécessaires sans imposer une implémentation globale unique. ## Worker / Job lifecycle - **DEP-WORKER-001** — `ksp-worker-control-lib` dépend de `ksp-worker-api` et ne dépend pas de `ksp-job-api`. - **DEP-WORKER-002** — Les workers de processing reconstruisent leur backlog depuis `ksp-store-api`/Store ; une notification ne suffit pas à prouver qu'un input a été traité. - **DEP-WORKER-003** — La logique réutilisable d'un worker/job dépend en priorité des APIs KSP (`ksp-store-api`, `ksp-program-api`, `ksp-materializer-api`, etc.) et reçoit les implémentations par composition. Le binaire/service mince peut câbler `ksp-store-lib` ou les implémentations officielles nécessaires sans transférer cet ownership à la logique du worker/job. - **DEP-JOB-001** — `ksp-job-api` ne dépend ni de `ksp-worker-api` ni de `ksp-worker-control-lib`. - **DEP-JOB-002** — Un orchestrateur futur peut consommer séparément les APIs/contrôles workers et jobs sans introduire un lifecycle parent commun. - **DEP-JOB-003** — Lorsqu'une même transformation existe en live et en replay, jobs et workers réutilisent la même logique de transformation au lieu de dupliquer `RAW -> CORE`, `CORE -> DECODE` ou `DECODE -> SPECIALIZED`. ## Services, applications et control plane - **DEP-SERVICE-001** — Chaque worker concret doit pouvoir fonctionner comme service/processus indépendant. - **DEP-SERVICE-002** — La direction de packaging préférée est un package `ksp-worker-` contenant une cible bibliothèque réutilisable et une cible binaire autonome mince. - **DEP-SERVICE-003** — Un worker concret ne dépend pas d'un autre worker concret ; les données transitent par les niveaux durables Store. - **DEP-SERVICE-004** — Le binaire worker compose/initialise le service mais ne duplique pas le pipeline ou la logique métier de sa cible bibliothèque. - **DEP-CONTROL-001** — `ksp-worker-api` définit la sémantique de lifecycle indépendamment du transport local/IPC. - **DEP-CONTROL-002** — `ksp-worker-control-lib` dépend de `ksp-worker-api` et peut plus tard adapter des handles locaux ou proxies distants. - **DEP-CONTROL-003** — Le control plane ne transporte pas les payloads D1/D2/D3/D4 entre workers. - **DEP-CONTROL-004** — Aucun `ksp-ipc-api` générique n'est introduit avant le premier besoin concret de transport de control. - **DEP-APP-001** — Les applications spécialisées sont privilégiées avant une future application globale. - **DEP-APP-002** — Une app manager worker pilote le service via les contrats de control et ne modifie pas directement son état interne de processing dans PostgreSQL. - **DEP-SCENARIO-001** — Une app scenario dépend de `ksp-scenario--lib` ; le workflow du scenario ne réside pas dans l'application. - **DEP-SCENARIO-002** — Une crate scenario ne dépend pas de Tauri et doit pouvoir être appelée depuis d'autres interfaces/tests. ## Propriété des dépendances Solana - **DEP-SOL-001** — Une dépendance externe relative à Solana doit avoir un composant KSP propriétaire précis. - **DEP-SOL-002** — Les bibliothèques KSP de haut niveau qui n'ont pas besoin d'un contrat externe bas niveau ne dépendent pas directement de ce contrat. - **DEP-SOL-003** — Les primitives Solana/Anza suffisamment fondamentales et stables peuvent être utilisées dans les bibliothèques KSP de bas niveau qui en sont propriétaires. - **DEP-SOL-004** — La liste initialement acceptée de primitives fondamentales comprend `solana-pubkey`, `solana-keypair`, `solana-signer`, `solana-hash` et `solana-nonce`. - **DEP-SOL-005** — L'ajout d'une autre crate Solana/Anza est décidé à partir d'un besoin concret et de sa stabilité/API. - **DEP-SOL-006** — Une bibliothèque KSP peut exposer ou réexporter une primitive externe fondamentale lorsque cette primitive fait intentionnellement partie du contrat KSP. ## Crates de protocoles et interfaces wire - **DEP-PROTO-001** — Les crates d'interface/protocole externes telles que `mpl-token-metadata` ou `spl-elgamal-registry-interface` sont interdites par défaut comme dépendances runtime KSP. - **DEP-PROTO-002** — KSP préfère posséder ses représentations compatibles nécessaires : Program IDs, discriminants, layouts, enums, structures wire, règles de PDA, sérialisation/désérialisation et autres contrats effectivement requis. - **DEP-PROTO-003** — Une réimplémentation KSP vise le contrat nécessaire et ne consiste pas à copier mécaniquement l'architecture ou l'intégralité d'une crate externe. - **DEP-PROTO-004** — La méthode de vérification de compatibilité wire et l'usage éventuel de dépendances externes uniquement en tests de conformité doivent être définis avant la première implémentation concernée. - **DEP-PROTO-005** — Une dépendance protocolaire externe exceptionnellement nécessaire doit être explicitement justifiée et confinée au composant propriétaire le plus bas possible. ## Versions - **DEP-VER-001** — KSP privilégie les versions récentes compatibles des dépendances. - **DEP-VER-002** — Une version volontairement ancienne, bornée ou incompatible avec la politique générale est documentée avec la raison, le propriétaire et la condition permettant de lever la contrainte. - **DEP-VER-003** — Les lockfiles ne servent pas à figer silencieusement une version de dépendance ; les contraintes nécessaires appartiennent aux manifests et à la documentation.