v0.0.3-pre.007

This commit is contained in:
2026-08-14 12:14:00 +02:00
parent 2cb9f809b7
commit 3b5d1a8f7a
13 changed files with 1447 additions and 121 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 12
# version: 13
[workspace]
resolver = "3"
members = ["crates/ksp-core-lib"]
[workspace.package]
version = "0.0.3-pre.6"
version = "0.0.3-pre.7"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Roadmap KSP
@@ -57,7 +57,10 @@ Regrouper les releases consacrées aux fondations N1. La série n'est pas destin
- [ ] Introduire `ksp-worker-api` et `ksp-worker-raw-retriever`.
- [ ] Introduire `ksp-worker-control-lib` lorsque le manager W1 crée le premier besoin concret.
- [ ] Introduire `ksp-job-api` et `ksp-job-backfill`.
- [ ] Introduire les pipelines spécialisés raw ingestion, Core processing, generic materialization et domain projection lorsque leurs premières frontières fonctionnelles sont développées.
- [ ] Introduire les jobs de replay indépendants D1 -> D2, D2 -> D3 et D3 -> D4.
- [ ] Normaliser les notifications de données persistées indépendamment de leur producteur et conserver le Store comme source de vérité du backlog.
- [ ] Mettre en place claim/lease, outcomes durables et reprise après crash pour les traitements concurrents.
## 0.4.x — Baseline Solana, SPL et metadata
@@ -82,6 +85,7 @@ Regrouper les releases consacrées aux fondations N1. La série n'est pas destin
- [ ] Introduire `ksp-worker-core-processor` pour D1 Raw -> D2 Core canonique.
- [ ] Introduire `ksp-worker-generic-materializer` pour D2 Core -> D3 journal de matérialisation générique.
- [ ] Introduire `ksp-worker-domain-projector` pour D3 -> D4 projections spécialisées ; nom révisable.
- [ ] Exploiter les mêmes pipelines spécialisés pour les workers live et les jobs de replay afin d'éviter la duplication des frontières de processing.
- [ ] Étendre `ksp-worker-control-lib` à la gouvernance de plusieurs workers.
- [ ] Garder jobs et workers sous des lifecycle APIs séparées.
- [ ] Introduire un orchestrateur global lorsqu'il existe plusieurs managers/workers à coordonner.

207
deltas/0.0.3/pre.007.md Normal file
View File

