v0.2.0-pre.002
This commit is contained in:
@@ -1,202 +1,201 @@
|
||||
<!-- file: docs/architecture/002-LAYERS_AND_DEPENDENCIES.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Couches et dépendances KSP
|
||||
|
||||
## Rôle des niveaux
|
||||
## Rôle des niveaux architecturaux
|
||||
|
||||
Les niveaux N1 à N4 servent à raisonner sur les responsabilités, la stabilité et le sens des dépendances. Ils ne constituent pas une chaîne d'appels obligatoire.
|
||||
Les niveaux architecturaux N1–N4 décrivent les familles de composants du projet. Ils ne doivent pas être confondus avec les niveaux durables D1–D4.
|
||||
|
||||
Les niveaux durables de données utilisent une nomenclature distincte **D1 à D4** afin de ne jamais être confondus avec les couches architecturales N1 à N4 : D1 Raw, D2 Core canonique, D3 journal de matérialisation générique et D4 projections spécialisées.
|
||||
### N1 — Fondations communes
|
||||
|
||||
Une couche supérieure peut dépendre directement d'une bibliothèque KSP plus basse lorsque cette bibliothèque est exactement la propriétaire de la capacité recherchée.
|
||||
- `ksp-core-lib` ;
|
||||
- `ksp-logging-lib` ;
|
||||
- `ksp-config-lib` ;
|
||||
- premières règles/outils transversaux.
|
||||
|
||||
## N1 — Fondations
|
||||
|
||||
N1 contient les contrats et services transversaux qui doivent rester bas dans le graphe de dépendances.
|
||||
|
||||
Positionnement actuellement retenu :
|
||||
|
||||
- `ksp-core-lib` — primitives et contrats fondamentaux réellement transversaux, type d'erreur commun KSP et responsabilité autrefois séparée des identifiants de programmes ;
|
||||
- `ksp-interface-lib` — façade KSP des interfaces/wire on-chain nécessaires aux autres bibliothèques ;
|
||||
- `ksp-config-lib` — contrats, chargement/résolution et manipulation autorisée de la configuration et des profils ;
|
||||
- `ksp-logging-lib` — façade commune de logging/tracing, propriétaire de l'initialisation et des dépendances directes `tracing`, `tracing-appender` et `tracing-subscriber`.
|
||||
|
||||
`ksp-logging-lib` peut dépendre de `ksp-core-lib` pour le contrat commun `Error` / `Result`. La relation inverse n'est pas requise : `ksp-core-lib` reste sans dépendance logging tant qu'aucun besoin réel ne la justifie.
|
||||
|
||||
Les crates KSP contenant du comportement/runtime peuvent dépendre directement de `ksp-logging-lib` afin de produire des logs structurés aux niveaux `error`, `warn`, `info`, `debug` et `trace`. Les crates `*-api` purement déclaratives n'ajoutent pas cette dépendance sans comportement réel à logger.
|
||||
|
||||
Une bibliothèque N1 ne doit pas dépendre d'une fonctionnalité métier située dans une couche supérieure.
|
||||
|
||||
## N2 — Capacités Solana
|
||||
|
||||
N2 regroupe les capacités réutilisables opérant sur Solana au-dessus des fondations.
|
||||
|
||||
Le nom `ksp-program-lib` est retenu pour la bibliothèque propriétaire du traitement des programmes : décodage et préparation technique d'opérations via `ProgramExecutionPreparer`. Elle doit s'appuyer sur `ksp-interface-lib` plutôt que faire porter les contrats wire aux applications.
|
||||
|
||||
Les autres responsabilités N2 candidates comprennent notamment :
|
||||
### N2 — Capacités Solana réutilisables
|
||||
|
||||
- `ksp-onchain-transport-lib` ;
|
||||
- `ksp-offchain-transport-lib` lorsqu'un premier besoin réel justifiera son implémentation ;
|
||||
- `ksp-wallet-lib`.
|
||||
- `ksp-offchain-transport-lib` ;
|
||||
- `ksp-wallet-lib` ;
|
||||
- `ksp-interface-lib` ;
|
||||
- `ksp-program-api` puis implementations Program ;
|
||||
- `ksp-execution-policy-api` et orchestration d'exécution lorsqu'un vertical slice réel le justifie.
|
||||
|
||||
Le transport off-chain est général : il ne se limite pas aux metadata et pourra servir à des ressources telles que metadata externes, prix de référence, services de routage ou autres données hors blockchain.
|
||||
### N3 — Données, jobs, workers et processing
|
||||
|
||||
## N3 — Données et orchestration réutilisable
|
||||
- `ksp-store-api` / `ksp-store-lib` ;
|
||||
- `ksp-materializer-api` / implementations lorsque DECODE s'ouvre ;
|
||||
- `ksp-job-api` et jobs ;
|
||||
- `ksp-worker-api` et workers ;
|
||||
- processors/pipelines spécialisés réellement réutilisés.
|
||||
|
||||
N3 doit accueillir les responsabilités qui interprètent, persistent ou orchestrent des capacités inférieures, notamment :
|
||||
### N4 — Exécutables
|
||||
|
||||
- matérialisation ;
|
||||
- stockage ;
|
||||
- replay/reconstruction ;
|
||||
- pipelines ;
|
||||
- scénarios réutilisables ;
|
||||
- contrôle/orchestration de workers lorsqu'il sera introduit.
|
||||
- applications desk ;
|
||||
- services workers ;
|
||||
- outils/jobs exécutables ;
|
||||
- demos/scenarios ;
|
||||
- future orchestration globale.
|
||||
|
||||
### W1
|
||||
## Chaîne durable indépendante des niveaux N1–N4
|
||||
|
||||
W1 est un worker d'acquisition live/quasi-live uniquement.
|
||||
|
||||
Il consomme au minimum les contrats de configuration, transport on-chain et stockage nécessaires pour :
|
||||
|
||||
1. écouter les sources configurées ;
|
||||
2. rapatrier les données ;
|
||||
3. les persister sous forme raw ;
|
||||
4. notifier qu'une nouvelle information raw est disponible.
|
||||
|
||||
W1 :
|
||||
|
||||
- ne décode pas ;
|
||||
- ne matérialise pas ;
|
||||
- ne réalise pas de replay ;
|
||||
- ne décide pas de l'utilisation métier des données collectées ;
|
||||
- doit pouvoir faire évoluer à chaud ce qu'il écoute, rapatrie ou stocke selon les mécanismes de configuration/commande qui seront définis.
|
||||
|
||||
Les notifications W1 servent de wake-up. Les workers/jobs downstream reconstruisent leur backlog depuis le Store et appliquent les pipelines spécialisés correspondant aux frontières D1 -> D2 -> D3 -> D4.
|
||||
|
||||
### Workers de processing futurs
|
||||
|
||||
Le processing continu n'est plus modélisé comme un unique W2. Il sépare `ksp-worker-core-processor`, `ksp-worker-generic-materializer` et `ksp-worker-domain-projector` afin de respecter les frontières durables D1 Raw -> D2 Core -> D3 journal de matérialisation générique -> D4 projections de domaine. Le lifecycle, backlog, claim/lease et replay sont détaillés dans `009-ACQUISITION_WORKERS_AND_JOBS.md`.
|
||||
|
||||
## N4 — Exécutables
|
||||
|
||||
N4 contient les applications, demos et workers.
|
||||
|
||||
### Dépendances directes autorisées
|
||||
|
||||
N4 n'est pas obligé de traverser N3 puis N2 pour atteindre N1.
|
||||
|
||||
Exemples valides :
|
||||
La chaîne de données canonique est :
|
||||
|
||||
```text
|
||||
ksp-app-config-desk
|
||||
└── ksp-config-lib
|
||||
|
||||
ksp-app-store-desk
|
||||
├── ksp-store-lib
|
||||
└── ksp-config-lib
|
||||
D1 RAW
|
||||
-> D2 CORE
|
||||
-> D3 DECODE
|
||||
-> D4 SPECIALIZED
|
||||
```
|
||||
|
||||
Une application de configuration n'a aucune raison de dépendre de couches Solana qui ne participent pas à sa fonction.
|
||||
Aliases fonctionnels :
|
||||
|
||||
Une application de store peut utiliser `ksp-config-lib` pour sélectionner/résoudre un profil et `ksp-store-lib` pour valider, initialiser ou reconstruire le stockage. Elle ne doit pas réimplémenter ces opérations ni appeler directement le backend propriétaire.
|
||||
```text
|
||||
RAW -> CORE -> DECODE -> SPECIALIZED
|
||||
```
|
||||
|
||||
## Applications et demos
|
||||
RAW et CORE sont indépendants du décodage Program.
|
||||
|
||||
Une application ou demo :
|
||||
CORE est une normalisation générique de Solana : structure des blocs, transactions, messages, comptes, instructions/CPI brutes, logs/meta et relations fondamentales.
|
||||
|
||||
- recueille et présente les données ;
|
||||
- effectue les conversions/validations strictement liées à son interface ;
|
||||
- sélectionne les options, profils et scénarios autorisés ;
|
||||
- appelle les bibliothèques KSP propriétaires ;
|
||||
- affiche ou exporte les résultats.
|
||||
Le premier decoder Program intervient seulement à `CORE -> DECODE`.
|
||||
|
||||
Elle ne doit pas réécrire :
|
||||
## Progression par couche
|
||||
|
||||
- le décodage ;
|
||||
- la logique protocolaire ;
|
||||
- les PDA et layouts ;
|
||||
- la construction d'instructions ;
|
||||
- la matérialisation ;
|
||||
- les opérations de stockage ;
|
||||
- les scénarios réutilisables ;
|
||||
- les autres opérations appartenant à une bibliothèque inférieure.
|
||||
### RAW et CORE
|
||||
|
||||
Lorsqu'une bibliothèque de scénarios possède déjà un workflow de démonstration, l'application demo doit l'appeler.
|
||||
Ces deux couches sont construites horizontalement.
|
||||
|
||||
Les demos/scénarios doivent rester séparés par responsabilité fonctionnelle cohérente. Un regroupement n'est autorisé que lorsque plusieurs interfaces représentent réellement le même domaine fonctionnel.
|
||||
À la fin de chaque couche, KSP ajoute les composants d'exploitation nécessaires : persistence, replay/backfill, worker/service et application de contrôle lorsque utiles.
|
||||
|
||||
Exemples actuellement retenus :
|
||||
### DECODE et SPECIALIZED
|
||||
|
||||
- Memo : demo/scénarios séparés ;
|
||||
- SPL Token classique : demo/scénarios séparés ;
|
||||
- Associated Token Account : demo/scénarios séparés ;
|
||||
- Token-2022 : demo/scénarios séparés ;
|
||||
- metadata d'assets/tokens : Metaplex Token Metadata et Token-2022 Metadata peuvent partager une même famille de demo/scénarios ;
|
||||
- Solana Program Metadata (SPM) reste séparé car il n'appartient pas à la même catégorie fonctionnelle.
|
||||
À partir du décodage, KSP progresse verticalement par groupe fonctionnel :
|
||||
|
||||
## Workers
|
||||
```text
|
||||
wire
|
||||
-> decode
|
||||
-> materialize
|
||||
-> specialized projection si utile
|
||||
-> execution preparation
|
||||
-> policy
|
||||
-> execute
|
||||
-> scenarios
|
||||
```
|
||||
|
||||
Les workers sont différents des interfaces utilisateur. Ils peuvent contenir l'orchestration runtime strictement nécessaire à leur responsabilité.
|
||||
Cela évite de développer tous les decoders avant les matérialisations et toutes les executions.
|
||||
|
||||
Un worker doit néanmoins consommer les bibliothèques KSP propriétaires des contrats Solana et ne doit pas dépendre directement de crates Solana/protocoles externes.
|
||||
## Séparation maximale des dépendances
|
||||
|
||||
Les premiers managers de workers sont spécialisés et séparés. Une application globale est un produit futur, tandis qu'un orchestrateur commun reste une abstraction à réévaluer seulement lorsqu'un besoin opérationnel concret le justifie.
|
||||
Chaque composant possède son contrat et reçoit explicitement les données nécessaires.
|
||||
|
||||
Exemples structurants :
|
||||
|
||||
```text
|
||||
ksp-onchain-transport-lib -X-> ksp-config-lib
|
||||
ksp-onchain-transport-lib -X-> ksp-store-api
|
||||
ksp-wallet-lib -X-> ksp-onchain-transport-lib
|
||||
ksp-wallet-lib -X-> execution policy
|
||||
ksp-interface-lib -X-> ksp-program-api
|
||||
ksp-execution-lib -X-> ksp-program-lib
|
||||
```
|
||||
|
||||
La composition supérieure relie les composants.
|
||||
|
||||
## Configuration
|
||||
|
||||
`ksp-config-lib` est l'unique propriétaire des documents Config, `.env` et variables KSP/KSPB.
|
||||
|
||||
Un composant ne dépend pas de Config pour être utilisable. Il expose des settings publics.
|
||||
|
||||
Config peut fournir un document standard et un adapter vers ces settings lorsque cela devient utile :
|
||||
|
||||
```text
|
||||
ksp-config-lib -> public settings du composant
|
||||
```
|
||||
|
||||
sans dépendance inverse.
|
||||
|
||||
## Logging
|
||||
|
||||
`ksp-logging-lib` reste l'unique façade KSP de tracing runtime.
|
||||
|
||||
Les crates comportant du comportement runtime peuvent en dépendre. Les crates `*-api` purement déclaratives n'ajoutent cette dépendance que si elles ont réellement un comportement à logger.
|
||||
|
||||
## Applications
|
||||
|
||||
Les applications Tauri restent minces :
|
||||
|
||||
- DTOs applicatifs ;
|
||||
- composition de services KSP ;
|
||||
- lifecycle fenêtre/UI ;
|
||||
- instrumentation frontend ;
|
||||
- aucun déplacement de logique de transport, Wallet, Config, Program, Store ou Materializer dans Tauri.
|
||||
|
||||
Des applications spécialisées sont ajoutées au fur et à mesure pour valider les couches : Config Desk, Wallet Desk, Price Desk, backfill/RAW tooling, CORE tooling puis Market Desk.
|
||||
|
||||
## Workers et jobs
|
||||
|
||||
Un worker est un service continu/autonome ; un job est borné/terminable.
|
||||
|
||||
Ils utilisent des APIs lifecycle distinctes et ne s'appellent pas entre eux pour transférer les payloads du data plane.
|
||||
|
||||
Le Store reste le point durable de synchronisation entre couches de processing.
|
||||
|
||||
## Firewall des dépendances externes
|
||||
|
||||
Les exécutables KSP dépendent des bibliothèques KSP pour les capacités Solana.
|
||||
Les exécutables et couches supérieures n'importent pas directement les crates Solana/protocoles métier lorsqu'une façade KSP existe ou est prévue.
|
||||
|
||||
```text
|
||||
application / demo / worker
|
||||
│
|
||||
▼
|
||||
bibliothèques KSP
|
||||
│
|
||||
▼
|
||||
primitives externes explicitement autorisées
|
||||
│
|
||||
▼
|
||||
Solana
|
||||
```
|
||||
Exceptions bas niveau explicitement autorisées restent limitées aux primitives stables décidées par les règles KSP.
|
||||
|
||||
Une dépendance externe Solana ou protocolaire doit être possédée par la bibliothèque KSP la plus basse et la plus cohérente avec sa responsabilité.
|
||||
|
||||
## Sens des dépendances
|
||||
|
||||
Le principe recherché est :
|
||||
|
||||
```text
|
||||
N4 ───────► N3 / N2 / N1
|
||||
N3 ───────► N2 / N1
|
||||
N2 ───────► N1
|
||||
N1 ───────► fondations externes explicitement autorisées
|
||||
```
|
||||
|
||||
Il n'est pas permis d'introduire une dépendance vers une couche supérieure pour résoudre localement un problème. Si cela semble nécessaire, le classement des responsabilités doit être réexaminé.
|
||||
`ksp-interface-lib` concentre les interfaces/wires officielles ou compatibles afin d'éviter les doublons de générations et les dépendances protocolaires dans les couches supérieures.
|
||||
|
||||
## Principe contract-first
|
||||
|
||||
Les contrats minimaux entre couches doivent être définis suffisamment tôt pour que les composants futurs puissent se construire contre une frontière KSP stable, même lorsque l'implémentation complète arrive dans une version ultérieure.
|
||||
Une crate `*-api` est créée uniquement lorsque l'extension externe/backend/lifecycle exige un contrat séparé.
|
||||
|
||||
Ce principe s'applique notamment aux futurs :
|
||||
Cas décidés :
|
||||
|
||||
- decoders ;
|
||||
- `ProgramExecutionPreparer` / constructeurs d'opérations ;
|
||||
- materializers ;
|
||||
- store/repositories ;
|
||||
- transports ;
|
||||
- scénarios ;
|
||||
- notifications et contrôle des workers ;
|
||||
- orchestrateur.
|
||||
```text
|
||||
ksp-program-api
|
||||
ksp-materializer-api
|
||||
ksp-store-api
|
||||
ksp-worker-api
|
||||
ksp-job-api
|
||||
ksp-execution-policy-api
|
||||
```
|
||||
|
||||
Il ne signifie pas qu'il faut implémenter prématurément toutes les fonctionnalités. Les interfaces/traits peuvent évoluer légèrement lorsque l'expérience révèle un besoin réel, mais une dépendance entre couches ne doit pas être remplacée par un couplage ad hoc sous prétexte que le contrat final n'existe pas encore.
|
||||
`ksp-interface-lib`, Wallet et transports conservent pour l'instant leurs APIs publiques dans leur bibliothèque d'implémentation.
|
||||
|
||||
## Groupes Program prioritaires
|
||||
|
||||
Après RAW/CORE :
|
||||
|
||||
```text
|
||||
Solana Core Programs
|
||||
-> SPL token/trading
|
||||
-> token metadata
|
||||
-> Anchor
|
||||
-> Meteora
|
||||
-> Raydium
|
||||
-> Pump
|
||||
-> Orca
|
||||
-> Market Desk V1
|
||||
-> Jupiter/OKX routing
|
||||
-> Market Desk V2
|
||||
-> trading-adjacent
|
||||
-> general decoding
|
||||
```
|
||||
|
||||
Un satellite nécessaire à un protocole reste dans son groupe : Pump fee avec Pump, Meteora vault avec Meteora, etc.
|
||||
|
||||
## Questions encore ouvertes
|
||||
|
||||
- représentation interne exacte du type d'erreur commun KSP, à traiter dès `0.1.1-pre.001` ;
|
||||
- types publics précis de `ksp-program-api` et format ouvert/persistable des résultats décodés ;
|
||||
- méthode de conformité wire contre les projets externes ;
|
||||
- forme exacte des settings publics Transport ;
|
||||
- nécessité future d'un pool automatique de sessions WebSocket ;
|
||||
- split éventuel d'une API Interface séparée uniquement si un vrai besoin apparaît ;
|
||||
- contrats Rust exacts de Program/Materializer/Store ;
|
||||
- mécanisme IPC du premier manager de worker autonome ;
|
||||
- besoins de contexte des futurs `DomainProjector` stateful ;
|
||||
- nécessité réelle d'un orchestrateur commun lorsque plusieurs services/managers existeront.
|
||||
- granularité future des workers DECODE/SPECIALIZED par groupe.
|
||||
|
||||
Reference in New Issue
Block a user