v0.2.0-pre.002

This commit is contained in:
2026-08-17 13:33:37 +02:00
parent 7d40de3249
commit 259bff6707
23 changed files with 2999 additions and 3301 deletions

View File

@@ -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 N1N4 décrivent les familles de composants du projet. Ils ne doivent pas être confondus avec les niveaux durables D1D4.
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.
## N1Fondations
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 :
### N2Capacité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 N1N4
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.

View File

@@ -1,30 +1,17 @@
<!-- file: docs/architecture/003-COMPONENT_CONTRACTS.md -->
<!-- version: 11 -->
<!-- version: 6 -->
# Contrats initiaux des composants KSP
## Objet
Ce document enregistre les frontières déjà suffisamment claires pour guider la planification. Il ne définit pas encore les API Rust finales.
Le principe commun est de définir tôt les contrats nécessaires entre composants, puis d'enrichir les implémentations lorsque le besoin réel apparaît.
L'inventaire détaillé courant est maintenu dans [`004-COMPONENT_INVENTORY.md`](004-COMPONENT_INVENTORY.md), le graphe autorisé/interdit dans [`005-DEPENDENCY_GRAPH.md`](005-DEPENDENCY_GRAPH.md), Wire/Program dans [`006-WIRE_AND_PROGRAM.md`](006-WIRE_AND_PROGRAM.md) Execution/Policy dans [`007-EXECUTION_AND_POLICY.md`](007-EXECUTION_AND_POLICY.md), Data/Materialization/Store dans [`008-DATA_MATERIALIZATION_AND_STORE.md`](008-DATA_MATERIALIZATION_AND_STORE.md) Acquisition/Workers/Jobs dans [`009-ACQUISITION_WORKERS_AND_JOBS.md`](009-ACQUISITION_WORKERS_AND_JOBS.md) et Apps/Services/Scenarios/Control dans [`010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md`](010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md).
Ce document synthétise les responsabilités des composants KSP. Les types Rust exacts restent définis au moment de leur première implémentation réelle.
## Convention API / implémentation
Lorsqu'un domaine doit exposer des contrats publics pouvant être implémentés indépendamment, KSP peut séparer :
Une crate de contrats extensibles se nomme `ksp-<domain>-api`. Une implémentation réutilisable se nomme `ksp-<role>-lib`.
```text
ksp-<domain>-api
ksp-<domain>-lib
```
La crate `ksp-<domain>-api` est techniquement une bibliothèque Rust mais ne porte volontairement pas le suffixe `-lib`.
Cette séparation n'est pas automatique. Elle est utilisée lorsqu'une vraie frontière d'extension/backend/lifecycle la justifie.
Couples retenus :
Couples explicitement retenus :
```text
ksp-program-api / ksp-program-lib
@@ -32,185 +19,192 @@ ksp-materializer-api / ksp-materializer-lib
ksp-store-api / ksp-store-lib
```
APIs lifecycle retenues :
Lifecycle APIs séparées :
```text
ksp-worker-api
ksp-job-api
ksp-execution-policy-api
```
Aucune API commune worker+job n'est prévue.
Une crate `*-api` n'est jamais créée uniquement pour la symétrie des noms.
## Execution policy
## Core
`ksp-execution-policy-api` est un contrat public de décision séparé de `ksp-program-lib`, du wallet, du transport et de l'UI.
`ksp-core-lib` porte les primitives transversales réellement fondamentales, dont `Error`/`Result` et le registre KSP des Program IDs fondamentaux.
Une exécution réelle via `ksp-execution-lib` reçoit explicitement une policy ; aucun fallback permissif implicite n'est prévu.
La policy peut être évaluée à plusieurs checkpoints afin d'intégrer des informations obtenues pendant le cycle, notamment le résultat de simulation.
Une policy peut autoriser, refuser ou imposer des requirements ; elle ne réalise pas elle-même la simulation, la signature, le réseau ou une interaction Tauri.
Les implémentations appartiennent aux crates de contexte appropriées : scenario Devnet, future bibliothèque d'application générale, future policy trading, etc.
Aucune `ksp-execution-policy-lib` générique n'est prévue sans logique réellement commune.
## Execution orchestration
`ksp-execution-lib` consomme fondamentalement `PreparedProgramExecution` conforme à `ksp-program-api` et ne dépend pas de `ksp-program-lib`.
Il orchestre :
- policy checkpoints ;
- assemblage message/transaction ;
- simulation via `ksp-onchain-transport-lib` ;
- résolution des signers et signature via `ksp-wallet-lib` ;
- submission ;
- confirmation ;
- retry d'exécution lorsque celui-ci change le lifecycle ;
- suspension/reprise lorsqu'une approbation externe est requise.
Le wallet et le provider/réseau sont sélectionnés/fournis par la composition supérieure ; `ksp-execution-lib` les utilise sans définir une policy de sélection implicite.
Le retry d'un appel réseau identique reste une responsabilité transport, distincte du retry d'exécution nécessitant reconstruction/resimulation/resignature.
`ksp-execution-lib` ne persiste pas automatiquement son résultat et ne dépend pas du store.
Il ne devient pas une crate de modèles métier ou de transport.
## Logging
`ksp-logging-lib` est la façade KSP unique pour le logging/tracing runtime. Elle importe/initialise directement `tracing`, `tracing-appender` et `tracing-subscriber` et peut dépendre de `ksp-core-lib` pour `Error` / `Result`.
`ksp-logging-lib` est la façade unique KSP de tracing runtime.
Les crates comportementales KSP utilisent sa façade pour leurs événements `error`, `warn`, `info`, `debug`, `trace` et pour leurs spans sync/async. Elles n'émettent pas leurs propres logs via une dépendance directe à la stack tracing.
Les composants runtime émettent leurs événements via cette façade. Les targets tiers sont silencieux par défaut et les informations utiles sont réémises sous le target du composant KSP propriétaire.
Chaque émission KSP indique un target correspondant au nom Cargo de la crate propriétaire ; `domain`, `component` et les autres champs structurés décrivent les subdivisions fonctionnelles sans multiplier les targets.
## Config
Le subscriber KSP rend les targets tiers silencieux par défaut. Lorsqu'une information provenant d'une dépendance externe est nécessaire, la crate KSP qui possède l'opération la réémet explicitement sous son propre target ; Logging ne renomme pas les événements tiers.
`ksp-config-lib` est l'unique propriétaire des documents Config, `.env`, variables KSP/KSPB et persistence Config.
Logging possède ses `LoggingSettings`, ses writers/guards et son lifecycle. Le subscriber global est installé une fois, puis la configuration peut être rechargée à chaud via la façade KSP sans dépendance vers Config.
`ksp-core-lib` n'a pas de dépendance logging requise. Les crates `*-api` purement déclaratives restent sans logging par défaut.
Une application Tauri peut exceptionnellement avoir une dépendance/framework tracing imposée par un plugin, sans définir une politique parallèle à `ksp-logging-lib`; les événements KSP restent émis via la façade KSP.
## Frontière materializer / store
Les niveaux durables utilisent D1 Raw, D2 Core canonique, D3 journal de matérialisation générique et D4 projections spécialisées.
`ksp-materializer-api` peut dépendre de `ksp-program-api` pour consommer des contrats Core ouverts. Il doit pouvoir distinguer conceptuellement une matérialisation générique D2 -> D3 et une projection spécialisée D3 -> D4.
`ksp-materializer-lib` reste une bibliothèque de transformation et ne dépend ni de `ksp-store-api` ni de `ksp-store-lib`.
`ksp-store-api` possède les DTO/contrats persistants et reste indépendant des APIs Program/Materializer. Les workers/jobs de processing convertissent explicitement entre modèles runtime et modèles persistants.
D3 est un journal durable obligatoire ; D4 reste plus évolutif. Cette séparation évite d'introduire un `ksp-data-api` monolithique uniquement pour partager des modèles entre couches.
Les composants exposent leurs settings publics ; Config peut fournir un document standard et un adapter vers ces settings sans créer de dépendance inverse.
## Transport on-chain
Aucune `ksp-onchain-transport-api` séparée n'est prévue.
`ksp-onchain-transport-lib` regroupe les transports/providers on-chain et expose des modèles de sortie homogènes par catégorie de données.
`ksp-onchain-transport-lib` possède :
Il ne dépend pas de `ksp-store-api`.
- settings runtime publics ;
- endpoints/providers/clusters ;
- pools/rôles/capabilities ;
- HTTP JSON-RPC ;
- WebSocket ;
- Yellowstone gRPC et futurs adapters provider lorsque introduits ;
- modèles homogènes par catégorie de donnée ;
- observabilité transport.
Les modèles de transport doivent cependant être conçus pour une conversion explicite et simple vers les modèles raw persistants du store, sans décodage protocolaire.
Il ne dépend pas de Config, Store ou Program.
Pour toute surface normative ciblée, toutes les méthodes documentées sont inventoriées/implémentées sauf impossibilité documentée. Les méthodes deprecated/obsolete encore fonctionnelles et unstable/experimental émettent un warning KSP à l'utilisation.
## Transport off-chain
Aucune `ksp-offchain-transport-api` commune n'est prévue.
La crate est volontairement hétérogène : metadata, prix, quotes, routage et autres ressources externes peuvent avoir des modules/APIs distincts à l'intérieur d'une seule crate afin d'éviter une prolifération de crates artificielles.
`ksp-offchain-transport-lib` peut contenir plusieurs modules/APIs distincts : prix, metadata HTTP/IPFS/Arweave, quotes et autres accès externes. La première surface engagée est le prix SOL/USD et SOL/EUR.
## Wallet
Aucune `ksp-wallet-api` n'est prévue.
Aucune `ksp-wallet-api` séparée n'est prévue.
`ksp-wallet-lib` possède le format wallet KSP et les capacités de lecture/protection/import/export/pubkey/secret/signature nécessaires à ses consommateurs.
`ksp-wallet-lib` possède le format `.kspwallet`, le secret protégé, l'identité publique, signature, import/export et conversions utiles.
## Store et notifications de données
Il ne possède pas `WalletPolicy` ni les règles d'autorisation d'exécution.
`ksp-store-api` reste la frontière backend-agnostic. `ksp-store-lib` contient PostgreSQL comme implémentation de référence.
Le wallet temporaire JSON historique n'est pas migré.
Les notifications de données persistées sont normalisées indépendamment de leur producteur. W1, un job de backfill, un import ou un replay utilisent le même contrat pour signaler le même type de donnée.
## Interface / wire
Une notification est seulement un signal de réveil : le Store et les marqueurs d'idempotence/backlog restent la source de vérité. La publication suit l'ordre `persist -> commit -> notify`.
`ksp-interface-lib` est la façade wire officielle KSP et expose aussi une API publique wire réutilisable par `ksp-program-lib` et les extensions Program externes.
Le contrat de notification est distinct de son transport concret.
Aucune `ksp-interface-api` séparée n'est retenue actuellement.
La crate sélectionne entre réexport contrôlé, wrapper ou implémentation wire compatible selon stabilité, ownership et graphe de dépendances des interfaces externes.
## Program
`ksp-program-api` porte les contrats extensibles de Program : descriptors/capabilities, decoders, outputs et préparation d'exécution lorsque ces contrats sont démontrés.
`ksp-program-lib` porte les implementations officielles et dépend de `ksp-program-api`.
Une crate externe peut implémenter `ksp-program-api` sans dépendre de `ksp-program-lib`.
## Execution policy
`ksp-execution-policy-api` est le contrat commun de décision/safety.
Une policy décide ; elle ne signe pas, n'envoie pas et ne possède ni Wallet ni Transport.
Une petite policy de scenario/orchestrateur peut être implémentée localement. Des bibliothèques communes sont créées uniquement si une réutilisation réelle apparaît.
## Execution orchestration
`ksp-execution-lib` est introduit lorsque le premier vertical slice réel nécessite une orchestration stable entre :
```text
ksp-program-api
ksp-execution-policy-api
ksp-wallet-lib
ksp-onchain-transport-lib
```
Il ne dépend pas de `ksp-program-lib` afin d'accepter des implementations Program externes.
## Store et niveaux durables
La chaîne durable est :
```text
D1 RAW
-> D2 CORE
-> D3 DECODE
-> D4 SPECIALIZED
```
### RAW
Acquisition replayable + provenance, sans décodage Program.
### CORE
Normalisation générique Solana, sans décodage Program.
### DECODE
Interprétation Program/protocole puis matérialisation générique/journal durable.
### SPECIALIZED
Projections queryables de domaine : token, metadata, pools, trades, OHLC, routes, etc.
`ksp-store-api` possède les contrats backend-agnostic. `ksp-store-lib` fournit PostgreSQL comme backend officiel.
La première Store release est RAW-only ; les couches suivantes sont ajoutées quand elles sont réellement ouvertes.
## Materializer
`ksp-materializer-api`/`ksp-materializer-lib` sont introduits avec le premier besoin DECODE réel, pas avant.
Program et Materializer restent indépendants du backend Store ; les composants de composition convertissent leurs outputs vers les DTO persistants.
## Workers
`ksp-worker-api` est une lifecycle API pour services continus/live.
`ksp-worker-api` est la lifecycle API des services continus.
`ksp-worker-control-lib` est une implémentation réutilisable de gouvernance pouvant être consommée d'abord par les applications manager spécialisées, puis éventuellement par un futur orchestrateur ou une future application globale.
RAW et CORE peuvent recevoir leurs workers à la fin de leur couche respective.
Workers retenus :
```text
ksp-worker-raw-retriever
ksp-worker-core-processor
ksp-worker-generic-materializer
ksp-worker-domain-projector
```
Le dernier nom reste provisoire.
Chaque worker doit pouvoir fonctionner comme service/processus indépendant afin d'être arrêté, redémarré ou mis à jour sans imposer l'arrêt des autres. La direction de packaging préférée est un package `ksp-worker-*` avec cible bibliothèque réutilisable et binaire autonome mince.
Les workers de processing utilisent le Store comme source de vérité du backlog, peuvent être réveillés par notification, et doivent pouvoir reprendre après crash. Le raw retriever possède en plus une capacité de hot reconfiguration de sa sélection d'acquisition.
Les workers DECODE/SPECIALIZED sont introduits avec les groupes Program réels, afin de ne pas créer une orchestration générique vide avant les processors.
## Jobs
`ksp-job-api` est une lifecycle API distincte pour travaux déclenchés et terminables.
`ksp-job-api` est la lifecycle API des travaux déclenchés/terminables.
Jobs de données retenus :
Le premier job retenu est le backfill RAW.
Les jobs de replay suivent ensuite les frontières durables ouvertes : RAW -> CORE, CORE -> DECODE, DECODE -> SPECIALIZED.
Aucune `ksp-job-control-lib` n'est prévue sans duplication concrète.
## Scenarios
Les scenarios restent dans `ksp-scenario-<domain>-lib` et sont appelables sans desktop.
Ils composent les Program implementations, policy, Wallet, transport et execution nécessaires à leur vertical slice.
L'application demo correspondante reste une UI mince.
## Applications
KSP privilégie des applications spécialisées servant à valider/exploiter une capacité réelle :
```text
ksp-job-backfill
ksp-job-replay-core
ksp-job-replay-generic-materialization
ksp-job-replay-domain-projection
ksp-app-config-desk
ksp-app-wallet-desk
price desk
backfill/raw tooling
CORE tooling
ksp-app-market-desk
```
Les trois jobs de replay correspondent exactement aux frontières D1 -> D2, D2 -> D3 et D3 -> D4.
Une application globale reste future.
Aucune `ksp-job-control-lib` n'est prévue actuellement. D'autres jobs pourront apparaître pour metadata, quotes ou autres besoins ponctuels.
## Progression verticale Program
## Scénarios
Les scénarios restent dans des crates spécialisées `ksp-scenario-<domain>-lib`.
`ksp-scenario-api` n'est pas retenu actuellement : `docs/rules/SCENARIO_CONVENTION.md` porte la norme commune tant qu'un vrai contrat Rust réutilisable n'a pas émergé.
Les demos desktop de scénario suivent provisoirement la forme :
À partir de DECODE :
```text
ksp-app-scenario-<domain>-<environment>-desk-demo
wire -> decode -> materialize -> specialized -> prepare -> policy -> execute -> scenario
```
et réutilisent la crate de scénario correspondante.
Ordre prioritaire actuel : Solana Core Programs, SPL token/trading, token metadata, Anchor, Meteora, Raydium, Pump, Orca, routing, trading-adjacent, puis décodage généraliste.
## Applications, services et control plane
Les applications spécialisées sont développées avant toute application globale.
Les apps restent des interfaces/compositions et ne réimplémentent pas les workflows des bibliothèques/services sous-jacents.
Les workers sont des services autonomes et ne communiquent pas directement leurs données entre eux. D1D4 constituent le data plane ; `ksp-worker-api`, `ksp-worker-control-lib`, `ksp-job-api` et le futur IPC constituent le control plane.
Aucun `ksp-ipc-api` générique ni `ksp-orchestrator-lib` n'est retenu comme crate actuelle.
Une future application globale est conservée comme idée produit, pas comme tâche du roadmap présent.
## Pipelines
Aucun `ksp-pipeline-lib` monolithique.
Quatre pipelines spécialisés sont maintenant retenus parce qu'ils évitent de dupliquer une même frontière entre worker live et job :
```text
ksp-pipeline-raw-ingestion-lib
ksp-pipeline-core-processing-lib
ksp-pipeline-generic-materialization-lib
ksp-pipeline-domain-projection-lib
```
Ils dépendent des APIs de domaine nécessaires, pas des implémentations officielles `ksp-store-lib`, `ksp-program-lib` ou `ksp-materializer-lib`. Les workers/jobs réalisent cette composition.
Un satellite nécessaire reste dans son groupe protocolaire.