@@ -0,0 +1,207 @@
<!-- file: deltas/0.0.3/pre.007.md -->
<!-- version: 1 -->
# Delta 0.0.3-pre.007
## Base requise
`v0.0.3-pre.006`.
## Objectif
Formaliser le modèle opérationnel des acquisitions et traitements continus/ponctuels au-dessus des niveaux durables D1D4, sans encore ouvrir les apps/managers/IPC.
## Version Cargo
`workspace.package.version` passe de :
```text
0.0.3-pre.6
```
à :
```text
0.0.3-pre.7
```
Le header de `Cargo.toml` passe de version 12 à 13.
## Fichiers ajoutés
- `docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md`
- `deltas/0.0.3/pre.007.md`
## Fichiers modifiés
- `Cargo.toml`
- `ROADMAP.md`
- `docs/architecture/000-README.md`
- `docs/architecture/003-COMPONENT_CONTRACTS.md`
- `docs/architecture/004-COMPONENT_INVENTORY.md`
- `docs/architecture/005-DEPENDENCY_GRAPH.md`
- `docs/rules/RULES_DEPENDENCIES.md`
- `docs/rules/RULES_KSP.md`
- `docs/IDEAS.md`
- `docs/plans/001-V0_0_3_PLAN.md`
- `prompts/001-V0_1_X_START_PROMPT.md`
## Fichiers supprimés
Aucun.
## Décisions principales
### Pipelines spécialisés
Le besoin concret de mutualiser exactement la même frontière entre worker live et job justifie quatre crates :
```text
ksp-pipeline-raw-ingestion-lib
ksp-pipeline-core-processing-lib
ksp-pipeline-generic-materialization-lib
ksp-pipeline-domain-projection-lib
```
Aucun `ksp-pipeline-lib` monolithique n'est introduit.
Les pipelines dépendent des APIs nécessaires, pas des implémentations officielles lorsqu'une injection est possible :
```text
raw ingestion -> onchain transport models + store-api
core processing -> program-api + store-api
generic materialize -> materializer-api + store-api
domain projection -> materializer-api + store-api
```
Workers/jobs composent ensuite `ksp-store-lib`, `ksp-program-lib`, `ksp-materializer-lib` ou des implémentations externes compatibles.
### Workers
Workers retenus :
```text
ksp-worker-raw-retriever
ksp-worker-core-processor
ksp-worker-generic-materializer
ksp-worker-domain-projector
```
`ksp-worker-api` reste une lifecycle API continue.
Le raw retriever supporte la hot reconfiguration et distingue configuration desired/effective.
### Jobs
Jobs de données retenus :
```text
ksp-job-backfill
ksp-job-replay-core
ksp-job-replay-generic-materialization
ksp-job-replay-domain-projection
```
`ksp-job-api` reste séparé de Worker et aucune `ksp-job-control-lib` n'est créée.
### Backlog et outcomes
L'absence d'output ne signifie pas qu'un input est pending.
Le backlog est relatif à :
```text
input
processor identity
processor version
capability/materializer/projector
```
Chaque traitement possède un outcome durable, y compris pour NoOutput/NotApplicable/Unsupported selon les types finaux.
Une nouvelle version de processor peut créer un nouveau travail pour un input déjà terminal sous l'ancienne version.
### Claim / lease
La concurrence multi-instance utilise une ownership temporaire par claim/lease.
Une lease expirée après crash rend l'input de nouveau claimable.
Le détail SQL est reporté à l'implémentation PostgreSQL.
### At-least-once
Sémantique retenue :
```text
at-least-once processing
+
idempotent durable persistence
+
durable processing outcomes
```
Aucune promesse exactly-once distribuée n'est recherchée.
### Atomicité
Outputs obligatoires et processing outcome d'une même unité logique doivent être cohérents/atomiques du point de vue durable.
### Reprise
Après restart, worker/job recharge configuration/scope, laisse expirer/récupère les claims, requête le backlog Store et reprend.
Un cursor est une optimisation, pas la preuve de completion.
### Replay
Replay normal/reprise et force replay sont distincts.
Un force replay conserve provenance/historique et ne supprime pas silencieusement le résultat courant.
### Notifications
PostgreSQL `LISTEN/NOTIFY` est retenu comme mécanisme initial de référence de wake-up, sans garantie de backlog.
Chaque consumer combine :
```text
notification wake-up
+
periodic polling
```
Le Store reste la source de vérité.
### Batching / backpressure
Batch size, concurrence, poll interval, retry/backoff et lease duration sont des paramètres spécialisés, pas nécessairement des propriétés universelles de Worker/Job API.
Un backlog downstream croissant est observable mais ne ralentit pas automatiquement l'acquisition D1.
## Plan
- `pre.008` — apps/managers/scenarios/processus/IPC/orchestration ;
- `pre.009` — releases fonctionnelles concrètes ;
- `pre.010` — clôture fondatrice.
## Questions reportées
- schéma SQL de claim/lease ;
- durée/renouvellement de lease ;
- types exacts des processing outcomes ;
- contexte stateful des projectors ;
- graceful shutdown d'un batch ;
- pause/resume générique ou capability de job ;
- télémétrie/metrics au-delà des logs et health.
## Validations
- headers `file:` / `version:` vérifiés ;
- `Cargo.toml` parsé et version `0.0.3-pre.7` vérifiée ;
- référence vers `009-ACQUISITION_WORKERS_AND_JOBS.md` vérifiée ;
- quatre pipelines spécialisés présents dans inventaire/règles ;
- quatre workers et quatre jobs de données présents dans l'architecture ;
- aucune dépendance pipeline vers `ksp-store-lib`, `ksp-program-lib` ou `ksp-materializer-lib` dans le graphe de pipeline ;
- plan conservé jusqu'à `pre.010` ;
- aucune commande Cargo build/test exécutée : ce delta reste documentaire.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/IDEAS.md -->
<!-- version: 10 -->
<!-- version: 11 -->
# Idées à explorer
@@ -228,20 +228,50 @@ Le journal D3 doit accepter les outputs de materializers officiels ou externes s
### Backlog et checkpoints
**Status :** À explorer en `pre.007`
**Status :** Transférée vers une décision/règle
Les notifications restent des wake-ups. Définir comment chaque worker/job interroge le Store pour retrouver les inputs non traités par une version donnée, avec pagination, batching, reprise et concurrence.
Les processing outcomes par processor/version/capability constituent la vérité du backlog. Les cursors sont des optimisations et les jobs historiques conservent en plus leurs checkpoints de source.
### Jobs de replay
**Status :** À explorer en `pre.007`
**Status :** Transférée vers une décision/règle
Prévoir des jobs séparés pour D1 -> D2, D2 -> D3 et D3 -> D4 plutôt qu'un replay monolithique obligatoire.
Les noms définitifs ne sont pas encore retenus.
Trois jobs distincts sont retenus : `ksp-job-replay-core`, `ksp-job-replay-generic-materialization` et `ksp-job-replay-domain-projection`. Ils réutilisent les pipelines spécialisés correspondants.
### Notification backend de référence
**Status :** À explorer en `pre.007`
**Status :** Transférée vers une décision/règle
PostgreSQL LISTEN/NOTIFY est un candidat naturel pour la première implémentation de signal de réveil, mais le contrat doit rester indépendant du mécanisme et le Store reste la source de vérité.
PostgreSQL LISTEN/NOTIFY est retenu comme mécanisme initial de référence de wake-up, combiné à un periodic polling du backlog. Le Store reste la source de vérité.
## Workers / jobs — questions d'implémentation restantes
### Claim/lease PostgreSQL
**Status :** À explorer avec la première implémentation Store/worker
Définir le schéma SQL, la durée/renouvellement de lease et la technique PostgreSQL exacte permettant plusieurs instances concurrentes sans bloquer définitivement un input après crash.
### Processing outcomes
**Status :** À explorer avec D2/D3/D4 réels
Fixer les noms/types exacts et distinguer Produced, NoOutput, NotApplicable, Unsupported et failure déterministe sans transformer des situations normales en erreurs.
### Contexte stateful des projectors
**Status :** À explorer avec la première projection nécessitant un état existant
Le Store est interrogé par le pipeline/worker puis le contexte est injecté au `DomainProjector`. Définir comment le projector décrit les données de contexte nécessaires sans dépendre du backend.
### Job pause/resume
**Status :** À explorer avec `ksp-job-api`
Checkpoint/restart est nécessaire pour backfill/replay. Déterminer si pause/resume doit être une capability générique ou rester spécifique aux jobs qui la supportent.
### Télémétrie opérationnelle
**Status :** À explorer
Backlog count, oldest pending age, processing rate et failure rate doivent être observables. Décider plus tard si health/status + logging suffisent ou si une API/metrics exporter dédiée devient nécessaire.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/000-README.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Architecture KSP
@@ -24,6 +24,7 @@ Ils ne remplacent ni `ROADMAP.md`, ni les plans de version, ni les deltas.
5. [`005-DEPENDENCY_GRAPH.md`](005-DEPENDENCY_GRAPH.md) — graphe de dépendances retenu, dépendances interdites et frontières de conversion/composition ;
6. [`006-WIRE_AND_PROGRAM.md`](006-WIRE_AND_PROGRAM.md) — propriété des contrats wire, politique de dépendances codecs/interfaces, API Program ouverte, preparation d'exécution et extensibilité externe ;
7. [`007-EXECUTION_AND_POLICY.md`](007-EXECUTION_AND_POLICY.md) — policy multi-checkpoints, orchestration transactionnelle, wallet/transport, retry, approval externe et résultat d'exécution ;
8. [`008-DATA_MATERIALIZATION_AND_STORE.md`](008-DATA_MATERIALIZATION_AND_STORE.md) — niveaux durables D1D4, Materialization, Store PostgreSQL de référence, provenance, idempotence, replay et notifications de données persistées.
8. [`008-DATA_MATERIALIZATION_AND_STORE.md`](008-DATA_MATERIALIZATION_AND_STORE.md) — niveaux durables D1D4, Materialization, Store PostgreSQL de référence, provenance, idempotence, replay et notifications de données persistées ;
9. [`009-ACQUISITION_WORKERS_AND_JOBS.md`](009-ACQUISITION_WORKERS_AND_JOBS.md) — pipelines spécialisés, workers live, jobs de backfill/replay, backlog, claim/lease, reprise, concurrence et mécanisme de notification de référence.
`004-COMPONENT_INVENTORY.md` et `005-DEPENDENCY_GRAPH.md` sont maintenus ensemble : une évolution du graphe qui change le propriétaire d'une responsabilité doit corriger l'inventaire au lieu de laisser deux descriptions contradictoires.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/003-COMPONENT_CONTRACTS.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Contrats initiaux des composants KSP
@@ -9,7 +9,7 @@ Ce document enregistre les frontières déjà suffisamment claires pour guider l
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) et Data/Materialization/Store dans [`008-DATA_MATERIALIZATION_AND_STORE.md`](008-DATA_MATERIALIZATION_AND_STORE.md).
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) et Acquisition/Workers/Jobs dans [`009-ACQUISITION_WORKERS_AND_JOBS.md`](009-ACQUISITION_WORKERS_AND_JOBS.md).
## Convention API / implémentation
@@ -136,7 +136,7 @@ Le contrat de notification est distinct de son transport concret.
`ksp-worker-control-lib` est une implémentation réutilisable de gouvernance pouvant être consommée par les applications manager desktop, une future application globale ou un orchestrateur.
Workers actuellement retenus :
Workers retenus :
```text
ksp-worker-raw-retriever
@@ -147,11 +147,22 @@ ksp-worker-domain-projector
Le dernier nom reste provisoire.
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.
## Jobs
`ksp-job-api` est une lifecycle API distincte pour travaux déclenchés et terminables.
`ksp-job-backfill` est retenu pour le backfill historique.
Jobs de données retenus :
```text
ksp-job-backfill
ksp-job-replay-core
ksp-job-replay-generic-materialization
ksp-job-replay-domain-projection
```
Les trois jobs de replay correspondent exactement aux frontières D1 -> D2, D2 -> D3 et D3 -> D4.
Aucune `ksp-job-control-lib` n'est prévue actuellement. D'autres jobs pourront apparaître pour metadata, quotes ou autres besoins ponctuels.
@@ -173,4 +184,13 @@ et réutilisent la crate de scénario correspondante.
Aucun `ksp-pipeline-lib` monolithique.
Des pipelines spécialisés peuvent être ajoutés à la demande. `ksp-execution-lib` est justement étudié comme un pipeline/orchestrateur spécialisé, pas comme une infrastructure universelle.
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.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Inventaire initial des composants KSP
@@ -9,7 +9,7 @@ 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 et `pre.006` les niveaux durables/Materialization/Store dans [`008-DATA_MATERIALIZATION_AND_STORE.md`](008-DATA_MATERIALIZATION_AND_STORE.md). Les détails de types Rust restent révisables avec les premières implémentations.
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 dans [`008-DATA_MATERIALIZATION_AND_STORE.md`](008-DATA_MATERIALIZATION_AND_STORE.md), puis `pre.007` l'exploitation workers/jobs/pipelines dans [`009-ACQUISITION_WORKERS_AND_JOBS.md`](009-ACQUISITION_WORKERS_AND_JOBS.md). Les détails de types Rust restent révisables avec les premières implémentations.
## Statuts
@@ -21,41 +21,47 @@ Le premier inventaire a été produit en `0.0.3-pre.002`. `pre.003` l'a corrigé
## 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.x` | `Error` commun, Program IDs, primitives/contrats réellement transversaux |
| Configuration | `ksp-config-lib` | lib | N1 | Retenu | `0.1.x` | documents de configuration, profils, résolution, modifications autorisées |
| Logging | `ksp-logging-lib` | lib | N1 | Retenu | `0.1.x` | façade unique `tracing`/appender/subscriber, initialisation et logging structuré KSP ; peut dépendre de core pour Error/Result |
| 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 des workers pour managers/apps/orchestrateur |
| 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 |
| 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 |
| Specialized pipelines | `ksp-pipeline-<role>-lib` ou autre forme | variable | N3/N4 | À la demande | selon besoin | pipeline concret et borné ; aucune crate pipeline globale |
| 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 | Nature | Niveau provisoire | Statut | Première série envisagée | Responsabilité principale |
|----------------------------------|---------------------------------------------|-------------------------|-------------------|-----------------------------------|-----------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| Core | `ksp-core-lib` | lib | N1 | Retenu | `0.1.x` | `Error` commun, Program IDs, primitives/contrats réellement transversaux |
| Configuration | `ksp-config-lib` | lib | N1 | Retenu | `0.1.x` | documents de configuration, profils, résolution, modifications autorisées |
| Logging | `ksp-logging-lib` | lib | N1 | Retenu | `0.1.x` | façade unique `tracing`/appender/subscriber, initialisation et logging structuré KSP ; peut dépendre de core pour Error/Result |
| 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 des workers pour managers/apps/orchestrateur |
| 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 |
## APIs séparées retenues
@@ -255,7 +261,37 @@ Chaque application appelle la crate `ksp-scenario-<domain>-lib` correspondante e
`ksp-pipeline-lib` reste rejeté.
Des pipelines spécialisés peuvent être créés à la demande lorsqu'un flux concret possède assez de logique réutilisable pour justifier sa propre frontière. Leur forme n'est pas nécessairement une bibliothèque : certains pourront être workers, jobs ou composants spécialisés.
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`
@@ -275,4 +311,4 @@ Le graphe confirme les principes suivants :
- `pre.004` : types publics précis de `ksp-program-api` et policy ;
- `pre.005` : types publics de transport on-chain et conversion vers les DTO raw de `ksp-store-api` ;
- `pre.005` : modèles materializer/store, notifications, replay et provenance ;
- `pre.006` : managers/apps/processus/IPC, norme des scenarios et orchestrateur futur.
- `pre.008` : managers/apps/processus/IPC, norme des scenarios et orchestrateur futur.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/005-DEPENDENCY_GRAPH.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Graphe de dépendances KSP
@@ -460,6 +460,50 @@ Le mécanisme concret peut être channel, PostgreSQL LISTEN/NOTIFY, IPC ou broke
---
# Graphe des pipelines spécialisés
Les pipelines réutilisent une frontière de processing sans prendre le lifecycle worker/job.
```text
ksp-pipeline-raw-ingestion-lib
-> ksp-onchain-transport-lib
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
ksp-pipeline-core-processing-lib
-> ksp-program-api
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
ksp-pipeline-generic-materialization-lib
-> ksp-materializer-api
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
ksp-pipeline-domain-projection-lib
-> ksp-materializer-api
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
```
Interdictions :
```text
pipelines -X-> ksp-store-lib
core-processing pipeline -X-> ksp-program-lib
materialization pipelines -X-> ksp-materializer-lib
pipelines -X-> ksp-worker-api
pipelines -X-> ksp-job-api
```
Les workers/jobs fournissent les implémentations officielles ou externes aux pipelines.
---
# Graphe lifecycle Worker
```text
@@ -508,106 +552,135 @@ Un futur orchestrateur peut utiliser workers et jobs séparément sans créer de
# Graphe des composants concrets d'acquisition/processing
Les dépendances ci-dessous décrivent la composition attendue. Les détails de processus/IPC seront approfondis plus tard.
## `ksp-worker-raw-retriever` — transport -> D1
## `ksp-worker-raw-retriever`
```text
ksp-worker-raw-retriever
-> ksp-worker-api
-> ksp-config-lib
-> ksp-pipeline-raw-ingestion-lib
-> ksp-onchain-transport-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Responsabilité de conversion :
Il pilote l'acquisition live, puis transmet chaque modèle transport homogène au pipeline raw ingestion.
```text
transport raw model
|
v
store raw persistence model
```
Cette conversion appartient au worker d'acquisition, pas au transport ni au store.
Il possède une capacité spécifique de hot reconfiguration et distingue configuration desired/effective.
## `ksp-job-backfill`
```text
ksp-job-backfill
-> ksp-job-api
-> ksp-config-lib
-> ksp-pipeline-raw-ingestion-lib
-> ksp-onchain-transport-lib
-> ksp-store-api
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Il produit exactement la même famille de DTO D1 persistants et la même notification de données persistées que le worker live.
Il pilote pagination/range/checkpoint historique puis transmet les modèles acquis au même pipeline D1 que W1.
## `ksp-worker-core-processor` — D1 -> D2
## `ksp-worker-core-processor`
```text
ksp-worker-core-processor
-> ksp-worker-api
-> ksp-program-api
-> ksp-program-lib
-> ksp-store-api
-> ksp-pipeline-core-processing-lib
-> ksp-program-lib # composition officielle
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Il effectue la conversion explicite :
Une composition alternative peut fournir une implémentation externe compatible avec `ksp-program-api`.
## `ksp-job-replay-core`
```text
store raw DTO
|
v
program decode input
|
v
program canonical/decode output
|
v
store Core DTO
ksp-job-replay-core
-> ksp-job-api
-> ksp-pipeline-core-processing-lib
-> ksp-program-lib ou implémentation compatible
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
`ksp-program-lib` ne connaît donc pas le store.
Worker live et replay partagent donc exactement la logique D1 -> D2.
## `ksp-worker-generic-materializer` — D2 -> D3
## `ksp-worker-generic-materializer`
```text
ksp-worker-generic-materializer
-> ksp-worker-api
-> ksp-materializer-api
-> ksp-materializer-lib
-> ksp-store-api
-> ksp-pipeline-generic-materialization-lib
-> ksp-materializer-lib # composition officielle
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Il consomme le backlog D2, appelle la capacité de matérialisation générique puis persiste le journal D3. La notification éventuelle accélère le traitement mais ne remplace pas la query de backlog.
## `ksp-job-replay-generic-materialization`
## `ksp-worker-domain-projector` — D3 -> D4
```text
ksp-job-replay-generic-materialization
-> ksp-job-api
-> ksp-pipeline-generic-materialization-lib
-> ksp-materializer-lib ou implémentation compatible
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
## `ksp-worker-domain-projector`
```text
ksp-worker-domain-projector
-> ksp-worker-api
-> ksp-materializer-api
-> ksp-materializer-lib
-> ksp-store-api
-> ksp-pipeline-domain-projection-lib
-> ksp-materializer-lib # projectors officiels
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
Son nom reste provisoire.
## `ksp-job-replay-domain-projection`
Il est propriétaire de la composition entre D3, la projection/materialisation spécialisée et les DTO D4 persistants ; `ksp-materializer-lib` reste indépendant du backend. D4 est organisé par faits canoniques plutôt que par familles de tables propres aux protocoles.
```text
ksp-job-replay-domain-projection
-> ksp-job-api
-> ksp-pipeline-domain-projection-lib
-> ksp-materializer-lib ou implémentation compatible
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
## Backlog / notification
Tous les workers de processing :
```text
LISTEN/NOTIFY wake-up
+
periodic polling
|
v
Store backlog query
|
v
claim/lease bounded batch
|
v
pipeline
|
v
outputs + processing outcome
```
La notification ne remplace jamais le Store.
---

