Files
khadhroony-solana-project/docs/rules/RULES_DEPENDENCIES.md
2026-08-17 21:03:51 +02:00

20 KiB
Raw Blame History

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-<domain>-api ne dépend jamais de l'implémentation officielle ksp-<domain>-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 <dependency>.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 <dependency> = { 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-002ksp-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-001ksp-logging-lib est le propriétaire KSP direct de tracing, tracing-appender, tracing-subscriber et de l'initialisation/configuration runtime logging.
  • DEP-LOG-002ksp-logging-lib peut dépendre de ksp-core-lib pour le contrat commun Error / Result.
  • DEP-LOG-003ksp-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-008ksp-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 lexpansion des macros de ksp-logging-lib est un détail dimplémentation réservé à ces macros ; une crate consommatrice ne lutilise 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 quun littéral dispersé.
  • DEP-LOG-011env!("CARGO_PKG_NAME") ne sert pas de target de tracing/logging KSP : le target appartient au contrat dobservabilité et doit rester explicite dans le code. Les metadata Cargo restent autorisées lorsquelles sont réellement la donnée recherchée, par exemple pour un User-Agent ou une information de build.

Program / Execution

  • DEP-PROGRAM-001ksp-program-api peut dépendre de ksp-core-lib et ksp-interface-lib.
  • DEP-PROGRAM-002ksp-program-lib dépend de ksp-program-api et peut dépendre de ksp-interface-lib/ksp-core-lib.
  • DEP-PROGRAM-003ksp-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-<name>-lib peut dépendre directement de ksp-program-api sans dépendre de ksp-program-lib.
  • DEP-EXECUTION-001ksp-execution-policy-api dépend du contrat public Program et de Core, pas de ksp-program-lib, wallet, transport, store ou UI.
  • DEP-EXECUTION-002ksp-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-008ksp-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-001ksp-materializer-api peut dépendre de ksp-program-api lorsque les contrats de matérialisation consomment des sorties canoniques de processing.
  • DEP-MAT-002ksp-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-001ksp-store-api ne dépend pas de Program, Materializer ou Transport.
  • DEP-STORE-002ksp-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-001ksp-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-005ksp-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-001ksp-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-001ksp-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-<role> 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-001ksp-worker-api définit la sémantique de lifecycle indépendamment du transport local/IPC.
  • DEP-CONTROL-002ksp-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-<domain>-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.