View File

@@ -1,344 +1,153 @@
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
<!-- version: 10 -->
<!-- version: 6 -->
# Inventaire initial des composants KSP
## Objet
Ce document constitue le premier inventaire architectural de `0.0.3-pre.002`.
Il répond principalement à la question : **quel composant possède quelle responsabilité ?**
Le premier inventaire a été produit en `0.0.3-pre.002`. `pre.003` l'a corrigé à partir du graphe, puis `pre.004` a détaillé Wire/Program dans [`006-WIRE_AND_PROGRAM.md`](006-WIRE_AND_PROGRAM.md), `pre.005` Execution/Policy, `pre.006` les niveaux durables/Materialization/Store, `pre.007` l'exploitation workers/jobs/pipelines, `pre.008` Apps/Services/Scenarios/Control, puis `pre.009` le séquencement des premières releases fonctionnelles. La séquence détaillée est dans `docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`. Les détails de types Rust restent révisables avec les premières implémentations.
Ce document maintient l'inventaire synthétique des composants retenus ou pressentis. Les numéros de release précis restent soumis au sizing de chaque session.
## Statuts
- **Retenu** — composant ou responsabilité considérée nécessaire dans la trajectoire actuelle ;
- **Candidat fort** — composant très probable mais dont la frontière exacte doit encore être validée ;
- **Futur retenu** — responsabilité acquise mais implémentation différée ;
- **À la demande**ne doit être créé que lorsqu'un premier besoin concret le justifie ;
- **Non retenu actuellement** — idée volontairement non créée ; elle peut être réévaluée si l'usage réel change.
- `Stable` — implémenté et publié ;
- `Retenu` — composant/contrat décidé ;
- `Pressenti` — direction décidée mais périmètre exact à confirmer ;
- `À la demande`créé seulement au premier besoin réel ;
- `Non retenu` — explicitement écarté pour l'instant.
## Inventaire synthétique
| Domaine | Composant | Nature | Niveau provisoire | Statut | Première série envisagée | Responsabilité principale |
|----------------------------------|---------------------------------------------|-------------------------|-------------------|-----------------------------------|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| Core | `ksp-core-lib` | lib | N1 | Retenu | `0.1.1` | `Error` commun, Program IDs, primitives/contrats réellement transversaux |
| Configuration | `ksp-config-lib` | lib | N1 | Retenu | `0.1.3` par défaut | documents de configuration, profils, résolution, modifications autorisées |
| Logging | `ksp-logging-lib` | lib | N1 | Retenu | `0.1.2` | façade unique `tracing`/appender/subscriber, initialisation et logging structuré KSP ; peut dépendre de core pour Error/Result |
| Config desktop | `ksp-app-config-desk` | app | N4 | Retenu | `0.1.4` par défaut | app spécialisée Tauri validant chargement, profils, édition, sauvegarde, validation et diagnostics Config |
| Wire Solana | `ksp-interface-lib` | lib | N1 | Retenu | `0.2.x` | façade wire on-chain, réexports contrôlés et réimplémentations compatibles |
| Program API | `ksp-program-api` | API | N2 contrat | Retenu | `0.2.x` | contrats publics ouverts de décodage, préparation d'exécution, descriptors et registry |
| Program impl. | `ksp-program-lib` | lib | N2 | Retenu | `0.2.x+` | decoders et `ProgramExecutionPreparer` officiels organisés par domaine/programme/capacité |
| Program extension | `ksp-program-<name>-lib` | lib externe/optionnelle | N2 | À la demande | dès besoin | implémentation externe de `ksp-program-api` pour un Program ID non encore intégré officiellement |
| Execution policy | `ksp-execution-policy-api` | API | N3 contrat | Retenu | premier besoin d'exécution réelle | policy obligatoire, multi-checkpoints, décision/requirements sans wallet/réseau/UI |
| Execution orchestration | `ksp-execution-lib` | lib | N3 | Retenu | premier besoin d'exécution réelle | consomme `PreparedProgramExecution`; orchestre policy/simulation/signature/submission/confirmation/retry sans dépendre de `ksp-program-lib` ou du store |
| Transport on-chain | `ksp-onchain-transport-lib` | lib | N2 | Retenu | `0.2.x` | RPC/WS/providers et modèles de transport homogènes, sans dépendance store |
| Transport off-chain | `ksp-offchain-transport-lib` | lib | N2 | Retenu, implémentation différable | premier besoin réel | accès metadata, prix, quotes, routage et autres ressources hors blockchain |
| Wallet | `ksp-wallet-lib` | lib | N2 | Retenu | `0.2.x` | format wallet KSP, lecture/protection/import/export, pubkey, secret/signature |
| Materializer API | `ksp-materializer-api` | API | N3 contrat | Retenu | `0.3.x` | contrats publics/extensibles de matérialisation |
| Materializer impl. | `ksp-materializer-lib` | lib | N3 | Retenu | `0.3.x+` | materializers officiels KSP |
| Store API | `ksp-store-api` | API | N3 contrat | Retenu | `0.3.x` | contrats backend-agnostic, modèles persistants et notifications de données persistées |
| Store impl. | `ksp-store-lib` | lib | N3 | Retenu | `0.3.x` | PostgreSQL de référence, migrations, repositories, queries, backlog/replay et notification backend |
| Worker lifecycle | `ksp-worker-api` | API | N3 contrat | Retenu | `0.3.x` | lifecycle commun des services continus |
| Worker control | `ksp-worker-control-lib` | lib | N3 | Retenu | `0.3.x+` | gouvernance réutilisable de services workers autonomes pour apps spécialisées puis futurs managers/orchestrateurs |
| Live raw acquisition | `ksp-worker-raw-retriever` | worker | N4 | Retenu | `0.3.x` | acquisition live/quasi-live -> raw persisté -> notification data |
| Raw -> Core | `ksp-worker-core-processor` | worker | N4 | Futur retenu | `0.6.x` | transformer le raw persisté en Core canonique |
| Core -> generic mat. | `ksp-worker-generic-materializer` | worker | N4 | Futur retenu | `0.6.x` | produire la matérialisation/journal générique depuis le Core |
| Domain projection | `ksp-worker-domain-projector` | worker | N4 | Futur retenu, nom provisoire | `0.6.x` | matérialiser/classer/stocker les projections spécialisées par domaine |
| Job lifecycle | `ksp-job-api` | API | N3 contrat | Retenu | `0.3.x` | lifecycle/progression commun des travaux déclenchés et terminables |
| Historical backfill | `ksp-job-backfill` | job | N4 | Retenu | `0.3.x` | acquisition historique avec pagination, progression, checkpoint/reprise |
| Core replay | `ksp-job-replay-core` | job | N4 | Retenu | `0.3.x/0.6.x` | replay borné D1 -> D2 via le pipeline Core |
| Generic materialization replay | `ksp-job-replay-generic-materialization` | job | N4 | Retenu | `0.3.x/0.6.x` | replay borné D2 -> D3 via le pipeline générique |
| Domain projection replay | `ksp-job-replay-domain-projection` | job | N4 | Retenu | `0.3.x/0.6.x` | replay borné D3 -> D4 via le pipeline de projection |
| Other jobs | `ksp-job-<role>` | job | N4 | À la demande | `0.4.x+` | metadata, quotes et autres travaux ponctuels/historiques |
| Scenarios | `ksp-scenario-<domain>-lib` | lib | N3 | Retenu | `0.4.x+` | scénarios de validation spécialisés par domaine |
| Scenario common API | `ksp-scenario-api` | API | — | Non retenu actuellement | — | préférer une norme de scénario souple plutôt qu'un trait commun contraignant |
| Scenario demo apps | `ksp-app-scenario-<domain>-<env>-desk-demo` | app | N4 | Retenu | `0.4.x+` | interface desktop appelant la crate scénario correspondante |
| Raw ingestion pipeline | `ksp-pipeline-raw-ingestion-lib` | lib | N3 | Retenu | `0.3.x` | conversion/persistence transport model -> D1 partagée par worker live et backfill |
| Core processing pipeline | `ksp-pipeline-core-processing-lib` | lib | N3 | Retenu | `0.3.x/0.6.x` | logique D1 -> D2 partagée par worker et replay, basée sur `ksp-program-api` |
| Generic materialization pipeline | `ksp-pipeline-generic-materialization-lib` | lib | N3 | Retenu | `0.3.x/0.6.x` | logique D2 -> D3 partagée par worker et replay, basée sur `ksp-materializer-api` |
| Domain projection pipeline | `ksp-pipeline-domain-projection-lib` | lib | N3 | Retenu | `0.3.x/0.6.x` | logique D3 -> D4 partagée par worker et replay, basée sur `ksp-materializer-api` |
| Trading Intelligence | noms à définir | API/libs/jobs | N3+ | Futur retenu | `0.7.x` | statistiques, features, signaux, anomalies, backtests, ML |
| Trading operation/app | noms à définir | libs/apps | N3/N4 | Futur retenu | après Trading Intelligence | politique/automatisation de trading et application monoposte |
| Solana explorer | noms à définir | libs/apps | N3/N4 | Futur retenu | futur | exploration générale Solana |
| DEX explorer | noms à définir | libs/apps | N3/N4 | Futur retenu | futur | exploration/analyse DEX |
| Domaine | Composant | Type | Statut | Première cible actuelle | Mission |
|-------------------------|------------------------------------------|--------------------|--------------|---------------------------------|----------------------------------------------------------|
| Core | `ksp-core-lib` | lib | Stable | `0.1.1` | Error/Result, Program IDs et primitives fondamentales |
| Logging | `ksp-logging-lib` | lib | Stable | `0.1.2` | façade unique tracing KSP |
| Config | `ksp-config-lib` | lib | Stable | `0.1.3` | documents, profils, env et persistence Config |
| Config Desk | `ksp-app-config-desk` | app | Stable | `0.1.4` | validation/management Config |
| On-chain HTTP | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.1` | JSON-RPC HTTP complet, settings, pools, rôles |
| Wallet | `ksp-wallet-lib` | lib | Retenu | `0.2.2` | `.kspwallet`, secrets, signature, import/export |
| Wallet Desk | `ksp-app-wallet-desk` | app | Retenu | `0.2.3` | Wallet + Config composite + HTTP/balance |
| Standard WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.4` | WebSocket Solana complet, sessions/subscriptions |
| Helius WS | `ksp-onchain-transport-lib` | lib | Retenu | `0.2.5` | LaserStream WebSocket comme extension du moteur standard |
| Yellowstone | `ksp-onchain-transport-lib` | lib | Pressenti | `0.2.6` | client gRPC standard/provider-neutral |
| Off-chain price | `ksp-offchain-transport-lib` | lib | Retenu | `0.2.7` | première abstraction/provider de prix SOL/USD, SOL/EUR |
| Price Desk | nom à fixer | app | Retenu | `0.2.8` | visualisation/validation des prix |
| Wire | `ksp-interface-lib` | lib | Retenu | `0.2.9` | façade wire officielle + API publique wire |
| Program API | `ksp-program-api` | API | Retenu | `0.2.10` | contrats extensibles Program |
| Program impl. | `ksp-program-lib` | lib | Retenu | vertical slices ultérieurs | implementations Program officielles |
| Program extension | `ksp-program-<name>-lib` | lib externe | À la demande | dès besoin | implementation externe de `ksp-program-api` |
| Store API | `ksp-store-api` | API | Retenu | `0.3.1` | contrats persistence backend-agnostic, RAW d'abord |
| Store PostgreSQL | `ksp-store-lib` | lib | Retenu | `0.3.1` | backend PostgreSQL officiel, RAW d'abord |
| Job lifecycle | `ksp-job-api` | API | Retenu | `0.3.3` | lifecycle des jobs terminables |
| Backfill | `ksp-job-backfill` | job/lib à préciser | Retenu | `0.3.3` | acquisition historique vers RAW |
| Backfill Desk | nom à fixer | app | Retenu | `0.3.4` | contrôle/inspection du backfill RAW |
| Worker lifecycle | `ksp-worker-api` | API | Retenu | fin couche RAW | lifecycle des services continus |
| RAW worker | `ksp-worker-raw-retriever` ou nom révisé | worker | Retenu | fin couche RAW | acquisition live vers RAW |
| CORE processor | nom à fixer | processor/lib | Retenu | couche CORE | normalisation Solana générique RAW -> CORE |
| CORE worker | nom à fixer | worker | Retenu | fin couche CORE | backlog RAW -> CORE continu |
| Materializer API | `ksp-materializer-api` | API | Retenu | premier groupe DECODE | contrats extensibles matérialisation |
| Materializer impl. | `ksp-materializer-lib` | lib | Retenu | premier groupe DECODE | implementations officielles communes |
| Execution policy | `ksp-execution-policy-api` | API | Retenu | premier vrai besoin execution | décision/safety multi-contexte |
| Execution orchestration | `ksp-execution-lib` | lib | Retenu | premier vrai cycle execution | Program + policy + Wallet + transport |
| Scenarios | `ksp-scenario-<domain>-lib` | lib | Retenu | vertical slices | validation métier/devnet par groupe |
| Scenario API | `ksp-scenario-api` | API | Non retenu | — | norme souple avant trait commun |
| Market Desk | `ksp-app-market-desk` | app | Pressenti | après Meteora/Raydium/Pump/Orca | tokens, pools, trades, liquidity, price, OHLC |
| Trading Intelligence | noms à définir | libs/jobs | Futur | après données stables | features/signaux/anomalies/ML |
## APIs séparées retenues
Les couples suivants ont une justification d'extensibilité suffisante :
## Contrats séparés retenus
```text
ksp-program-api -> ksp-program-lib
ksp-materializer-api -> ksp-materializer-lib
ksp-store-api -> ksp-store-lib
ksp-program-api
ksp-materializer-api
ksp-store-api
ksp-worker-api
ksp-job-api
ksp-execution-policy-api
```
Les APIs lifecycle sont également séparées :
Pas de crates séparées actuellement pour :
```text
ksp-worker-api -> workers continus
ksp-job-api -> jobs terminables
ksp-interface-api
ksp-wallet-api
ksp-onchain-transport-api
ksp-offchain-transport-api
ksp-scenario-api
ksp-job-control-lib
ksp-data-api
```
Aucune API commune worker+job n'est prévue.
## Transport
## Execution policy et orchestration
`ksp-onchain-transport-lib` doit couvrir l'intégralité des opérations documentées de la surface ciblée par chaque release. Les statuts deprecated/obsolete encore fonctionnels et unstable/experimental restent exposés avec warning runtime KSP.
La frontière détaillée est définie dans [`007-EXECUTION_AND_POLICY.md`](007-EXECUTION_AND_POLICY.md).
La Config standard Transport appartient à `ksp-config-lib`, qui adapte vers les settings publics du transport ; le transport ne dépend jamais de Config.
Principes retenus :
Les WebSockets supportent plusieurs sessions pour un même endpoint URL, mais un pool/scheduler automatique n'est créé qu'après besoin démontré.
```text
PreparedProgramExecution
|
v
ksp-execution-lib
| | |
policy wallet onchain transport
```
- `ksp-execution-lib` dépend de `ksp-program-api`, pas de `ksp-program-lib` ;
- une policy est explicitement fournie pour toute exécution réelle ;
- la policy peut être évaluée à plusieurs checkpoints ;
- une policy décide/contraint mais n'exécute pas de réseau/signature/UI ;
- Program constraints, options caller et policy constraints restent trois sources distinctes ;
- wallet/signers et transport/provider sont fournis par la composition supérieure ;
- simulation/submission/status sont des primitives transport orchestrées par execution ;
- signature est une capacité wallet orchestrée par execution ;
- retry réseau identique et retry de lifecycle d'exécution restent distincts ;
- une approbation externe peut suspendre/reprendre l'exécution sans faire dépendre la policy de l'UI ;
- aucun accès Store depuis `ksp-execution-lib`.
`ksp-logging-lib` est consommé transversalement par les crates runtime qui doivent logger, sans imposer une dépendance aux crates `*-api` déclaratives ni à `ksp-core-lib`.
## Transport on-chain
Aucune crate `ksp-onchain-transport-api` n'est prévue.
`ksp-onchain-transport-lib` peut contenir plusieurs familles hétérogènes :
- HTTP RPC ;
- WebSocket RPC ;
- Helius avancé ;
- Yellowstone ;
- autres providers/transports futurs.
Les adapters providers doivent toutefois faire sortir de la crate des **modèles de transport homogènes par catégorie de donnée**, afin que les consommateurs n'aient pas à comprendre chaque réponse propriétaire.
Ces modèles :
- restent indépendants de `ksp-store-api` ;
- conservent les informations raw/provenance nécessaires ;
- ne réalisent aucun décodage métier/protocolaire ;
- doivent être facilement et explicitement convertibles par `ksp-worker-raw-retriever` vers les modèles raw persistants de `ksp-store-api`.
Les principes de cette frontière sont désormais fixés : transport et Store restent indépendants, et la conversion explicite transport -> D1 appartient au pipeline/composant de composition. Les DTO exacts seront définis avec les premières implémentations Transport/Store.
## Transport off-chain
Aucune crate `ksp-offchain-transport-api` ni trait global `OffchainTransport` n'est prévu.
`ksp-offchain-transport-lib` regroupe volontairement des accès hétérogènes afin d'éviter une explosion de petites crates. Metadata externes, quotes, prix hors blockchain ou routage peuvent conserver des APIs/modules spécialisés à l'intérieur de cette crate sans prétendre partager une abstraction métier commune.
Les providers Yellowstone spécifiques restent des extensions futures ; le contrat standard est provider-neutral.
## Wallet
Aucune crate `ksp-wallet-api` n'est prévue.
Le format natif est `.kspwallet`.
`ksp-wallet-lib` est propriétaire du format wallet KSP, des opérations de protection/import/export et de l'accès contrôlé aux capacités pubkey/secret/signature nécessaires aux couches supérieures.
Les anciens temporary wallets JSON ne sont pas migrés.
Les applications futures utilisant ce wallet restent des consommateurs de `ksp-wallet-lib`, pas des implémentations alternatives du contrat wallet.
`WalletPolicy` est exclu du Wallet et relève de l'execution policy.
## Workers
Import/export reste extensible ; les formats supplémentaires sont suivis dans `docs/IDEAS.md`.
### `ksp-worker-api`
`ksp-worker-api` est une **lifecycle API de services continus**.
Elle pourra porter des contrats communs comme identité, état, health, start/stop/shutdown et événements de lifecycle. Une capacité optionnelle comme la reconfiguration à chaud ne doit devenir universelle que si plusieurs workers la partagent réellement.
Elle ne contient aucun concept de progression/checkpoint terminal propre aux jobs.
### `ksp-worker-control-lib`
`ksp-worker-control-lib` est une implémentation réutilisable de gouvernance au-dessus de `ksp-worker-api`.
Elle doit pouvoir être consommée par :
- une application desktop manager spécialisée ;
- une future application globale ;
- un éventuel orchestrateur commun si un besoin opérationnel concret le justifie ;
- des tools/tests lorsque pertinent.
Les applications restent des interfaces et ne réimplémentent pas elles-mêmes registre, dispatch start/stop, agrégation d'état ou reconfiguration générique.
### Packaging des workers
Chaque package `ksp-worker-<role>` doit pouvoir fournir :
## Data plane
```text
library target
-> logique/runtime service réutilisable
binary target
-> bootstrap autonome mince
RAW -> CORE -> DECODE -> SPECIALIZED
```
Cette direction permet de tester/réutiliser la logique sans perdre la propriété « service indépendant ».
- RAW : acquisition replayable ;
- CORE : normalisation blockchain générique sans decoder Program ;
- DECODE : interpretation Program + matérialisation générique/journal ;
- SPECIALIZED : projections queryables de domaine.
Le binaire autonome n'est pas une seconde implémentation du worker.
## Progression des processors
### Workers de processing
RAW et CORE sont complétés couche par couche avec jobs/workers/apps utiles.
Le modèle initial d'un unique W2 est remplacé par une chaîne de responsabilités plus étroites :
À partir de DECODE, progression verticale par groupe :
```text
raw persisted
|
v
ksp-worker-core-processor
|
v
canonical Core
|
v
ksp-worker-generic-materializer
|
v
generic materialization/journal
|
v
ksp-worker-domain-projector
|
v
domain projections
wire -> decode -> materialize -> specialized -> prepare -> policy -> execute -> scenario
```
Le nom `ksp-worker-domain-projector` est explicitement provisoire jusqu'à ce que les contrats de matérialisation spécialisée soient définis.
## Jobs
`ksp-job-api` est une **lifecycle API de travaux déclenchés et terminables**.
Elle peut porter identité, état, progression, cancel, résultat et, lorsque pertinent, pause/resume/checkpoint.
Aucune `ksp-job-control-lib` n'est prévue actuellement. Le fait que plusieurs jobs implémentent `ksp-job-api` suffit tant qu'aucune duplication concrète de gouvernance ne justifie une bibliothèque commune.
## Notifications de données
Les notifications de données restent indépendantes du lifecycle des workers et des jobs.
Le même type de donnée persistée doit produire le même contrat de notification quelle que soit son origine :
Groupes prioritaires :
```text
worker live -----\
job backfill -----+--> même notification de donnée
import -----------/
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
```
`ksp-store-api` reste le propriétaire candidat de ces références/notifications lorsqu'elles signifient qu'une donnée persistée est disponible.
Meteora vaults, Pump fees et autres satellites nécessaires restent dans leur groupe.
Le transport de notification reste distinct du contrat de donnée.
## Applications spécialisées
## Scénarios et demos
Les applications servent de validations/exploitations réelles sans absorber la logique des bibliothèques.
Aucune crate monolithique de scénarios n'est prévue.
Market Desk est progressive : V1 après les DEX prioritaires, puis enrichissement routing après Jupiter/OKX.
Les scénarios vivent dans des crates spécialisées :
## Questions restantes
```text
ksp-scenario-memo-lib
ksp-scenario-token-lib
ksp-scenario-ata-lib
ksp-scenario-token-2022-lib
ksp-scenario-metadata-lib
ksp-scenario-spm-lib
...
```
`ksp-scenario-api` n'est pas retenu actuellement. La norme commune est documentée dans `docs/rules/SCENARIO_CONVENTION.md` et peut évoluer avec les premières implémentations.
Les applications de démonstration correspondantes suivent la forme :
```text
ksp-app-scenario-<domain>-<environment>-desk-demo
```
Exemples :
```text
ksp-app-scenario-memo-devnet-desk-demo
ksp-app-scenario-token-2022-devnet-desk-demo
ksp-app-scenario-metadata-devnet-desk-demo
```
Chaque application appelle la crate `ksp-scenario-<domain>-lib` correspondante et ne duplique pas son scénario. La crate scenario doit également pouvoir être appelée hors desktop.
## Applications spécialisées et control plane
Les applications spécialisées sont prioritaires sur une future application globale.
Une app worker spécialisée passe par `ksp-worker-control-lib` / `ksp-worker-api` et ne manipule pas directement l'état interne du worker dans le Store.
Le data plane est D1D4. Le control plane porte start/stop/status/health/reconfigure et reste séparé des payloads de processing.
Les workers doivent être exploitables comme services autonomes. Le mécanisme IPC exact reste à définir à la première implémentation manager/service ; aucun `ksp-ipc-api` générique n'est créé maintenant.
Une future application globale est conservée dans `docs/IDEAS.md` seulement.
## Pipelines
`ksp-pipeline-lib` reste rejeté.
Le premier besoin concret de réutilisation est maintenant identifié : worker live et job de replay/backfill doivent partager la même logique d'une frontière durable.
Pipelines retenus :
```text
ksp-pipeline-raw-ingestion-lib
ksp-pipeline-core-processing-lib
ksp-pipeline-generic-materialization-lib
ksp-pipeline-domain-projection-lib
```
Les pipelines sont backend/implementation agnostic autant que possible : ils dépendent des APIs (`ksp-store-api`, `ksp-program-api`, `ksp-materializer-api`) et reçoivent les implémentations concrètes par composition depuis worker/job.
## Modèle opérationnel workers/jobs
Le backlog de processing est défini par les inputs applicables moins les processing outcomes terminaux du processor/version/capability cible.
L'absence d'output n'est pas une preuve d'absence de traitement.
KSP retient :
```text
notification wake-up + periodic polling
Store backlog = source de vérité
claim/lease = ownership temporaire
at-least-once + idempotence = sémantique de traitement
```
Le raw retriever expose une hot reconfiguration avec distinction desired/effective configuration.
Les jobs de replay restent distincts des workers continus et réutilisent les mêmes pipelines.
## Corrections issues de `pre.003`
Le graphe confirme les principes suivants :
- Program et Materializer restent indépendants du store et des I/O réseau ;
- `ksp-execution-policy-api` et `ksp-execution-lib` sont retenus ;
- `ksp-execution-lib` consomme `ksp-program-api`, pas l'implémentation officielle `ksp-program-lib` ;
- `ksp-materializer-api` peut dépendre de `ksp-program-api`, mais ni Materializer API/lib ni Store API/lib ne se dépendent mutuellement ;
- les workers/jobs spécialisés réalisent les conversions explicites entre modèles de transport, processing et persistence ;
- aucun `ksp-data-api` global n'est introduit ;
- `ksp-worker-control-lib` est retenu comme gouvernance workers réutilisable ; aucune `ksp-job-control-lib` n'est retenue.
## Questions restantes après la fondation
- types Rust exacts des contrats ouverts de `ksp-program-api` ;
- DTO exacts des modèles transport et D1/D2/D3/D4 avec les premières implémentations concernées ;
- schémas SQL, indexes, claims/leases et pagination du Store PostgreSQL ;
- première implémentation manager/service : mécanisme IPC et proxy distant Worker ;
- contexte requis par les projectors stateful ;
- futur : orchestrateur commun seulement si un besoin opérationnel concret le justifie ; l'application globale reste un produit futur après validation des apps spécialisées.
- noms exacts de Price Desk et Backfill Desk ;
- surface exacte Yellowstone après audit normatif de `0.2.6-pre.001` ;
- nécessité future d'un pool automatique WS ;
- types exacts `ksp-program-api`/`ksp-materializer-api`/`ksp-store-api` ;
- nom/packaging précis du premier RAW worker et du CORE normalizer ;
- granularité des workers DECODE/SPECIALIZED par groupe.

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/006-WIRE_AND_PROGRAM.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Wire, Program API et implémentations Program
@@ -46,6 +46,21 @@ Les Program IDs fondamentaux restent possédés par `ksp-core-lib`.
- policy/safety ;
- lifecycle d'exécution réseau.
## API publique de `ksp-interface-lib`
`ksp-interface-lib` reste une seule crate pour l'instant : aucune `ksp-interface-api` séparée n'est créée.
La façade doit néanmoins exposer une API publique wire stable et réutilisable par :
```text
ksp-program-lib
external ksp-program-<name>-lib
```
Une implementation externe peut donc expérimenter contre les mêmes contrats wire publics avant intégration officielle dans KSP. Lorsqu'un wire externe devient officiel, son intégration dans `ksp-interface-lib` doit rester compatible avec l'API publique retenue, sauf évolution de contrat explicitement versionnée/documentée.
Si une future contrainte de dépendances démontre qu'un split `ksp-interface-api` apporte une valeur réelle, il pourra être étudié selon `KSP-API-007`; la symétrie avec Program ne suffit pas.
## Propriété des codecs wire
Pour le code KSP officiel, les dépendances directement utilisées pour encoder/décoder les formats wire, notamment `borsh`, `wincode` ou codecs équivalents, appartiennent normalement à `ksp-interface-lib`.
@@ -403,6 +418,18 @@ Les validations peuvent combiner selon le cas :
Une crate externe provoquant volontairement une génération incompatible de dépendances fondamentales ne doit pas être ajoutée au workspace simplement pour faciliter un test si des fixtures/vecteurs indépendants permettent la même vérification.
## Progression verticale par groupe
Après les couches RAW/CORE, les Program implementations ne sont pas développées horizontalement comme une longue liste de decoders isolés. Chaque groupe prioritaire avance successivement :
```text
wire -> decode -> materialize -> specialized -> execution preparation -> policy -> execution -> scenario
```
Un composant satellite nécessaire à un protocole reste dans son groupe : Meteora vaults avec Meteora, Pump fee avec Pump, etc.
Ordre prioritaire actuel : Solana Core Programs, SPL token/trading, token metadata, Anchor, Meteora, Raydium, Pump, Orca, routing, trading-adjacent puis décodage généraliste.
## Questions laissées ouvertes
La première implémentation Program devra encore fixer précisément :
@@ -415,4 +442,4 @@ La première implémentation Program devra encore fixer précisément :
- stratégie précise de warning/log pour opérations abandonnées ;
- convention finale `dec` / `exec_prep`.
La tranche suivante doit traiter `ksp-execution-policy-api` et `ksp-execution-lib` sans rouvrir les responsabilités Program définies ici.
Les releases exactes d'introduction de `ksp-program-lib`, `ksp-execution-policy-api` et `ksp-execution-lib` suivent désormais les vertical slices définis par le roadmap ; les responsabilités Program décrites ici restent valables.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/007-EXECUTION_AND_POLICY.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Execution et Policy
@@ -311,6 +311,18 @@ ksp-execution-lib -X-> ksp-store-api
ksp-execution-lib -X-> ksp-store-lib
```
## Ownership des implementations de policy
`ksp-execution-policy-api` est le contrat commun. Une crate générale `ksp-execution-policy-lib` n'est pas créée par symétrie.
Une petite policy strictement propre à un scenario, un orchestrateur ou une application spécialisée peut être implémentée directement dans cette crate. Une ou plusieurs bibliothèques de policies communes ne sont introduites que lorsque plusieurs consommateurs démontrent une réutilisation réelle.
Les anciennes règles historiques de type `WalletPolicy` qui concernent limites de dépense, réseau, programme, simulation ou autorisation sont déplacées conceptuellement vers cette frontière policy et non vers `ksp-wallet-lib`.
## Execution dans les vertical slices
L'exécution n'est pas reportée après « tous les decoders ». Pour chaque groupe Program prioritaire, les opérations pertinentes avancent après décodage/matérialisation jusqu'à préparation, policy, execution et scénarios Devnet lorsque le réseau/protocole permet une validation réelle.
## Questions laissées à l'implémentation
- types Rust exacts des checkpoints et décisions de policy ;

View File

@@ -1,614 +1,344 @@
<!-- file: docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md -->
<!-- version: 2 -->
<!-- version: 3 -->
# Data, Materialization et Store
## Objet
Ce document constitue la sortie principale de `0.0.3-pre.006`.
Ce document définit la chaîne durable KSP, la responsabilité du Store et les frontières de replay.
Il définit les frontières durables de données KSP et précise :
- les niveaux D1 à D4 ;
- la séparation `ksp-materializer-api` / `ksp-materializer-lib` / Store ;
- le rôle backend-agnostic de `ksp-store-api` ;
- PostgreSQL comme implémentation de référence de `ksp-store-lib` ;
- provenance et temporalités ;
- idempotence et versionnement des processors ;
- replay indépendant par frontière ;
- sémantique des notifications de données persistées ;
- stabilité différente entre niveaux structurants et projections spécialisées.
Le lifecycle complet, batching, concurrence, backlog et reprise des workers/jobs sont détaillés dans `009-ACQUISITION_WORKERS_AND_JOBS.md`.
## Nomenclature des niveaux durables
Les niveaux de données ne réutilisent pas N1 à N4, déjà réservés aux couches architecturales KSP.
La nomenclature durable retenue est :
La nomenclature canonique est désormais :
```text
D1 — Raw
D2 — Core canonique
D3 — Journal de matérialisation générique
D4 — Projections spécialisées/queryables par domaine
RAW -> CORE -> DECODE -> SPECIALIZED
```
Flux général :
Les aliases D1D4 restent utilisés pour les niveaux persistés :
```text
source on-chain
|
v
ksp-worker-raw-retriever
|
v
D1 Raw
|
v
ksp-worker-core-processor
|
v
D2 Core canonique
|
v
ksp-worker-generic-materializer
|
v
D3 journal générique
|
v
ksp-worker-domain-projector
|
v
D4 projections de domaine
D1 = RAW
D2 = CORE
D3 = DECODE / matérialisation générique décodée
D4 = SPECIALIZED
```
Le nom `ksp-worker-domain-projector` reste révisable ; la frontière D3 -> D4 est, elle, retenue.
Cette clarification remplace l'ancienne interprétation où D1 -> D2 pouvait déjà dépendre de `ksp-program-api`. **RAW et CORE sont indépendants de tout decoder Program.**
# D1 — Raw
## Principes structurants
- le Store persiste des contrats de données ; il ne possède ni transport, ni decoder, ni materializer ;
- chaque frontière durable peut être rejouée indépendamment ;
- les données de provenance/versioning permettent de savoir quel processor a produit quel output ;
- les couches dérivées ne rendent jamais obligatoire une nouvelle acquisition réseau lorsque l'input durable nécessaire existe déjà ;
- D4 privilégie les faits métier génériques lorsqu'une normalisation inter-protocoles est pertinente.
# D1 — RAW
## Mission
D1 conserve l'acquisition suffisamment fidèlement pour permettre un nouveau processing sans redemander la donnée à la blockchain lorsque l'information nécessaire a déjà été capturée.
RAW conserve l'acquisition suffisamment fidèlement pour reconstruire CORE sans redemander la donnée au provider lorsqu'elle a déjà été capturée.
`raw` ne signifie pas nécessairement « enveloppe propriétaire du provider conservée sans aucune normalisation ». Le transport peut normaliser ses différentes sources vers des modèles KSP homogènes.
Le transport peut normaliser plusieurs providers vers un modèle KSP homogène, mais D1 doit rester lossless pour les besoins de replay couverts.
La persistance D1 doit toutefois rester **lossless pour les besoins de replay couverts** : toute information nécessaire à la reconstruction du Core doit être conservée, y compris le contenu brut et la provenance utile.
D1 ne décode aucun programme Solana/SPL/Metaplex/DEX.
## Frontière transport -> D1
## Frontière Transport -> RAW
```text
Solana RPC ------\
Helius -----------+--> modèle homogène ksp-onchain-transport-lib
Yellowstone ------/
|
v
conversion explicite
|
v
DTO D1 de ksp-store-api
HTTP / WS / gRPC / provider
|
v
ksp-onchain-transport-lib
|
v
conversion explicite
|
v
ksp-store-api RAW DTO
|
v
ksp-store-lib
```
`ksp-onchain-transport-lib` ne dépend ni de `ksp-store-api` ni de `ksp-store-lib`.
La conversion appartient au composant de composition, principalement `ksp-worker-raw-retriever` ou `ksp-job-backfill`.
## Provenance RAW
## Provenance D1
Selon la catégorie, D1 doit pouvoir conserver notamment :
Selon la catégorie de donnée, D1 doit pouvoir conserver notamment :
- réseau ;
- identité blockchain : slot, signature, pubkey ou autre identifiant applicable ;
- contenu raw/replayable ;
- cluster/network ;
- slot/signature/pubkey/identité blockchain applicable ;
- payload replayable ;
- provider ;
- transport/source ;
- rôle d'acquisition : live, backfill, import ou autre ;
- instant d'observation/acquisition ;
- endpoint/source/transport ;
- rôle d'acquisition : live, backfill, import ;
- instant d'observation ;
- instant de persistence ;
- hash/identité d'idempotence ;
- informations de pagination/capture nécessaires à la reprise lorsque pertinentes.
- identité/hash d'idempotence ;
- cursor/page/range/checkpoint lorsque pertinent.
`block_time` reste optionnel et n'est jamais inventé lorsqu'il n'est pas fourni ou reconstructible de manière fiable.
# D2 — Core canonique
# D2 — CORE
## Mission
D2 contient les faits canoniques Solana produits à partir de D1.
CORE est une **normalisation canonique générique de la blockchain Solana**.
Le Core doit être suffisamment durable et général pour être rejoué vers les matérialisations futures sans repasser par l'acquisition ou le décodage raw.
Cette couche doit fonctionner même si `ksp-program-api` et `ksp-program-lib` ne sont pas encore capables de décoder le moindre programme métier.
Conceptuellement, D2 peut accueillir notamment :
Exemples de faits CORE candidats :
- transactions canoniques ;
- instructions top-level ;
- instructions CPI ;
- comptes/états canoniques ;
- résultats de décodage Program ouverts ;
- événements/return data lorsqu'ils sont supportés ;
- autres faits génériques Solana qui appartiennent réellement au Core.
- slots ;
- blocks et block metadata ;
- signatures ;
- transactions ;
- messages legacy/versioned ;
- account keys et address lookups ;
- comptes et états bruts structurés génériquement ;
- instructions top-level brutes ;
- instructions CPI brutes ;
- logs ;
- transaction meta ;
- balances/fees/rewards lorsqu'ils appartiennent au contrat blockchain générique ;
- return data brute ;
- relations structurelles transaction/message/instruction/account.
## Top-level / CPI
Un fait CORE peut contenir un `program_id`, des bytes et des indexes sans savoir que l'instruction représente un `Transfer`, un `Swap` ou une mutation Metadata.
Les instructions top-level et CPI restent des faits distincts.
Leur modèle peut partager des champs, mais KSP ne doit pas les fusionner artificiellement lorsque leurs invariants ou requêtes diffèrent.
La séparation physique exacte sera décidée dans la première release Store.
## Frontière D1 -> D2
## Frontière RAW -> CORE
```text
DTO D1 store
|
v
ksp-worker-core-processor
|
+--> conversion vers entrée ksp-program-api
|
+--> ksp-program-lib / extension compatible
|
+--> sortie Core ouverte
|
v
conversion vers DTO D2 store
D1 RAW
|
v
normalisation Solana générique
|
v
D2 CORE
```
`ksp-program-api` / `ksp-program-lib` restent indépendants du Store.
Interdictions :
## Provenance D2
```text
RAW -> CORE -X-> ksp-program-api
RAW -> CORE -X-> ksp-program-lib
RAW -> CORE -X-> ksp-materializer-api
```
D2 doit pouvoir relier un résultat à :
Les codecs/wires génériques nécessaires à la structure Solana peuvent provenir de `ksp-interface-lib` lorsqu'ils appartiennent à la façade wire officielle, sans transformer cette étape en décodage Program.
## Provenance CORE
D2 doit pouvoir relier chaque résultat à :
- son input D1 ;
- l'identité/version du processor ;
- l'identité/version de l'implémentation Program/decoder lorsque pertinente ;
- la capacité de décodage utilisée ;
- un hash de l'input logique ;
- l'identité/version du normalizer CORE ;
- un hash logique d'input ;
- l'instant de processing/persistence ;
- l'état de processing lorsqu'un lifecycle durable est nécessaire.
- son état de processing durable lorsque nécessaire.
# D3 — Journal de matérialisation générique
# D3 — DECODE / matérialisation générique
## Mission
D3 est un **journal durable**, pas une étape volatile.
DECODE commence lorsque KSP interprète un `program_id`, un layout d'instruction, un compte ou un événement selon un contrat Program/protocole.
Il conserve l'équivalent conceptuel obligatoire de l'ancien journal `k_sol_mat_outputs` de `ks-store`, sans figer encore le nom exact de la table KSP.
Il doit permettre de répondre à des questions telles que :
La progression logique d'un groupe est :
```text
quel input D2 ?
CORE
|
v
decoder Program
|
v
decoded facts
|
v
materialisation générique / journal durable
|
v
D3 DECODE
```
D3 conserve l'équivalent conceptuel obligatoire du journal générique de matérialisation de bot3 (`k_sol_mat_outputs`), sans imposer son ancien schéma ou son nom physique.
Le journal doit pouvoir répondre au minimum :
```text
quel input CORE ?
quel program/decoder ?
quelle version ?
quel materializer ?
quelle version ?
quel output logique ?
quel type/domaine ?
quel hash ?
quel instant ?
quel état courant/superseded/failed/replay ?
quel état/superseded/failed/replay ?
```
D3 permet notamment de reconstruire D4 après évolution d'un projector sans refaire D1 -> D2 ou D2 -> D3.
Les types exacts de decoded facts et du journal sont décidés lorsque les premiers vertical slices Program existent.
## Frontière D2 -> D3
## Frontière CORE -> DECODE
```text
D2 Core
D2 CORE
|
v
ksp-worker-generic-materializer
|
+--> conversion vers ksp-materializer-api
|
+--> GenericMaterializer
ksp-program-api implementation
|
v
generic materialization output
decoded output
|
v
conversion vers DTO D3 store
ksp-materializer-api implementation
|
v
D3 journal / decoded materialization
```
Les noms Rust exacts ne sont pas figés.
Les implémentations officielles pourront provenir de `ksp-program-lib` et `ksp-materializer-lib`; des implémentations externes compatibles restent possibles.
## Extensibilité externe
Program et Materializer ne dépendent pas du backend Store.
Une implémentation externe de materializer doit pouvoir produire un output générique compatible avec D3 sans exiger une nouvelle table PostgreSQL spécialisée.
Cela rend possible :
```text
external materializer
|
v
ksp-materializer-api
|
v
D3 journal générique
```
avant une éventuelle intégration officielle complète en D4.
# D4 — Projections spécialisées de domaine
# D4 — SPECIALIZED
## Mission
D4 contient les représentations optimisées pour les requêtes métier, analytiques et produit.
Exemples futurs :
- assets/tokens ;
- metadata d'assets/tokens ;
- Solana Program Metadata ;
- liquidity pools ;
- order books ;
- swaps/trades ;
- prices/volumes ;
- positions ;
- autres projections de domaine.
## Faits canoniques, pas familles par protocole
D4 reste organisé par **fait canonique**, pas par Program ID/protocole.
Éviter par défaut :
```text
meteora_pools
raydium_pools
orca_pools
```
au profit d'une projection canonique telle que :
```text
liquidity_pools
```
avec provenance/identité du protocole lorsque nécessaire.
La même règle s'applique aux swaps, order books et autres faits pouvant être normalisés.
## Metadata
Les metadata d'assets/tokens constituent une famille canonique commune pouvant recevoir des données provenant notamment :
- Metaplex Token Metadata ;
- Token-2022 Metadata.
Solana Program Metadata reste une projection distincte car le domaine fonctionnel est différent.
## Nouvelle projection externe
Une nouvelle projection D4 relationnelle implique nécessairement un contrat de persistence et une implémentation backend.
KSP ne masque pas cette réalité derrière une API de matérialisation « magique ».
Une extension externe peut fonctionner jusqu'à D3 sans migration Store spécialisée. Pour obtenir une nouvelle projection D4 officielle, il faut intégrer :
- le contrat DTO/repository approprié dans `ksp-store-api` ;
- la migration/repository PostgreSQL dans `ksp-store-lib` ;
- la conversion/projector appropriée dans le composant de processing.
Un mécanisme de backend/projection entièrement externe pourra être étudié seulement si un besoin concret apparaît.
# Stabilité des niveaux durables
La direction retenue est :
```text
D1 — fortement stable
D2 — fortement stable
D3 — fortement stable
D4 — volontairement plus évolutif
```
Après stabilisation de la première série Store réelle, les contrats D1/D2/D3 doivent changer seulement en cas :
- d'erreur structurelle ;
- d'omission majeure ;
- de nécessité de compatibilité impossible à résoudre additivement.
D4 peut évoluer plus librement lorsque de nouveaux décodeurs, materializers ou produits révèlent des besoins queryables supplémentaires.
# `ksp-materializer-api`
## Rôle
Une seule crate publique est retenue :
```text
ksp-materializer-api
```
Elle expose les contrats de matérialisation réutilisables sans dépendre du Store.
Deux capacités conceptuelles doivent pouvoir être distinguées :
```text
GenericMaterializer
DomainProjector
```
Les noms exacts restent à valider.
### GenericMaterializer
Transforme une représentation Core/runtime en output générique persistable en D3.
### DomainProjector
Transforme un ou plusieurs inputs génériques/canoniques en représentation spécialisée de domaine destinée à D4.
Le second contrat peut évoluer en fonction des premiers cas réels. La séparation des responsabilités est plus importante que le nom du trait.
## Dépendances
```text
ksp-materializer-api
-> ksp-core-lib
-> ksp-program-api
```
Pas de dépendance vers Store.
# `ksp-materializer-lib`
`ksp-materializer-lib` contient les implémentations officielles KSP de `ksp-materializer-api`.
Organisation conceptuelle possible :
```text
generic/
...
domain/
metadata/
token/
dex/
...
```
La structure finale suivra les règles de domaine établies avec les premières implémentations.
Interdictions :
```text
ksp-materializer-lib -X-> ksp-store-api
ksp-materializer-lib -X-> ksp-store-lib
```
Un materializer transforme ; il ne persiste pas directement.
Le worker/job/pipeline spécialisé relie la transformation à la persistence.
# `ksp-store-api`
## Rôle
`ksp-store-api` expose la frontière backend-agnostic de persistence KSP.
Il possède les contrats persistants correspondant aux niveaux durables :
```text
raw
core
materialization
domain
```
La structure exacte des modules Rust sera définie avec la première implémentation.
`ksp-store-api` ne dépend pas de Program, Materializer ou Transport.
## Contrats génériques et contrats de domaine
D1/D2/D3 doivent rester génériques et fortement structurants.
D4 peut croître progressivement avec les domaines officiellement supportés.
Cette différence est volontaire : l'API Store doit pouvoir ajouter de nouvelles projections queryables sans déstabiliser les contrats de replay historiques.
# `ksp-store-lib`
`ksp-store-lib` est l'implémentation officielle de référence de `ksp-store-api`.
PostgreSQL est le backend de référence prévu.
La crate possède notamment :
- configuration backend/connexion ;
- pool/transactions backend ;
- migrations ;
- repositories ;
- queries ;
- persistence D1/D2/D3/D4 ;
- primitives de backlog/replay nécessaires au backend ;
- mécanismes PostgreSQL de notification lorsqu'ils sont retenus.
Les autres crates KSP ne contournent pas `ksp-store-lib` pour exécuter directement leurs propres opérations PostgreSQL.
Un second backend n'est pas créé abstraitement ; il devra justifier l'évolution de l'architecture lorsqu'un besoin réel apparaît.
# Temporalités
Les temporalités blockchain et locales sont distinctes.
Exemples blockchain :
```text
slot
block_time: Option<...>
```
Exemples locaux :
```text
observed_at
acquired_at
persisted_at
processed_at
materialized_at
projected_at
```
Toutes ne doivent pas nécessairement être présentes dans chaque DTO/table. Leur sémantique doit cependant être explicite lorsqu'elles existent.
Aucune date locale ne remplace silencieusement un `block_time` absent.
# Provenance
Un niveau dérivé doit permettre de remonter à son input durable et au processor qui l'a produit.
## D1
Provenance d'acquisition :
- network ;
- provider/source ;
- transport ;
- rôle d'acquisition ;
- identité blockchain ;
- temporalités d'observation/persistence.
## D2
En plus :
- input D1 ;
- processor/decoder identity ;
- processor/decoder version ;
- input hash ;
- processing time/state.
## D3
En plus :
- input D2 ;
- materializer identity/version ;
- output identity/type/domain ;
- output/input hash ;
- materialization time/state.
## D4
En plus :
- input(s) D3 ou références canoniques explicitement définies ;
- projector identity/version ;
- projection time/state.
La représentation exacte de la provenance sera conçue pour éviter de répéter inutilement de gros payloads.
# Idempotence et versionnement
Chaque frontière dérivée doit pouvoir rejouer le même input sans créer de doublons logiquement distincts.
Principe conceptuel :
```text
same logical input
+ same processor identity
+ same processor version
+ same logical output identity
= same durable result
```
Une nouvelle version du processor doit pouvoir coexister avec ou superséder le résultat précédent selon la politique du niveau.
Le système doit pouvoir représenter selon besoin des états tels que :
```text
current
superseded
pending
failed
replay
```
Les noms, colonnes et contraintes SQL exacts seront décidés avec la première implémentation.
L'idempotence ne doit pas reposer uniquement sur l'espoir qu'une notification soit livrée une seule fois.
# Replay
Les replays sont séparés par frontière durable :
```text
D1 -> D2
D2 -> D3
D3 -> D4
```
Ils doivent pouvoir être exécutés indépendamment.
SPECIALIZED expose des projections queryables utiles aux applications, analyses et futurs modèles ML.
Exemples :
- nouveau decoder/Core processor : rejouer D1 -> D2 ;
- nouveau materializer générique : rejouer D2 -> D3 ;
- nouvelle version d'un projector : rejouer D3 -> D4.
- token/asset state ;
- metadata canonique d'asset ;
- pools/markets ;
- reserves/liquidity ;
- positions ;
- swaps/trades ;
- fees ;
- observations de prix ;
- OHLC/candles ;
- routes et legs ;
- faits trading-adjacent ;
- projections d'autres domaines futurs.
Il ne doit pas être nécessaire de refaire toute la chaîne lorsqu'un niveau inférieur inchangé contient déjà l'information requise.
## Faits métier génériques
Les replays sont des **jobs bornés**, pas des modes cachés des workers live.
Les projections de trading ne sont pas séparées automatiquement par protocole.
Les jobs de replay retenus sont `ksp-job-replay-core`, `ksp-job-replay-generic-materialization` et `ksp-job-replay-domain-projection`.
# Notifications de données persistées
## Contrat
`ksp-store-api` est le propriétaire du contrat canonique lorsqu'une notification signifie :
> une donnée durable de telle catégorie/référence est disponible.
Le même type de donnée utilise le même format de notification quelle que soit son origine :
Préférer lorsque possible :
```text
worker live
backfill job
import
replay
autre source
liquidity_pools
trades
positions
price_observations
ohlc
routes
route_legs
```
## Notification != source de vérité
Une notification est un **signal de réveil/accélération**, jamais la source de vérité du backlog.
Elle peut être :
- perdue ;
- dupliquée ;
- retardée ;
- reçue après un restart.
Le consumer doit toujours pouvoir reconstruire son travail depuis le Store.
Exemple conceptuel :
plutôt que :
```text
notification RawAvailable
|
v
wake-up core worker
|
v
store query:
"quels inputs D1 ne sont pas encore traités
par CoreProcessor version X ?"
meteora_trades
raydium_trades
orca_trades
pump_trades
```
Le Store, l'idempotence et les checkpoints durables constituent la vérité.
Les champs réellement protocol-specific peuvent être conservés dans une extension ou une projection dédiée uniquement lorsqu'un besoin de requête/invariant le justifie.
Cette règle évite d'exiger immédiatement un broker exactly-once.
## Metadata
## Ordre de publication
La direction reste :
Une donnée n'est annoncée disponible qu'après persistence réussie :
- projection canonique commune pour metadata d'assets/tokens alimentée par Metaplex Token Metadata et Token-2022 Metadata ;
- SPM reste distinct et sera redéveloppé plus tard avec le décodage généraliste.
## OHLC
Les candles sont des projections SPECIALIZED calculées à partir des trades/price observations persistés.
Une application marché lit les OHLC matérialisés ; elle ne reparcourt pas toutes les transactions pour reconstruire les candles à chaque affichage.
# Vertical slices Program
RAW et CORE sont développés horizontalement.
À partir de DECODE, la progression est verticale par groupe :
```text
wire
-> decode
-> generic materialization / D3
-> specialized projection / D4 si utile
-> execution preparation
-> execution policy
-> execution
-> Devnet scenarios / validation
```
Un groupe doit atteindre une cohérence verticale suffisante avant que le groupe suivant devienne prioritaire.
Les composants satellites nécessaires à un protocole appartiennent à son groupe : Pump fees avec Pump, Meteora vaults avec Meteora, etc.
# `ksp-store-api`
`ksp-store-api` est backend-agnostic et porte les contrats nécessaires aux consommateurs.
La première implementation `0.3.1` est volontairement **RAW-only** : elle ne crée pas prématurément les contrats physiques D2/D3/D4.
Les surfaces CORE/DECODE/SPECIALIZED sont ajoutées quand leurs couches sont réellement ouvertes.
# `ksp-store-lib`
`ksp-store-lib` fournit PostgreSQL comme backend officiel de référence derrière `ksp-store-api`.
Il possède :
- migrations ;
- SQL ;
- transactions ;
- mapping backend ;
- pagination ;
- claim/lease lorsque nécessaire ;
- notifications backend si retenues.
Il ne possède pas :
- transport réseau ;
- decoder Program ;
- materializer ;
- orchestration de worker/job.
# `ksp-materializer-api` et `ksp-materializer-lib`
Ils sont introduits seulement lorsque le premier groupe DECODE démontre le contrat réel.
`ksp-materializer-api` porte les contrats extensibles ; `ksp-materializer-lib` contient les implementations officielles communes.
Une projection très locale/spécifique peut rester dans son groupe si la création d'une implémentation commune séparée n'apporte pas de réutilisation réelle.
# Replay
Les frontières durables restent replayables indépendamment :
```text
RAW -> CORE
CORE -> DECODE
DECODE -> SPECIALIZED
```
Un replay d'une couche dérivée ne doit pas refaire arbitrairement les couches précédentes.
# Notifications persistées
Le Store reste source de vérité du backlog.
Les notifications ne sont qu'un wake-up : elles peuvent être perdues ou dupliquées.
Ordre :
```text
persist
@@ -616,118 +346,35 @@ commit
notify
```
et non :
```text
notify
persist
```
## Payload
La notification privilégie une référence durable compacte plutôt que la duplication de tout le payload :
- catégorie/type ;
- réseau ;
- identifiant/range/cursor durable ;
- autres informations minimales nécessaires au consumer.
Les noms de DTO exacts restent à définir.
## Mécanisme de diffusion
Le contrat est indépendant du mécanisme.
Candidats :
```text
channel in-process
PostgreSQL LISTEN/NOTIFY
IPC
broker externe
```
`ksp-store-lib` peut fournir PostgreSQL LISTEN/NOTIFY comme mécanisme de référence si cela répond au premier besoin.
Le mécanisme initial de référence et la reprise opérationnelle sont détaillés dans `009-ACQUISITION_WORKERS_AND_JOBS.md`.
Le consumer reconstruit toujours son backlog depuis le Store avec les versions de processor et les marqueurs d'idempotence.
# Acquisition live et backfill
`ksp-worker-raw-retriever` et `ksp-job-backfill` diffèrent par leur lifecycle/orchestration mais produisent le **même contrat D1** pour la même catégorie de donnée.
Live et backfill alimentent la même frontière RAW :
```text
live source ----------\
+--> D1 Raw
historical backfill --/
live worker ----\
+--> RAW persistence
backfill job ----/
```
Cela garantit que le processing downstream ne dépend pas de la manière dont la donnée a été acquise.
Ils ne dupliquent pas le contrat durable.
Le backfill n'est pas un mode historique du worker live.
# Stabilité
# Workers de processing
La stabilité cible est différente selon la couche :
Les frontières de responsabilité sont désormais :
```text
ksp-worker-raw-retriever
transport -> D1
ksp-worker-core-processor
D1 -> D2
ksp-worker-generic-materializer
D2 -> D3
ksp-worker-domain-projector
D3 -> D4
```
Chaque worker :
- peut utiliser les notifications pour réduire la latence ;
- doit pouvoir reconstruire son backlog depuis le Store ;
- écrit seulement le niveau durable dont il est propriétaire ;
- ne transforme pas silencieusement plusieurs frontières en une étape monolithique.
Le lifecycle, la concurrence, les cursors/checkpoints et la hot reconfiguration sont détaillés dans `009-ACQUISITION_WORKERS_AND_JOBS.md`.
# Projections de trading et autres domaines
Le trading reste une priorité produit mais ne détermine pas la structure D1/D2/D3.
D4 doit accueillir progressivement des faits canoniques de nombreux domaines :
- token ;
- metadata ;
- staking ;
- programmes ;
- trading/DEX ;
- autres domaines futurs.
Pour le trading, les materializers/projectors doivent normaliser les noms et structures propres aux protocoles vers des faits communs lorsque les invariants le permettent.
- RAW : fortement stable après mise en production ;
- CORE : fortement stable après validation de la normalisation Solana générique ;
- DECODE : extensible par nouveaux Program/versions ;
- SPECIALIZED : plus évolutif selon les besoins de query, trading et analytics.
# Questions laissées ouvertes
La première implémentation Store devra encore fixer :
- schémas SQL et noms exacts des tables ;
- clés/idempotence exactes ;
- représentation des hashes ;
- états de processing exacts ;
- temporalités obligatoires/optionnelles par table ;
- format exact des DTO D1/D2/D3 ;
- structure des repositories/transactions backend ;
- pagination/cursors ;
- conversion u64/slot/PostgreSQL ;
- stratégie des migrations initiales.
Les sujets opérationnels worker/job ont été précisés dans `009-ACQUISITION_WORKERS_AND_JOBS.md`.
Restent à définir à l'implémentation :
- schémas SQL et contraintes exactes ;
- format concret des DTO D1/D2/D3/D4 ;
- claim/lease PostgreSQL ;
- contexte des projectors stateful ;
- mécanisme IPC des managers de services autonomes.
- schémas SQL exacts RAW puis CORE ;
- représentation persistable exacte d'un decoded output ;
- contrat exact du journal D3 ;
- granularité des projectors SPECIALIZED ;
- politique de supersession/versioning des outputs ;
- fenêtres OHLC initiales ;
- mécanisme de contexte pour les projections stateful.

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md -->
<!-- version: 1 -->
<!-- version: 2 -->
# Applications, services, scenarios et control plane
@@ -47,6 +47,12 @@ Elle ne doit pas réimplémenter :
- lifecycle interne d'un worker/job ;
- logique de pipeline réutilisable.
# Applications de validation par couche
KSP peut ajouter une petite application spécialisée à la fin d'une couche RAW ou CORE lorsque cela permet de valider et exploiter réellement la couche avant de passer à la suivante. Ces applications lisent les contrats KSP et ne recopient pas les processors dans Tauri.
À partir des vertical slices Program, les applications restent attachées aux besoins réels : demos de scenarios pour l'exécution et Market Desk pour les projections de marché.
# Priorité aux applications spécialisées
KSP ne planifie pas actuellement de cockpit desktop global.
@@ -151,11 +157,12 @@ Exemples conceptuels :
```text
ksp-worker-raw-retriever
ksp-worker-core-processor
ksp-worker-generic-materializer
ksp-worker-domain-projector
future CORE worker
future group-specific DECODE/SPECIALIZED workers when justified
```
RAW et CORE reçoivent leurs workers à la fin de leur couche respective. Les workers DECODE/SPECIALIZED ne sont plus tous anticipés comme une chaîne globale fixe : leur granularité doit émerger des premiers vertical slices Program.
Le binaire doit rester mince.
Il ne duplique pas le pipeline ni la logique de worker contenue dans la cible bibliothèque du même package.
@@ -232,7 +239,7 @@ Le data plane transporte/persiste les données Solana et les résultats de proce
ksp-onchain-transport-lib
|
v
D1 -> D2 -> D3 -> D4
RAW -> CORE -> DECODE -> SPECIALIZED
```
avec notifications de données persistées comme wake-up.
@@ -469,6 +476,16 @@ worker status
Une app spécialisée peut éditer une configuration puis demander son application, mais ne doit pas considérer l'écriture du document comme la preuve que le worker l'a appliquée.
# Market Desk progressive
Après les groupes Meteora/Raydium/Pump/Orca, KSP prévoit une première application spécialisée candidate `ksp-app-market-desk`.
V1 peut afficher tokens, pools/markets, liquidité, trades/swaps, prix, volumes, OHLC et activité live/récente à partir des projections SPECIALIZED et des contrats KSP. Elle ne dépend pas directement des SDK/protocoles DEX pour reconstruire leurs modèles dans l'UI.
Après Jupiter/OKX, la même application est enrichie avec routes, legs, DEX impliqués, fees/slippage et comparaison quote/execution lorsqu'elle existe.
Les OHLC sont matérialisés dans SPECIALIZED et consommés par l'application; ils ne sont pas recalculés à partir de tout l'historique lors de chaque rendu.
# Future orchestrator
Un orchestrateur global pourra devenir utile lorsque plusieurs services/managers/jobs devront être coordonnés.
@@ -522,7 +539,7 @@ control/application adapters
Data plane séparé :
```text
transport -> D1 -> D2 -> D3 -> D4
transport -> RAW -> CORE -> DECODE -> SPECIALIZED
```
Aucun payload de processing n'a besoin de transiter via l'UI/control plane.