Files
khadhroony-solana-project/docs/architecture/005-DEPENDENCY_GRAPH.md
2026-08-14 11:42:19 +02:00

698 lines
18 KiB
Markdown

<!-- file: docs/architecture/005-DEPENDENCY_GRAPH.md -->
<!-- version: 3 -->
# Graphe de dépendances KSP
## Objet
Ce document constitue la sortie principale de `0.0.3-pre.003`.
Il répond à la question : **quels composants peuvent dépendre de quels autres composants, et où doivent se produire la composition, l'I/O et les conversions de modèles ?**
Convention des graphes :
```text
A -> B
```
signifie : **A peut dépendre de B**.
Le graphe exprime une direction architecturale. Une dépendance autorisée n'est pas obligatoire si l'implémentation peut rester plus faible.
## Principes structurants
### 1. APIs sous les implémentations
Une crate `ksp-<domain>-api` est placée sous les implémentations de son domaine.
```text
implementation -> domain-api
```
Une API publique ne dépend pas de son implémentation officielle.
### 2. Transformations séparées de l'I/O
Les bibliothèques de sémantique/transformation comme `ksp-program-lib` et `ksp-materializer-lib` ne deviennent pas propriétaires :
- du transport réseau ;
- du wallet ;
- du backend PostgreSQL ;
- du lifecycle d'un worker/job.
Les workers, jobs, scenarios et pipelines spécialisés composent ces capacités lorsqu'ils ont réellement besoin d'I/O.
### 3. Modèles de domaine distincts des DTO persistants
KSP ne crée pas actuellement un `ksp-data-api` global.
Chaque frontière possède les modèles nécessaires à sa responsabilité :
- transport : modèles homogènes de transport ;
- program : contrats de décodage/opération préparée ;
- materializer : entrées/sorties de matérialisation ;
- store : modèles persistants et références de données persistées.
La conversion entre ces modèles est explicite dans la couche qui relie les deux responsabilités, principalement les workers/jobs spécialisés.
### 4. Composition supérieure pour l'exécution
`ksp-program-lib` ne dépend pas de `ksp-wallet-lib` ou de `ksp-onchain-transport-lib`.
Le cycle signature/simulation/envoi/confirmation est composé au-dessus, par `ksp-execution-lib`.
### 5. Workers et jobs restent deux familles
`ksp-worker-api` et `ksp-job-api` n'ont pas de parent lifecycle commun.
Un orchestrateur futur peut consommer les deux familles séparément sans les fusionner.
---
# Graphe fondations N1
```text
ksp-core-lib
ksp-logging-lib -> ksp-core-lib
ksp-config-lib -> ksp-core-lib
ksp-config-lib -> ksp-logging-lib # lorsque du runtime logging est nécessaire
ksp-interface-lib -> ksp-core-lib
ksp-interface-lib -> ksp-logging-lib # lorsque du runtime logging est nécessaire
```
`ksp-core-lib` ne dépend d'aucun composant KSP supérieur.
`ksp-interface-lib` est propriétaire de la façade wire et peut dépendre des crates externes Solana/interface explicitement autorisées par `RULES_DEPENDENCIES.md`.
`ksp-logging-lib` est la façade logging/tracing KSP et peut dépendre de `ksp-core-lib` pour `Error` / `Result`. `ksp-core-lib` n'a pas de dépendance inverse vers le logging. Les composants comportant du runtime peuvent dépendre directement de `ksp-logging-lib`; cette permission n'oblige pas les crates purement déclaratives à le faire.
---
# Graphe Logging
```text
ksp-logging-lib
-> ksp-core-lib
-> tracing / tracing-appender / tracing-subscriber
runtime crate
-> ksp-logging-lib
```
`ksp-logging-lib` est la seule façade KSP propriétaire de l'initialisation/configuration tracing. Une crate runtime ne dépend normalement pas directement de `tracing`.
Exception technique possible : une application/framework, notamment Tauri, peut devoir intégrer un plugin tracing. Cette adaptation ne crée pas une seconde politique de logging parallèle.
`ksp-core-lib` et les crates `*-api` purement déclaratives n'ont pas de dépendance logging obligatoire.
---
# Propriété des codecs wire
Pour les surfaces wire officielles KSP :
```text
ksp-interface-lib
-> codecs wire nécessaires (borsh/wincode/...)
```
`ksp-program-lib` n'ajoute pas directement une autre génération de codec pour les mêmes surfaces.
Une extension Program externe peut temporairement posséder son wire lorsqu'il n'est pas encore officiellement intégré à `ksp-interface-lib`.
Le critère d'adoption d'une crate d'interface externe inclut la compatibilité de son graphe de dépendances avec le stack KSP actuel.
---
# Graphe Program
```text
ksp-program-api
-> ksp-core-lib
-> ksp-interface-lib
ksp-program-lib
-> ksp-program-api
-> ksp-interface-lib
-> ksp-core-lib
```
## Frontière de `ksp-program-api`
`ksp-program-api` doit porter les contrats publics nécessaires à une implémentation externe de decoder/execution preparation.
Il est également le propriétaire candidat du **contrat d'opération préparée** produit par la sémantique programme et consommé par la couche d'exécution.
Noms exacts à définir en `pre.004`, par exemple conceptuellement :
```text
PreparedProgramOperation
ProgramExecutionPlan
```
Le choix du nom/type final n'est pas décidé ici.
## Interdictions Program
```text
ksp-program-api -X-> ksp-wallet-lib
ksp-program-api -X-> ksp-onchain-transport-lib
ksp-program-api -X-> ksp-store-api
ksp-program-api -X-> ksp-materializer-api
ksp-program-lib -X-> ksp-wallet-lib
ksp-program-lib -X-> ksp-onchain-transport-lib
ksp-program-lib -X-> ksp-store-api
ksp-program-lib -X-> ksp-store-lib
ksp-program-lib -X-> ksp-materializer-lib
ksp-program-lib -X-> ksp-execution-lib
```
Le decoder/execution preparation de programme reste donc testable sans réseau, wallet ou base de données.
---
## Implémentations Program externes
Une implémentation externe peut dépendre de :
```text
ksp-program-<name>-lib
-> ksp-program-api
-> ksp-core-lib
-> ksp-interface-lib # lorsque le wire officiel nécessaire existe
```
Elle ne dépend pas obligatoirement de `ksp-program-lib`.
Le runtime peut composer registry officiel + registry/implémentations externes derrière `ksp-program-api`.
# Graphe Execution / Policy
```text
ksp-execution-policy-api
-> ksp-program-api
-> ksp-core-lib
ksp-execution-lib
-> ksp-program-api
-> ksp-execution-policy-api
-> ksp-wallet-lib
-> ksp-onchain-transport-lib
-> ksp-logging-lib
-> ksp-core-lib
```
`ksp-execution-lib` ne dépend pas de `ksp-program-lib` et reçoit fondamentalement une opération déjà préparée conforme à `ksp-program-api`.
## Policy obligatoire et multi-checkpoints
Toute exécution réelle reçoit explicitement une implémentation de `ksp-execution-policy-api`.
La policy peut être consultée à plusieurs checkpoints (préflight, après simulation, avant submission ou autres points réellement justifiés). Le contrat exact ne doit pas imposer plus de callbacks que nécessaire.
La policy peut autoriser/refuser/ajouter des requirements, mais n'appelle ni wallet, ni transport, ni UI.
## Composition supérieure
Le caller fournit notamment :
- réseau/provider/transport sélectionné ;
- wallet/signers sélectionnés ;
- options d'exécution.
`ksp-execution-lib` vérifie/compose ces éléments avec les contraintes techniques de `PreparedProgramExecution` et les contraintes supplémentaires de policy.
## Simulation / signature / submission / confirmation
- primitive simulation/submission/status -> `ksp-onchain-transport-lib` ;
- orchestration de ces étapes -> `ksp-execution-lib` ;
- primitive signature -> `ksp-wallet-lib` ;
- résolution/coordination des signers -> `ksp-execution-lib`.
## Retry
Retry technique d'un appel réseau identique -> transport.
Retry qui change le lifecycle (nouveau blockhash, reconstruction, resimulation, resignature, resubmission) -> execution, éventuellement limité par policy.
## Approbation externe
Une policy peut produire un requirement d'approbation externe. `ksp-execution-lib` peut retourner un état suspendu/reprenable ; l'UI obtient l'approbation sans être appelée directement par la policy ou l'execution lib.
## Store
```text
ksp-execution-policy-api -X-> ksp-store-api
ksp-execution-lib -X-> ksp-store-api
ksp-execution-lib -X-> ksp-store-lib
```
La persistence d'un `ExecutionOutcome` est une composition supérieure.
---
# Graphe Wallet
```text
ksp-wallet-lib
-> ksp-core-lib
```
`ksp-wallet-lib` peut consommer config/logging si nécessaire à son implémentation, sans que ces dépendances deviennent partie obligatoire du contrat wallet.
Interdictions :
```text
ksp-wallet-lib -X-> ksp-program-lib
ksp-wallet-lib -X-> ksp-execution-lib
ksp-wallet-lib -X-> ksp-store-lib
```
Le wallet fournit les capacités de clés/signature ; il n'orchestre pas une opération Solana.
---
# Graphe Transport
## On-chain
```text
ksp-onchain-transport-lib
-> ksp-core-lib
```
Il peut consommer config/logging lorsque nécessaire.
Il peut posséder plusieurs familles internes :
```text
HTTP RPC
WS RPC
Helius advanced
Yellowstone
...
```
sans créer `ksp-onchain-transport-api`.
### Modèles homogènes
Chaque famille provider convertit ses réponses propriétaires vers des modèles KSP homogènes **à l'intérieur de la frontière transport**.
Exemple conceptuel :
```text
Solana RPC ------\
Helius -----------+--> transport raw model
Yellowstone ------/
```
Ces modèles :
- sont indépendants du store ;
- conservent le raw et la provenance nécessaire ;
- sont faciles à convertir vers les modèles persistants.
Interdiction ferme :
```text
ksp-onchain-transport-lib -X-> ksp-store-api
ksp-onchain-transport-lib -X-> ksp-store-lib
```
## Off-chain
```text
ksp-offchain-transport-lib
-> ksp-core-lib
```
Config/logging sont autorisés selon le besoin.
La crate reste volontairement hétérogène. Aucun `ksp-offchain-transport-api` global n'est introduit.
---
# Graphe Materialization
```text
ksp-materializer-api
-> ksp-core-lib
-> ksp-program-api
ksp-materializer-lib
-> ksp-materializer-api
-> ksp-program-api
-> ksp-core-lib
```
`ksp-interface-lib` peut être consommée par `ksp-materializer-lib` lorsqu'une matérialisation a réellement besoin d'un contrat wire déjà possédé par KSP, mais ne doit pas devenir une dépendance obligatoire de toute matérialisation.
## Décision importante
Ni `ksp-materializer-api` ni `ksp-materializer-lib` ne dépendent du store.
```text
ksp-materializer-api -X-> ksp-store-api
ksp-materializer-lib -X-> ksp-store-api
ksp-materializer-lib -X-> ksp-store-lib
```
Une matérialisation transforme des données ; le worker/job/pipeline spécialisé persiste le résultat.
Cette séparation permet également de tester un materializer externe sans PostgreSQL.
---
# Graphe Store
```text
ksp-store-api
-> ksp-core-lib
ksp-store-lib
-> ksp-store-api
-> ksp-core-lib
```
`ksp-store-lib` peut dépendre de config/logging et contient PostgreSQL comme implémentation de référence.
## Indépendance du store
Le store ne dépend pas des implémentations Program/Materializer/Transport :
```text
ksp-store-api -X-> ksp-program-api
ksp-store-api -X-> ksp-materializer-api
ksp-store-api -X-> ksp-onchain-transport-lib
ksp-store-lib -X-> ksp-program-lib
ksp-store-lib -X-> ksp-materializer-lib
ksp-store-lib -X-> ksp-onchain-transport-lib
```
`ksp-store-api` définit les DTO/contrats persistants nécessaires aux niveaux durables sans imposer les modèles runtime des processors.
## Notifications de données persistées
`ksp-store-api` est retenu comme propriétaire du contrat canonique de notification lorsqu'il signifie :
> une donnée persistée de telle catégorie est disponible.
Le même contrat est utilisé quelle que soit l'origine :
```text
live worker ----\
backfill job ----+--> persisted data notification
import ----------/
```
Le mécanisme de diffusion reste hors du contrat :
```text
channel
LISTEN/NOTIFY
IPC
broker
...
```
Le mode de transport concret sera détaillé en `pre.005`.
---
# Graphe lifecycle Worker
```text
ksp-worker-api
-> ksp-core-lib
ksp-worker-control-lib
-> ksp-worker-api
-> ksp-core-lib
```
`ksp-worker-control-lib` ne dépend pas des workers concrets. Il fournit une gouvernance réutilisable au-dessus de l'API.
Les managers/apps/orchestrateurs composent les implémentations concrètes avec cette bibliothèque.
Interdictions :
```text
ksp-worker-api -X-> ksp-job-api
ksp-worker-control-lib -X-> ksp-job-api
```
Le contrôle des jobs ne fuit pas dans la gouvernance workers.
---
# Graphe lifecycle Job
```text
ksp-job-api
-> ksp-core-lib
```
Aucune `ksp-job-control-lib` n'est prévue actuellement.
Interdictions :
```text
ksp-job-api -X-> ksp-worker-api
ksp-job-api -X-> ksp-worker-control-lib
```
Un futur orchestrateur peut utiliser workers et jobs séparément sans créer de superclass lifecycle commune.
---
# Graphe des composants concrets d'acquisition/processing
Les dépendances ci-dessous décrivent la composition attendue. Les détails de processus/IPC seront approfondis plus tard.
## `ksp-worker-raw-retriever`
```text
ksp-worker-raw-retriever
-> ksp-worker-api
-> ksp-config-lib
-> ksp-onchain-transport-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-logging-lib
```
Responsabilité de conversion :
```text
transport raw model
|
v
store raw persistence model
```
Cette conversion appartient au worker d'acquisition, pas au transport ni au store.
## `ksp-job-backfill`
```text
ksp-job-backfill
-> ksp-job-api
-> ksp-config-lib
-> ksp-onchain-transport-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-logging-lib
```
Il utilise la même famille de DTO raw persistants et la même notification de données persistées que W1.
## `ksp-worker-core-processor`
```text
ksp-worker-core-processor
-> ksp-worker-api
-> ksp-program-api
-> ksp-program-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Il effectue la conversion explicite :
```text
store raw DTO
|
v
program decode input
|
v
program canonical/decode output
|
v
store Core DTO
```
`ksp-program-lib` ne connaît donc pas le store.
## `ksp-worker-generic-materializer`
```text
ksp-worker-generic-materializer
-> ksp-worker-api
-> ksp-materializer-api
-> ksp-materializer-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
La frontière exacte des entrées/sorties génériques sera détaillée en `pre.005`.
## `ksp-worker-domain-projector`
```text
ksp-worker-domain-projector
-> ksp-worker-api
-> ksp-materializer-api
-> ksp-materializer-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Son nom reste provisoire.
Il est propriétaire de la composition entre résultats de matérialisation spécialisée et projections persistantes par domaine ; `ksp-materializer-lib` reste indépendant du backend.
---
# Scenarios et applications demo
Une crate scénario peut composer les capacités nécessaires à son domaine :
```text
ksp-scenario-<domain>-lib
-> ksp-program-api
-> ksp-program-lib
-> ksp-execution-policy-api
-> ksp-execution-lib
-> ksp-wallet-lib
-> ksp-onchain-transport-lib
-> ksp-config-lib
```
Toutes ces dépendances ne sont pas obligatoires pour chaque scénario.
La crate scénario peut implémenter une policy Devnet adaptée à son besoin.
L'application correspondante reste une interface :
```text
ksp-app-scenario-<domain>-devnet-desk-demo
-> ksp-scenario-<domain>-lib
```
Elle peut dépendre de bibliothèques KSP d'interface/configuration strictement nécessaires à son UI, mais ne réimplémente ni scénario ni policy métier.
---
# Orchestrateur futur
Le futur orchestrateur est au-dessus des contrôles spécialisés.
Conceptuellement :
```text
orchestrator
-> ksp-worker-control-lib
-> ksp-job-api # séparément, si coordination de jobs nécessaire
-> autres contrôles spécialisés au besoin
```
Cette dépendance simultanée ne crée pas d'API lifecycle commune.
L'orchestrateur coordonne ; il ne fusionne pas les modèles worker/job.
---
# Dépendances explicitement non retenues
Les composants suivants ne sont pas introduits dans le graphe actuel :
```text
ksp-api-lib
ksp-onchain-transport-api
ksp-offchain-transport-api
ksp-wallet-api
ksp-scenario-api
ksp-job-control-lib
ksp-pipeline-lib
ksp-data-api
```
Ils pourront être réévalués uniquement si un besoin concret démontre que la frontière actuelle ne suffit plus.
---
# Contrôle des cycles
Le graphe impose notamment :
```text
core
<- interface
<- program-api
<- materializer-api
store-api
<- store-lib
worker-api
<- worker-control
job-api
<- concrete jobs
```
et interdit toute boucle inverse depuis les couches basses vers leurs consommateurs.
Les conversions entre Program/Materializer/Store ne sont pas résolues par des dépendances croisées mais par des composants de composition explicites.
---
# Questions reportées
`pre.004` doit détailler :
- noms/types exacts des entrées/sorties de `ksp-program-api` ;
- forme exacte de l'opération préparée ;
- appel/injection entre program implementation et `ksp-execution-lib` ;
- contrat exact de `ksp-execution-policy-api` ;
- frontière entre préparation, policy, simulation, signature, envoi et confirmation.
`pre.005` doit détailler :
- DTO raw/Core/materialization/projection du store ;
- entrées/sorties `ksp-materializer-api` ;
- conversion Core runtime <-> store Core ;
- notifications et transport de notifications ;
- niveaux durables/replay/idempotence/provenance ;
- rôle précis des deux workers de matérialisation.
`pre.006` doit détailler :
- managers spécialisés ;
- processus/IPC éventuels ;
- norme des scenarios ;
- apps demo ;
- orchestrateur futur et pipelines spécialisés.