View File

@@ -0,0 +1,904 @@
<!-- file: docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md -->
<!-- version: 1 -->
# Acquisition, workers, jobs et pipelines spécialisés
## Objet
Ce document constitue la sortie principale de `0.0.3-pre.007`.
Il transforme les frontières durables D1D4 en modèle opérationnel et définit :
- quatre pipelines spécialisés correspondant chacun à une frontière durable ;
- quatre workers continus ;
- le job de backfill historique ;
- trois jobs de replay indépendants ;
- la séparation worker/job lifecycle ;
- le backlog durable par input + processor/version ;
- les processing outcomes ;
- claim/lease et concurrence multi-instance ;
- at-least-once + idempotence plutôt qu'un faux exactly-once ;
- reprise après crash ;
- notification wake-up + periodic polling ;
- hot reconfiguration du raw retriever ;
- batching, backpressure et métriques opérationnelles minimales.
Les apps, managers desktop, IPC et orchestrateur global sont reportés à `pre.008`.
# Principe : une frontière de processing, une logique réutilisable
Un worker live et un job de replay ne doivent pas réimplémenter séparément la même transformation durable.
KSP introduit donc les premiers pipelines spécialisés justifiés par un besoin concret :
```text
ksp-pipeline-raw-ingestion-lib
ksp-pipeline-core-processing-lib
ksp-pipeline-generic-materialization-lib
ksp-pipeline-domain-projection-lib
```
Il ne s'agit pas d'un retour vers un `ksp-pipeline-lib` monolithique.
Chaque pipeline correspond à **une seule frontière durable**.
```text
transport model -> D1
D1 -> D2
D2 -> D3
D3 -> D4
```
Le pipeline porte la logique réutilisable de la frontière ; le worker/job porte le lifecycle et le scope d'exécution.
# Frontière des pipelines
## `ksp-pipeline-raw-ingestion-lib`
Mission :
```text
homogeneous on-chain transport model
|
v
conversion D1
|
v
persistence D1
|
v
notification after commit
```
Le pipeline ne choisit pas et ne pilote pas la stratégie d'acquisition réseau.
Le worker live et le job de backfill lui fournissent les données déjà acquises.
Dépendances conceptuelles :
```text
ksp-pipeline-raw-ingestion-lib
-> ksp-onchain-transport-lib
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
```
Il ne dépend pas de `ksp-store-lib`.
Le backend concret est fourni par composition via les contrats de `ksp-store-api`.
## `ksp-pipeline-core-processing-lib`
Mission :
```text
D1 input
|
v
conversion vers ksp-program-api
|
v
decoder/registry fourni
|
v
Core output + processing outcome
|
v
persistence D2
```
Dépendances conceptuelles :
```text
ksp-pipeline-core-processing-lib
-> ksp-program-api
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
```
Il ne dépend pas de `ksp-program-lib` ni de `ksp-store-lib`.
L'implémentation officielle Program ou une extension externe est fournie par composition.
## `ksp-pipeline-generic-materialization-lib`
Mission :
```text
D2 input
|
v
GenericMaterializer fourni
|
v
generic output
|
v
D3 journal + processing outcome
```
Dépendances conceptuelles :
```text
ksp-pipeline-generic-materialization-lib
-> ksp-materializer-api
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
```
Il ne dépend pas de `ksp-materializer-lib` ni de `ksp-store-lib`.
## `ksp-pipeline-domain-projection-lib`
Mission :
```text
D3 input + contexte nécessaire
|
v
DomainProjector fourni
|
v
D4 projection + processing outcome
```
Dépendances conceptuelles :
```text
ksp-pipeline-domain-projection-lib
-> ksp-materializer-api
-> ksp-store-api
-> ksp-core-lib
-> ksp-logging-lib
```
Il ne dépend pas de `ksp-materializer-lib` ni de `ksp-store-lib`.
Lorsqu'un projector est stateful, le pipeline/composant de composition charge via Store le contexte requis et le fournit au projector. Le projector reste indépendant du backend.
# Worker API
`ksp-worker-api` reste une lifecycle API générique pour services continus.
Concepts candidats :
```text
WorkerId
WorkerDescriptor
WorkerState
WorkerHealth
WorkerCapabilities
```
États conceptuels possibles :
```text
Stopped
Starting
Running
Degraded
Stopping
Failed
```
Les noms Rust exacts ne sont pas figés.
Les opérations communes attendues sont au minimum :
```text
start
stop
status
health
```
Une capability telle que `reconfigure` n'est pas imposée à tous les workers. Un worker expose les capacités qu'il supporte réellement.
Le lifecycle Worker ne contient aucune progression terminale propre aux jobs.
# `ksp-worker-raw-retriever`
## Mission
Service continu/live ou quasi-live :
```text
subscription/fetch live
|
v
homogeneous transport model
|
v
ksp-pipeline-raw-ingestion-lib
|
v
D1
```
Il ne décode pas, ne matérialise pas, ne backfill pas et ne rejoue pas les niveaux dérivés.
## Hot reconfiguration
Le raw retriever doit pouvoir modifier à chaud au moins les dimensions réellement supportées par son transport, par exemple :
- Program IDs suivis ;
- accounts/adresses suivis ;
- types de données/subscriptions ;
- filtres d'acquisition ;
- endpoints/providers lorsque le transport permet une transition sûre.
La configuration runtime doit distinguer :
```text
desired configuration generation
effective/applied configuration generation
```
Une reconfiguration est considérée appliquée seulement lorsque les subscriptions/filtres correspondants sont réellement actifs.
En cas d'échec partiel, le status/health doit pouvoir refléter la divergence entre desired et effective.
La stratégie exacte de diff/subscription est propre au worker/transport, pas à `ksp-worker-api`.
# `ksp-worker-core-processor`
Service continu :
```text
D1 backlog
|
v
ksp-pipeline-core-processing-lib
|
v
D2
```
Il utilise :
- `ksp-worker-api` pour son lifecycle ;
- `ksp-store-lib` comme backend officiel de composition ;
- `ksp-program-lib` ou d'autres implémentations compatibles ;
- le pipeline Core commun.
Il peut être réveillé par une notification D1 mais reconstruit toujours son backlog depuis le Store.
# `ksp-worker-generic-materializer`
Service continu :
```text
D2 backlog
|
v
ksp-pipeline-generic-materialization-lib
|
v
D3
```
Il compose :
- `ksp-store-lib` ;
- `ksp-materializer-lib` et/ou materializers compatibles ;
- le pipeline générique.
Le backlog est suivi par input + materializer identity/version.
# `ksp-worker-domain-projector`
Service continu :
```text
D3 backlog
|
v
ksp-pipeline-domain-projection-lib
|
v
D4
```
Le nom reste provisoire, mais la responsabilité D3 -> D4 est retenue.
Il compose Store, projectors officiels/externes et pipeline de projection.
Un projector peut nécessiter un contexte existant D4 ou canonique. Le worker/pipeline charge ce contexte depuis le Store et le fournit explicitement ; `ksp-materializer-lib` ne dépend toujours pas du Store.
# Job API
`ksp-job-api` reste distinct de `ksp-worker-api`.
Concepts candidats :
```text
JobId
JobDescriptor
JobState
JobProgress
JobResult
JobCapabilities
```
Le job est déclenché, borné et terminable.
Les capacités suivantes peuvent exister lorsqu'elles sont pertinentes :
```text
cancel
pause
resume
checkpoint
```
Elles ne sont pas obligatoirement universelles.
Aucune `ksp-job-control-lib` n'est introduite.
# `ksp-job-backfill`
## Mission
Acquisition historique uniquement :
```text
historical fetch/pagination
|
v
homogeneous transport model
|
v
ksp-pipeline-raw-ingestion-lib
|
v
D1
```
Il ne produit pas D2/D3/D4.
Live acquisition et backfill produisent donc le même contrat D1.
## Scope et progression
Un backfill doit pouvoir enregistrer durablement selon sa stratégie :
- network ;
- provider/source ;
- catégorie d'acquisition ;
- filtre/range demandé ;
- pagination/cursor ;
- slot/signature ranges lorsque pertinents ;
- candidats vus/traités ;
- records D1 persistés ;
- erreurs/retries ;
- checkpoint de reprise.
Le checkpoint backfill décrit également la progression dans une source externe ; il ne se réduit donc pas à un processing outcome D1.
# Jobs de replay
Trois jobs distincts sont retenus :
```text
ksp-job-replay-core
ksp-job-replay-generic-materialization
ksp-job-replay-domain-projection
```
Ils réutilisent les mêmes pipelines que les workers continus.
## `ksp-job-replay-core`
```text
scope D1
|
v
ksp-pipeline-core-processing-lib
|
v
D2
```
Il compose l'implémentation Program cible et son identité/version.
## `ksp-job-replay-generic-materialization`
```text
scope D2
|
v
ksp-pipeline-generic-materialization-lib
|
v
D3
```
Il cible un ou plusieurs materializers/versions.
## `ksp-job-replay-domain-projection`
```text
scope D3
|
v
ksp-pipeline-domain-projection-lib
|
v
D4
```
Il cible un ou plusieurs projectors/versions.
## Scope de replay
Selon la frontière, un replay peut être borné par :
- network ;
- slot/range ;
- Program ID ;
- type de donnée ;
- processor/materializer/projector ;
- domaine ;
- autres filtres canoniques disponibles.
Les scopes exacts sont définis par les contrats Store réels et non par une query PostgreSQL fuite dans `ksp-job-api`.
# Processing outcome durable
L'absence d'output ne signifie jamais automatiquement qu'un input n'a pas été traité.
Un traitement valide peut produire zéro output parce qu'il est :
- non applicable ;
- unsupported par cette version ;
- volontairement sans output ;
- reconnu mais ignoré selon le contrat du processor.
Chaque frontière dérivée doit donc conserver un outcome durable associé conceptuellement à :
```text
input identity
processor identity
processor version
logical capability/output identity
attempt/provenance
outcome
timestamps
```
Outcomes conceptuels possibles :
```text
Produced
NoOutput
NotApplicable
Unsupported
FailedDeterministic
```
Les noms exacts restent ouverts.
Les erreurs transitoires ne doivent pas nécessairement devenir immédiatement un outcome terminal.
# Backlog par processor/version
La vérité du backlog n'est pas :
```text
"aucune row de sortie"
```
La vérité est conceptuellement :
```text
inputs applicables
MINUS
outcomes terminaux pour processor/version/capability cible
```
Ainsi :
```text
D1 X + CoreProcessor v1 -> Unsupported
```
est traité pour v1.
Plus tard :
```text
D1 X + CoreProcessor v2
```
constitue un nouveau travail si v2 a changé sa capability.
Pour D2 -> D3 et D3 -> D4, un même input peut être candidat pour plusieurs materializers/projectors. Le backlog existe donc séparément pour chaque identité/version/capability.
# Claim / lease
Pour supporter plusieurs instances concurrentes et la reprise après crash, un candidat peut être temporairement possédé :
```text
candidate
|
v
claim
|
v
lease(owner, expires_at)
|
v
process
|
v
complete
```
Si l'instance meurt :
```text
lease expires
|
v
candidate claimable again
```
La sémantique de claim appartient au contrat Store.
L'implémentation PostgreSQL choisira plus tard la technique SQL appropriée.
Le claim n'est pas une preuve de completion.
# Sémantique de livraison
KSP préfère :
```text
at-least-once processing
+
idempotent durable writes
+
durable outcomes
```
à une promesse distribuée `exactly-once`.
Après crash, un même input peut être retraité.
L'idempotence garantit que :
```text
same logical input
+ same processor/version
+ same logical output identity
```
ne crée pas un second fait logique incohérent.
# Atomicité de l'unité de traitement
Pour une unité logique de processing, doivent être cohérents/atomiques du point de vue durable :
```text
output(s)
processing outcome
notification request/publication contract
```
Un outcome `Completed/Produced` ne peut pas être durable si seule une partie des outputs obligatoires a été persistée.
L'unité atomique est généralement un input, sauf lorsqu'un projector définit explicitement un groupe indivisible.
La transaction backend concrète appartient à `ksp-store-lib`; le pipeline l'oriente via `ksp-store-api`.
# Erreurs de processing
Trois familles conceptuelles au minimum :
## Transient
Exemples :
- timeout ;
- backend temporairement indisponible ;
- rate limit ;
- ressource temporairement indisponible.
Traitement :
```text
retry + backoff
```
avec limite/configuration.
## Deterministic failure
Exemples :
- donnée malformée connue ;
- invariant impossible ;
- erreur de transformation reproductible.
Un état durable permet d'éviter une boucle infinie pour la même version.
## Not applicable / unsupported
Ce ne sont pas nécessairement des erreurs.
Ils constituent des outcomes terminaux pour la version/capability considérée et peuvent être réévalués avec une nouvelle version.
# Reprise après crash
Un worker/job de processing doit pouvoir suivre la séquence :
```text
restart
|
v
load configuration/scope
|
v
recover/ignore expired claims
|
v
query backlog from Store
|
v
resume processing
```
Aucune notification perdue pendant l'arrêt ne doit rendre la reprise impossible.
# Cursor et checkpoint
Un cursor peut accélérer le scan :
```text
last scanned slot
last durable id
last page
```
mais il ne prouve pas qu'un input a été traité.
Pour les workers de processing :
```text
durable processing outcomes = vérité
cursor = optimisation
```
Pour `ksp-job-backfill`, le checkpoint possède aussi une sémantique de progression dans la source externe.
# Replay normal et replay forcé
Deux intentions doivent être distinguées.
## Compléter/reprendre
Traiter uniquement ce qui manque/échoue selon le scope et la version cible.
## Force replay
Retraiter même si un résultat actuel existe.
Un force replay :
- ne supprime pas silencieusement l'historique ;
- conserve la provenance ;
- produit ou supersède les résultats selon les règles du niveau ;
- reste idempotent pour l'identité logique choisie.
Les règles SQL exactes seront fixées avec les premiers modèles D2/D3/D4.
# Notifications : mécanisme de référence
Le mécanisme initial de référence retenu pour PostgreSQL est :
```text
LISTEN / NOTIFY
```
sans en faire une garantie de livraison.
Le modèle attendu est :
```text
persist outputs/outcome
|
v
commit
|
v
NOTIFY / wake-up
```
L'implémentation exacte peut exploiter le comportement transactionnel PostgreSQL de notification.
Chaque consumer combine :
```text
notification wake-up
+
periodic backlog polling
```
Le polling périodique constitue le filet de sécurité.
Le contrat public reste dans `ksp-store-api` et ne dépend pas de PostgreSQL.
# Batching et concurrence
Un worker/job de processing peut suivre :
```text
claim bounded batch
|
v
process with bounded concurrency
|
v
persist outcomes
|
v
repeat
```
Paramètres potentiels :
- batch size ;
- max concurrency ;
- poll interval ;
- retry/backoff ;
- lease duration.
Ces paramètres ne sont pas nécessairement des champs universels de `ksp-worker-api` ou `ksp-job-api`.
Ils appartiennent au composant qui sait les interpréter.
# Backpressure
Un backlog croissant n'est pas automatiquement une erreur :
```text
D1 production rate > D2 processing rate
```
Le système doit pouvoir observer au minimum conceptuellement :
- backlog count ;
- âge du plus ancien input pending ;
- processing rate ;
- retry/failure rate ;
- état degraded éventuel.
Le raw retriever n'est pas automatiquement ralenti par un backlog downstream. D1 sert précisément de tampon durable permettant de préserver l'acquisition.
Une stratégie de backpressure globale pourra être décidée plus tard par un manager/orchestrateur ou une configuration produit.
# Logging
Tous les pipelines, workers et jobs runtime utilisent `ksp-logging-lib`.
Les logs doivent couvrir selon pertinence :
- lifecycle ;
- claims/releases ;
- batch start/end ;
- retries/backoff ;
- outcomes unsupported/not applicable ;
- failures ;
- checkpoints ;
- replay scopes ;
- hot reconfiguration ;
- divergences desired/effective ;
- notifications/polling.
Les secrets et données sensibles ne sont jamais loggés.
# Graphe de composition
## Raw live
```text
ksp-worker-raw-retriever
-> ksp-worker-api
-> ksp-pipeline-raw-ingestion-lib
-> ksp-onchain-transport-lib
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
## Backfill
```text
ksp-job-backfill
-> ksp-job-api
-> ksp-pipeline-raw-ingestion-lib
-> ksp-onchain-transport-lib
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
## Core live/replay
```text
ksp-worker-core-processor
ksp-job-replay-core
-> lifecycle API correspondant
-> ksp-pipeline-core-processing-lib
-> ksp-program-lib ou implémentation compatible
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
## Generic materialization live/replay
```text
ksp-worker-generic-materializer
ksp-job-replay-generic-materialization
-> lifecycle API correspondant
-> ksp-pipeline-generic-materialization-lib
-> ksp-materializer-lib ou implémentation compatible
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
## Domain projection live/replay
```text
ksp-worker-domain-projector
ksp-job-replay-domain-projection
-> lifecycle API correspondant
-> ksp-pipeline-domain-projection-lib
-> ksp-materializer-lib ou implémentation compatible
-> ksp-store-lib
-> ksp-config-lib
-> ksp-logging-lib
```
# Questions laissées ouvertes
Les premières implémentations doivent encore fixer :
- types Rust précis Worker/Job state, health et progress ;
- modèle SQL exact de claim/lease ;
- durée/renouvellement d'une lease ;
- granularité des transactions par frontière ;
- nombre de retries et politique de backoff ;
- conflict handling entre plusieurs processor implementations ;
- type exact des processing outcomes ;
- contexte déclarable d'un `DomainProjector` stateful ;
- stratégie de graceful shutdown d'un batch en cours ;
- politique précise de pause/resume des jobs ;
- métriques/export telemetry au-delà des logs et health.
`pre.008` doit maintenant se concentrer sur apps, managers, scenarios, processus/IPC et orchestration globale.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/001-V0_0_3_PLAN.md -->
<!-- version: 10 -->
<!-- version: 11 -->
# Plan KSP 0.0.3
@@ -13,7 +13,7 @@ Transformer le brainstorming KSP en architecture, règles, inventaire et plan su
- `pre.002` — inventaire initial des composants ;
- `pre.003` — graphe de dépendances, correction de l'inventaire et stabilisation des frontières de composition.
Les tranches `pre.004` (Wire/Program), `pre.005` (Execution/Policy) et `pre.006` (Data/Materialization/Store) sont maintenant livrées séparément afin de conserver des prereleases de planification bornées.
Les tranches `pre.004` (Wire/Program), `pre.005` (Execution/Policy), `pre.006` (Data/Materialization/Store) et `pre.007` (Acquisition/Workers/Jobs) sont maintenant livrées séparément afin de conserver des prereleases de planification bornées.
## Décisions structurantes actuelles
@@ -33,7 +33,8 @@ Les tranches `pre.004` (Wire/Program), `pre.005` (Execution/Policy) et `pre.006`
- `ksp-store-api` reste indépendant de Program/Materializer/Transport.
- Les workers/jobs spécialisés convertissent explicitement les modèles entre transport, processing et persistence.
- `ksp-store-api` possède les notifications canoniques de données persistées ; leur transport concret reste séparé.
- Aucun `ksp-data-api`, `ksp-pipeline-lib`, `ksp-scenario-api`, `ksp-onchain-transport-api`, `ksp-offchain-transport-api` ou `ksp-wallet-api` n'est prévu actuellement.
- Aucun `ksp-data-api`, `ksp-pipeline-lib` monolithique, `ksp-scenario-api`, `ksp-onchain-transport-api`, `ksp-offchain-transport-api` ou `ksp-wallet-api` n'est prévu actuellement.
- Quatre pipelines spécialisés sont désormais retenus pour les frontières durables : raw ingestion, Core processing, generic materialization et domain projection.
- Les scenarios restent des crates spécialisées régies d'abord par une norme souple.
## Prévision souple des prereleases restantes
@@ -101,15 +102,22 @@ Livré :
### `pre.007` — Acquisition, workers de processing et jobs
- détailler `ksp-worker-raw-retriever` ;
- détailler `ksp-worker-core-processor` ;
- détailler `ksp-worker-generic-materializer` ;
- détailler `ksp-worker-domain-projector` et réévaluer son nom ;
- détailler `ksp-job-backfill` ;
- définir les jobs de replay D1 -> D2, D2 -> D3, D3 -> D4 ;
- définir backlog/checkpoints/cursors ;
- traiter batching, concurrence, reprise et hot reconfiguration ;
- choisir le mécanisme de notification de référence sans en faire la source de vérité.
Livré :
- quatre pipelines spécialisés réutilisant chaque frontière durable entre worker live et job ;
- `ksp-worker-api` maintenu comme lifecycle API continue ;
- `ksp-job-api` maintenu comme lifecycle API terminable séparée ;
- `ksp-worker-raw-retriever` avec hot reconfiguration desired/effective ;
- `ksp-worker-core-processor`, `ksp-worker-generic-materializer`, `ksp-worker-domain-projector` ;
- `ksp-job-backfill` strictement D1 ;
- `ksp-job-replay-core`, `ksp-job-replay-generic-materialization`, `ksp-job-replay-domain-projection` ;
- backlog par input + processor/version/capability ;
- processing outcomes explicites même sans output ;
- claim/lease et reprise après crash ;
- at-least-once + idempotence ;
- replay normal vs force replay ;
- PostgreSQL LISTEN/NOTIFY comme wake-up initial de référence + periodic polling ;
- batching/concurrence bornés et principe de backpressure observable mais non automatique.
### `pre.008` — Applications, managers, scenarios et orchestration
@@ -118,13 +126,15 @@ Livré :
- définir la norme des crates scenario et leurs apps demo ;
- traiter les processus/IPC/managers ;
- cadrer l'orchestrateur futur ;
- inventorier les pipelines spécialisés réellement nécessaires.
- déterminer comment apps/managers pilotent workers et jobs sans fusionner leurs lifecycle APIs ;
- inventorier les autres pipelines spécialisés seulement si un besoin concret apparaît.
### `pre.009` — Plan des premières releases fonctionnelles
- transformer les séries `0.1.x+` en premières releases concrètes ;
- dimensionner chaque release concrète ;
- choisir la première release `0.1.N` ;
- vérifier l'ordre réel core/logging/config/interface/program/store/transport/workers sans introduire de dépendances circulaires ;
- transformer le brouillon de prompt en prompt quasi-final de cette release concrète.
### `pre.010` — Clôture fondatrice

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_DEPENDENCIES.md -->
<!-- version: 5 -->
<!-- version: 6 -->
# Règles des dépendances KSP
@@ -78,11 +78,25 @@ Elles complètent les règles Rust générales et le graphe de `docs/architectur
- **DEP-TRANSPORT-003** — Les modèles de transport ne réalisent pas de décodage métier/protocolaire et doivent rester facilement convertibles en DTO raw persistants.
- **DEP-TRANSPORT-004** — Aucun `ksp-onchain-transport-api` ou `ksp-offchain-transport-api` global n'est créé dans l'architecture actuelle.
## Pipelines spécialisés
- **DEP-PIPE-001** — KSP ne crée pas de `ksp-pipeline-lib` monolithique.
- **DEP-PIPE-002** — Les pipelines spécialisés retenus pour les frontières durables sont `ksp-pipeline-raw-ingestion-lib`, `ksp-pipeline-core-processing-lib`, `ksp-pipeline-generic-materialization-lib` et `ksp-pipeline-domain-projection-lib`.
- **DEP-PIPE-003** — Un pipeline de processing dépend des APIs nécessaires à sa frontière et non des implémentations officielles correspondantes lorsque l'API permet l'injection/composition.
- **DEP-PIPE-004** — Les pipelines spécialisés ne dépendent pas de `ksp-worker-api` ou `ksp-job-api`; worker et job possèdent le lifecycle.
- **DEP-PIPE-005** — Worker live et job de replay/backfill réutilisent le même pipeline pour une même frontière durable afin d'éviter la duplication de logique.
- **DEP-PIPE-006** — Le pipeline raw ingestion peut dépendre des modèles homogènes de `ksp-onchain-transport-lib` et de `ksp-store-api`, mais pas de `ksp-store-lib`.
- **DEP-PIPE-007** — Le pipeline Core processing dépend de `ksp-program-api` et non de `ksp-program-lib`.
- **DEP-PIPE-008** — Les pipelines de matérialisation/projection dépendent de `ksp-materializer-api` et non de `ksp-materializer-lib`.
## Worker / Job lifecycle
- **DEP-WORKER-001** — `ksp-worker-control-lib` dépend de `ksp-worker-api` et ne dépend pas de `ksp-job-api`.
- **DEP-WORKER-002** — Les workers de processing reconstruisent leur backlog depuis `ksp-store-api`/Store ; une notification ne suffit pas à prouver qu'un input a été traité.
- **DEP-WORKER-003** — Les workers concrets peuvent dépendre de `ksp-store-lib` et des implémentations officielles Program/Materializer nécessaires à la composition.
- **DEP-JOB-001** — `ksp-job-api` ne dépend ni de `ksp-worker-api` ni de `ksp-worker-control-lib`.
- **DEP-JOB-002** — Un orchestrateur futur peut consommer séparément les APIs/contrôles workers et jobs sans introduire un lifecycle parent commun.
- **DEP-JOB-003** — Les jobs de replay réutilisent les pipelines des workers correspondants au lieu de dupliquer la logique D1 -> D2, D2 -> D3 ou D3 -> D4.
## Propriété des dépendances Solana

View File

@@ -1,5 +1,5 @@
<!-- file: docs/rules/RULES_KSP.md -->
<!-- version: 10 -->
<!-- version: 11 -->
# Règles spécifiques à KSP
@@ -14,6 +14,7 @@
- **KSP-NAME-007** — Une démonstration se termine par `-demo`.
- **KSP-NAME-008** — Les crates Rust sont placées directement sous `crates/`.
- **KSP-NAME-009** — Une application desktop de scénario spécialisée suit la forme `ksp-app-scenario-<domain>-<environment>-desk-demo` lorsque l'environnement est imposé.
- **KSP-NAME-010** — Un pipeline spécialisé réutilisable se nomme `ksp-pipeline-<role>-lib`; aucun `ksp-pipeline-lib` générique n'est créé.
## Architecture et APIs
@@ -83,6 +84,18 @@
- **KSP-MAT-003** — Une extension externe de materializer doit pouvoir produire du D3 générique sans migration PostgreSQL spécialisée.
- **KSP-MAT-004** — Une nouvelle projection relationnelle D4 exige explicitement un contrat Store/migration/backend correspondant ; cette responsabilité n'est pas cachée dans `ksp-materializer-api`.
## Backlog, claims et reprise
- **KSP-PROC-001** — Le backlog est défini relativement à l'identité/version/capability du processor et non par simple absence d'une row de sortie.
- **KSP-PROC-002** — Une nouvelle version de processor peut rendre de nouveau candidat un input déjà terminal pour une version précédente.
- **KSP-PROC-003** — Un input peut avoir plusieurs outcomes indépendants lorsqu'il est candidat pour plusieurs materializers/projectors.
- **KSP-PROC-004** — Les claims sont temporaires ; une lease expirée après crash rend le candidat de nouveau traitable.
- **KSP-PROC-005** — Les erreurs transitoires utilisent retry/backoff borné ; les failures déterministes doivent pouvoir devenir un état durable afin d'éviter une boucle infinie.
- **KSP-PROC-006** — Unsupported/NotApplicable ne sont pas nécessairement des erreurs et constituent des outcomes terminaux pour la version/capability concernée.
- **KSP-PROC-007** — Les consumers combinent wake-up par notification et polling périodique du backlog.
- **KSP-PROC-008** — Un backlog downstream croissant n'entraîne pas automatiquement le ralentissement du raw retriever ; une éventuelle backpressure globale appartient à une policy/configuration/orchestration supérieure.
## Notifications de données persistées
- **KSP-NOTIFY-001** — `ksp-store-api` possède le format canonique d'une notification signalant qu'une donnée persistée est disponible.
@@ -102,6 +115,10 @@
- **KSP-WORKER-006** — `ksp-worker-raw-retriever` persiste les données raw puis notifie leur disponibilité selon les contrats de données normalisés.
- **KSP-WORKER-007** — `ksp-worker-raw-retriever` doit pouvoir faire évoluer à chaud les listeners et la sélection des données qu'il rapatrie/stocke.
- **KSP-WORKER-008** — Les workers de processing actuellement retenus sont `ksp-worker-core-processor`, `ksp-worker-generic-materializer` et `ksp-worker-domain-projector`; le dernier nom reste provisoire.
- **KSP-WORKER-009** — Les workers de processing utilisent notification comme wake-up mais reconstruisent leur backlog depuis le Store.
- **KSP-WORKER-010** — `ksp-worker-raw-retriever` distingue une configuration desired et une configuration effective lors des reconfigurations à chaud.
- **KSP-WORKER-011** — Un cursor de scan est une optimisation ; les processing outcomes durables constituent la preuve qu'un input a été traité pour un processor/version/capability.
- **KSP-WORKER-012** — La concurrence de processing utilise une sémantique de claim/lease récupérable après expiration/crash.
## Jobs
@@ -113,6 +130,10 @@
- **KSP-JOB-006** — D'autres jobs peuvent être introduits pour metadata, quotes ou autres travaux ponctuels lorsqu'un besoin réel le justifie.
- **KSP-JOB-007** — Aucune `ksp-job-control-lib` commune n'est prévue actuellement ; elle ne sera créée que si une duplication concrète entre plusieurs jobs le justifie.
- **KSP-JOB-008** — Le contrôle/gouvernance des jobs reste séparé du contrôle des workers.
- **KSP-JOB-009** — Les jobs de replay retenus sont `ksp-job-replay-core`, `ksp-job-replay-generic-materialization` et `ksp-job-replay-domain-projection`.
- **KSP-JOB-010** — Les jobs de replay réutilisent exactement le pipeline spécialisé de la frontière correspondante.
- **KSP-JOB-011** — Le backfill conserve un checkpoint de progression dans la source historique en plus des outcomes de persistence D1.
- **KSP-JOB-012** — Replay normal/reprise et force replay sont deux intentions distinctes ; un force replay conserve provenance/historique et ne supprime pas silencieusement le résultat courant.
## Matérialisation et persistence
@@ -130,7 +151,13 @@
## Pipelines et scénarios
- **KSP-PIPE-001** — KSP ne crée pas de `ksp-pipeline-lib` monolithique. Les pipelines sont introduits séparément à la demande selon leur responsabilité réelle.
- **KSP-PIPE-001** — KSP ne crée pas de `ksp-pipeline-lib` monolithique.
- **KSP-PIPE-002** — Les quatre pipelines spécialisés retenus pour les frontières durables sont raw ingestion, Core processing, generic materialization et domain projection.
- **KSP-PIPE-003** — Un pipeline spécialisé contient la logique réutilisable d'une frontière mais aucun lifecycle worker/job.
- **KSP-PIPE-004** — Les pipelines utilisent les APIs Program/Materializer/Store lorsque ces frontières doivent être injectables ; les implémentations officielles sont composées par workers/jobs.
- **KSP-PIPE-005** — Le traitement est at-least-once avec persistence idempotente et outcomes durables, plutôt qu'une promesse exactly-once distribuée.
- **KSP-PIPE-006** — Un traitement valide produisant zéro output possède malgré tout un outcome terminal explicite tel que NoOutput/NotApplicable/Unsupported selon la sémantique finale.
- **KSP-PIPE-007** — Outputs obligatoires et processing outcome d'une unité logique sont atomiques du point de vue durable.
- **KSP-SCENARIO-001** — Il n'existe pas de crate monolithique `ksp-scenarios-lib`.
- **KSP-SCENARIO-002** — Les scénarios sont séparés en crates `ksp-scenario-<domain>-lib` par responsabilité fonctionnelle cohérente.
- **KSP-SCENARIO-003** — `ksp-scenario-api` n'est pas retenu actuellement ; KSP privilégie d'abord une norme documentaire/structurelle commune qui ne limite pas les contrats spécifiques des scénarios.

View File

@@ -1,5 +1,5 @@
<!-- file: prompts/001-V0_1_X_START_PROMPT.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Prompt de démarrage KSP 0.1.x
@@ -33,7 +33,7 @@ Ces objectifs pourront être répartis entre plusieurs releases `0.1.N`.
## 5. Sources de vérité
Relire au minimum `RULES.md`, `ROADMAP.md`, `docs/000-README.md`, `docs/rules/PROMPT_STRUCTURE.md`, les documents d'architecture `001` à `008`, le plan de version actif et les questions pertinentes de `docs/IDEAS.md`.
Relire au minimum `RULES.md`, `ROADMAP.md`, `docs/000-README.md`, `docs/rules/PROMPT_STRUCTURE.md`, les documents d'architecture `001` à `009`, le plan de version actif et les questions pertinentes de `docs/IDEAS.md`.
## 6. Décisions acquises pertinentes