v0.3.11-pre.012

This commit is contained in:
2026-09-08 18:58:34 +02:00
parent 636a0c5f43
commit a8cabbebd5
13 changed files with 724 additions and 40 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 515
# version: 516
[workspace]
resolver = "3"
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
[workspace.package]
version = "0.3.11-pre.11"
version = "0.3.11-pre.12"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: README.md -->
<!-- version: 11 -->
<!-- version: 12 -->
# Khadhroony Solana Project
@@ -57,7 +57,7 @@ La couche RAW dispose d'une façade Store backend-neutral et d'un premier job hi
`ksp-worker-api` fournit désormais la fondation générique des services continus : identité Worker, lifecycle borné, health/activity, intention de stop coopératif et observation latest-value. Cette API reste Core-only, runtime-neutral et sans connaissance Solana, Transport, Store ou Job. Elle ne démarre ni n'arrête elle-même un runtime concret.
Le futur `ksp-worker-raw-transaction-ingest-lib` sera un consumer concret distinct du Job Backfill : il fonctionnera en continu entre Start et Stop, sans scope historique métier, afin d'acquérir et persister des `RawTransaction` selon les sources/capabilities configurées. `ksp-job-backfill-lib` conserve de son côté son rôle historique paramétré et borné. Les deux producteurs restent indépendants et convergent uniquement vers les mêmes contrats RAW/Store.
`ksp-worker-raw-transaction-ingest-lib` est désormais le premier Worker concret distinct du Job Backfill. Sa fondation source-neutral possède le lifecycle Start/Stop, l'admission bornée, la canonicalisation Common RAW, la persistance Store backend-neutral, le shutdown borné et les snapshots latest-value, mais aucune source réseau productive ni dépendance Transport. Les adapters live/catch-up seront ajoutés dans les tranches suivantes sans transformer le Worker en campagne historique. `ksp-job-backfill-lib` conserve de son côté son rôle historique paramétré et borné ; les deux producteurs restent indépendants et convergent uniquement vers les mêmes contrats RAW/Store.
## Points d'entrée

View File

@@ -0,0 +1,158 @@
<!-- file: crates/ksp-worker-raw-transaction-ingest-lib/README.md -->
<!-- version: 1 -->
# ksp-worker-raw-transaction-ingest-lib
`ksp-worker-raw-transaction-ingest-lib` est le premier Worker concret de KSP pour l'alimentation continue de la couche RAW Transaction.
La crate fournit la fondation runtime **source-neutral** du Worker : identité et settings bornés, lifecycle Start/Stop, admission privée bornée, canonicalisation via `ksp-raw-transaction-lib`, persistance backend-neutral via `ksp-store-lib`, supervision des tâches, shutdown borné et snapshots latest-value projetables sur `ksp-worker-api`.
La fondation ne contient volontairement encore **aucune source réseau productive**. Elle ne dépend pas de `ksp-onchain-transport-lib` et n'expose pas d'API publique permettant au caller d'injecter directement des transactions dans la queue interne. Les adapters live/catch-up sont des responsabilités ultérieures du même Worker, pas de son API de fondation.
## Identité et réseau
Une exécution est liée à :
```text
RawNetworkId
WorkerId
Worker kind = raw_transaction_ingest
```
Le réseau logique doit être identique à celui du `Store` remis au démarrage. La transaction canonique conserve l'identité durable définie par la couche RAW commune ; le Worker n'ajoute ni provider, ni endpoint, ni protocole à cette identité.
## Runtime
Le point d'entrée public est :
```text
RawTransactionIngestWorker::start(settings, Arc<Store>)
-> RawTransactionIngestHandle
```
Le démarrage est synchrone mais nécessite qu'un runtime Tokio courant appartienne déjà au caller. Le Worker ne crée pas de runtime global et n'expose aucun `JoinHandle` public.
`RawTransactionIngestHandle` permet de :
- demander un stop coopératif et idempotent ;
- obtenir une source de snapshots concrets latest-value ;
- utiliser cette même source via `WorkerSnapshotSource` ;
- attendre le terminal après drain/abort+join des tâches possédées.
La destruction du dernier handle de contrôle ferme aussi la voie de contrôle privée ; le runtime termine alors selon les mêmes règles de shutdown.
## Admission et Common RAW
La queue centrale est un `tokio::sync::mpsc` privé borné par `admission_queue_capacity`. Les sources internes doivent subir la backpressure du channel ; aucune queue non bornée ni silent drop n'est autorisé.
Chaque ingress admis est :
1. vérifié contre le réseau attendu ;
2. canonicalisé exclusivement par `ksp-raw-transaction-lib` ;
3. associé à une observation key déterministe sous le domaine `ksp.raw_transaction_ingest.observation.v1` ;
4. assemblé en acquisition RAW commune ;
5. remis à la persistence Store.
La crate ne possède pas un second format RAW et ne duplique pas le canonicaliseur commun.
## Persistence Store
La persistance passe uniquement par `ksp-store-lib` avec `default-features = false` dans la crate Worker. Aucun backend physique n'est imposé ou importé directement.
L'écriture utilise le mode normal d'acquisition atomique `RawTransaction + RawTransactionObservation`. Les outcomes distingués sont notamment :
```text
entity inserted
entity already present
entity skipped purged
observation inserted
observation already present
observation not recorded for purged entity
content conflict
store failure
```
`persistence_concurrency` borne le nombre d'écritures Store simultanées. Un conflit de contenu est terminal et n'est jamais converti en succès idempotent.
## Shutdown et faults
Le shutdown possède une deadline bornée par `shutdown_drain_timeout`.
Avant publication terminale, le supervisor :
- arrête les nouvelles admissions ;
- signale le stop aux sources privées ;
- draine le travail déjà admis tant que la deadline le permet ;
- récolte les persistences et sources possédées ;
- en cas de timeout, abort les tâches restantes puis les rejoint avant le terminal.
Les codes d'erreur publics du Worker sont :
```text
worker_raw_transaction_ingest.settings_invalid
worker_raw_transaction_ingest.runtime_invalid
worker_raw_transaction_ingest.store_failed
worker_raw_transaction_ingest.content_conflict
worker_raw_transaction_ingest.counter_exhausted
worker_raw_transaction_ingest.source_failed
worker_raw_transaction_ingest.drain_timeout
```
Les diagnostics ne recopient pas de payload RAW, URL, credential, signature hostile ou texte backend/provider arbitraire.
## Snapshots
`RawTransactionIngestSnapshotSource` est latest-value. Les listeners peuvent rater des états intermédiaires mais obtiennent toujours une valeur complète et monotone par `WorkerSnapshotSequence`.
Le snapshot concret expose notamment :
```text
lifecycle / health / activity
admission_queue_capacity / admission_queue_depth
persistence_concurrency / in_flight_persistence
admitted_total / canonicalized_total / persisted_total
entity_inserted_total / entity_already_present_total / entity_skipped_purged_total
observation_inserted_total / observation_already_present_total
content_conflict_total / store_failure_total / source_failure_total
backpressure_wait_total
```
Les compteurs ne wrapent jamais silencieusement.
## Dépendances
Les dépendances normales sont exactement :
```text
ksp-core-lib
ksp-logging-lib
ksp-raw-transaction-lib
ksp-store-lib (default-features = false)
ksp-worker-api
sha2
tokio (macros, rt, sync, time)
```
La crate ne dépend pas de Config, Job, `ksp-store-api` directement, backend Store concret, Transport, Tauri ou SDK provider.
## Hors périmètre de la fondation source-neutral
Cette surface ne possède pas encore :
- adapter HTTP/WS/Yellowstone productif ;
- sélection Config de sources/endpoints/credentials ;
- discovery/hydration/replay de continuité live ;
- hot reconfiguration de listeners/sources ;
- application Desk ou process autonome ;
- campagne historique/backfill ;
- décodage STRUCTURAL/DECODED/DOMAIN.
Ces extensions doivent conserver la séparation avec `ksp-job-backfill-lib` et réutiliser les mêmes contrats RAW/Store.
## Documentation
- [`USAGE.md`](USAGE.md) — utilisation de la façade publique actuelle ;
- [`../ksp-worker-api/README.md`](../ksp-worker-api/README.md) — contrats Worker génériques ;
- [`../ksp-raw-transaction-lib/README.md`](../ksp-raw-transaction-lib/README.md) — canonicalisation RAW commune ;
- [`../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md`](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md) — séparation Worker/Job ;
- [`../../docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md`](../../docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md) — architecture d'acquisition RawTransaction.

View File

@@ -0,0 +1,206 @@
<!-- file: crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md -->
<!-- version: 1 -->
# Utilisation de ksp-worker-raw-transaction-ingest-lib
Cette page décrit l'utilisation de la façade publique source-neutral de `ksp-worker-raw-transaction-ingest-lib`. Le caller possède la composition du runtime Tokio et du `Store` ; la crate Worker ne construit ni Config, ni backend physique, ni Transport.
## Construire les settings
Les identités sont validées par leurs couches propriétaires :
```rust
fn worker_settings() -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings> {
let network = match ksp_store_lib::RawNetworkId::new("mainnet") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
let worker_id = match ksp_worker_api::WorkerId::new("raw-ingest-mainnet-0001") {
std::result::Result::Ok(value) => value,
std::result::Result::Err(error) => return std::result::Result::Err(error),
};
return std::result::Result::Ok(ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings::with_defaults(
network,
worker_id,
));
}
```
Le Worker kind est fixe :
```rust
assert_eq!(
ksp_worker_raw_transaction_ingest_lib::RAW_TRANSACTION_INGEST_WORKER_KIND_CODE,
"raw_transaction_ingest",
);
```
Pour des limites explicites :
```rust
let settings = ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings::new(
network,
worker_id,
512,
16,
std::time::Duration::from_secs(10),
);
```
Bornes publiques :
```text
admission_queue_capacity 1 ..= 65_536 défaut 256
persistence_concurrency 1 ..= 64 défaut 8
shutdown_drain_timeout 100 ms ..= 30 s défaut 5 s
```
Une valeur hors borne retourne `worker_raw_transaction_ingest.settings_invalid` avec uniquement le nom stable du champ invalide.
## Démarrer sur le runtime du caller
`RawTransactionIngestWorker::start` doit être appelé depuis un contexte possédant déjà un runtime Tokio courant. Le `Store` est passé dans un `Arc` et doit cibler exactement le même `RawNetworkId` que les settings.
```rust
async fn start_worker(
settings: ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestSettings,
store: std::sync::Arc<ksp_store_lib::Store>,
) -> ksp_core_lib::Result<ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestHandle> {
return ksp_worker_raw_transaction_ingest_lib::RawTransactionIngestWorker::start(settings, store);
}
```
Le démarrage retourne avant la fin du Worker. Aucun `JoinHandle` Tokio n'est exposé au caller.
Un appel hors runtime Tokio courant retourne une erreur `worker_raw_transaction_ingest.runtime_invalid`. Un mismatch réseau Store/settings est également rejeté avant le spawn.
## Observer le snapshot concret
```rust
let source = handle.snapshot_source();
let current = source.current();
let sequence = current.worker_snapshot().sequence();
let state = current.worker_snapshot().state();
let queue_depth = current.admission_queue_depth();
let in_flight = current.in_flight_persistence();
```
Pour attendre une valeur plus récente :
```rust
let observed = source.current().worker_snapshot().sequence();
let newer = source.wait_for_change(observed).await;
assert!(newer.worker_snapshot().sequence().is_after(observed));
```
Le flux est latest-value : les transitions intermédiaires peuvent être coalescées. Ne pas l'utiliser comme journal d'événements exhaustif.
## Utiliser la projection Worker API
La même source implémente `ksp_worker_api::WorkerSnapshotSource` :
```rust
let source = handle.worker_snapshot_source();
let current = ksp_worker_api::WorkerSnapshotSource::current(&source);
let observed = current.sequence();
let newer = ksp_worker_api::WorkerSnapshotSource::wait_for_change(&source, observed).await;
assert!(newer.sequence().is_after(observed));
```
Cette projection commune ne contient que les dimensions génériques Worker. Les compteurs d'admission/persistence restent disponibles sur `RawTransactionIngestSnapshot`.
## Lire les compteurs concrets
Les compteurs principaux sont monotones :
```rust
let snapshot = handle.snapshot_source().current();
let admitted = snapshot.admitted_total();
let canonicalized = snapshot.canonicalized_total();
let persisted = snapshot.persisted_total();
let inserted = snapshot.entity_inserted_total();
let existing = snapshot.entity_already_present_total();
let purged = snapshot.entity_skipped_purged_total();
let observations = snapshot.observation_inserted_total();
let conflicts = snapshot.content_conflict_total();
let store_failures = snapshot.store_failure_total();
let source_failures = snapshot.source_failure_total();
let backpressure = snapshot.backpressure_wait_total();
```
`admission_queue_depth()` et `in_flight_persistence()` sont des gauges latest-value, pas des totaux cumulés.
L'épuisement d'un compteur ou de la séquence est terminal et utilise `worker_raw_transaction_ingest.counter_exhausted` au lieu de wrapper silencieusement.
## Demander un stop et attendre le terminal
```rust
let accepted = handle.request_stop();
let terminal = handle.wait_terminal().await;
match terminal {
std::result::Result::Ok(state) => {
assert!(state.is_terminal());
}
std::result::Result::Err(error) => return std::result::Result::Err(error),
}
if accepted {
// La première demande de stop a été remise au runtime vivant.
}
```
`request_stop()` est idempotent. Il exprime une intention coopérative ; le terminal n'est publié qu'après traitement du drain et des tâches possédées.
Le shutdown est borné par `shutdown_drain_timeout`. Si les tâches ne peuvent pas être drainées à temps, le Worker les abort puis les rejoint avant de publier `worker_raw_transaction_ingest.drain_timeout`.
## Interpréter les terminaux faultés
Les codes Worker publics sont :
```text
settings_invalid settings techniques hors contrat
runtime_invalid invariant runtime/lifecycle impossible
store_failed erreur Store non-conflict classifiée
content_conflict transaction canonique incompatible avec le contenu durable
counter_exhausted compteur/séquence monotone arrivé à sa borne
source_failed tâche source privée terminée en erreur
drain_timeout drain du shutdown hors deadline
```
Un consumer doit traiter le `ErrorCode` comme contrat stable et ne pas dépendre d'un texte backend/provider arbitraire.
## Frontière d'admission
La queue d'admission et le type ingress sont volontairement privés. La façade publique actuelle ne propose ni `send`, ni `enqueue`, ni registration d'un adapter réseau.
Les adapters d'acquisition qui alimentent cette queue appartiennent à l'implémentation du Worker et doivent conserver :
```text
backpressure mpsc bornée
stop prioritaire sur send bloqué
canonicalisation via ksp-raw-transaction-lib
persistance via ksp-store-lib
aucun backend physique direct
aucun provider dans l'identité canonique
```
Le caller ne doit pas contourner cette frontière en écrivant directement dans les structures privées du Worker.
## Composition supérieure
Le pattern de composition attendu reste :
```text
Config / application / service owner
-> construit le Store
-> choisit ultérieurement les sources/adapters supportés
-> construit RawTransactionIngestSettings
-> démarre RawTransactionIngestWorker
-> observe RawTransactionIngestSnapshotSource
-> demande stop lorsque nécessaire
```
Le Worker ne reçoit pas de requête historique métier. Une campagne `signature/program_id/plage/limite` appartient à `ksp-job-backfill-lib`, pas à ce runtime continu.

169
deltas/0.3.11/pre.012.md Normal file
View File

@@ -0,0 +1,169 @@
<!-- file: deltas/0.3.11/pre.012.md -->
<!-- version: 1 -->
# Delta `0.3.11-pre.012` — réconciliation documentaire finale
## 1. Base requise
```text
0.3.11-pre.011
```
Le gate technique final opérateur du 8 septembre 2026 est fermé avant cette tranche : rustfmt check, audits, `cargo check`, Clippy strict, 56 tests Worker, tests workspace all-targets/all-features, arbres Cargo Worker normal/features et `cargo tree --duplicates` ont été exécutés avec succès sur `0.3.11-pre.11`.
## 2. Objectif
`pre.012` est le couloir de réconciliation documentaire finale de `0.3.11`.
La tranche :
- transforme les README/USAGE du Worker en références durables ;
- remplace les formulations où le Worker était encore décrit comme futur ;
- distingue explicitement la fondation source-neutral matérialisée des sources live `0.3.12+` ;
- réaligne les graphes d'architecture sur l'absence réelle de Transport dans la fondation ;
- ferme plan et validation sur les preuves réellement exécutées ;
- ne finalise ni `CHANGELOG.md`, ni `ROADMAP.md`, ni le prompt `0.3.12`.
## 3. Version workspace
`pre.012` est documentaire mais n'est pas un fix. Le contrat Cargo KSP impose donc le bump prerelease mécanique :
```text
0.3.11-pre.11
->
0.3.11-pre.12
```
Aucun `Cargo.toml` de crate, edge de dépendance, feature, build setting, runtime ou configuration n'est modifié.
## 4. Contrat Worker documenté
La documentation durable fixe l'état actuel suivant :
```text
Worker concret ksp-worker-raw-transaction-ingest-lib
consumer de ksp-worker-api
settings réseau/Worker bornés
start/stop sur runtime Tokio caller-owned
supervision privée des tâches
mpsc central borné et backpressure
canonicalisation/assembly via ksp-raw-transaction-lib
observation key déterministe
persistence atomique via ksp-store-lib, mode Normal
concurrence Store bornée
snapshots latest-value concrets + WorkerSnapshotSource
classification settings/runtime/store/content/source/counter/drain
shutdown deadline + abort/join avant terminal timeout
```
La même documentation rend explicite ce qui n'appartient pas encore à la fondation :
```text
aucune source HTTP/WS/Yellowstone productive
aucun edge ksp-onchain-transport-lib
aucune lecture Config
aucun backend Store direct
aucune API publique enqueue/source registration
aucun replay/gap-repair live
aucune campagne historique/backfill
```
## 5. Graphe de dépendances réconcilié
Le graphe normal Worker confirmé par `pre.011` est documenté comme :
```text
ksp-worker-raw-transaction-ingest-lib
-> ksp-core-lib
-> ksp-logging-lib
-> ksp-raw-transaction-lib
-> ksp-store-lib # default-features = false
-> ksp-worker-api
-> sha2
-> tokio
```
L'edge Worker -> `ksp-onchain-transport-lib` reste réservé aux adapters live ultérieurs et n'est plus présenté comme une dépendance déjà matérialisée.
## 6. Fichiers ajoutés
```text
crates/ksp-worker-raw-transaction-ingest-lib/README.md
crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md
deltas/0.3.11/pre.012.md
```
## 7. Fichiers modifiés
```text
Cargo.toml
README.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/architecture/005-DEPENDENCY_GRAPH.md
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md
docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md
docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md
```
## 8. Fichiers supprimés
```text
aucun
```
## 9. Surfaces volontairement inchangées
```text
crates/ksp-worker-raw-transaction-ingest-lib/src/**
crates/ksp-worker-raw-transaction-ingest-lib/tests/**
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/**
crates/ksp-worker-raw-transaction-ingest-lib/Cargo.toml
CHANGELOG.md
ROADMAP.md
prompts/**
config/**
```
## 10. Validations exécutées pendant l'assemblage
Sur l'état exact destiné à l'archive :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (340 table(s), 795 file(s))
```
La revue de diff confirme également qu'aucun fichier `src/`, test, manifest de crate, Config, `CHANGELOG.md`, `ROADMAP.md` ou prompt n'est modifié.
## 11. Validations non exécutées dans l'environnement d'assemblage
L'environnement d'assemblage ne dispose pas de Cargo/Rustc. Les validations Cargo propres au delta restent donc opérateur :
```bash
cargo fmt --all -- --check
cargo check --workspace
cargo test -p ksp-worker-raw-transaction-ingest-lib
```
Le gate technique lourd (`clippy`, workspace all-targets/all-features, arbres Cargo) n'est pas rejoué car il appartient à `pre.011` et aucun code/test/dépendance/feature n'est modifié.
## 12. Décisions prises
- la fondation `0.3.11` est documentée comme Worker concret utilisable pour lifecycle/observabilité, mais sans source réseau productive ;
- l'admission reste privée : aucune API publique d'enqueue n'est inventée pour anticiper `0.3.12` ;
- les graphes séparent l'état matériel `0.3.11` du futur edge Transport ;
- le Job Backfill reste indépendant et historique ;
- `pre.013` reste seule propriétaire du prompt `0.3.12`, de `CHANGELOG.md` et de `ROADMAP.md`.
## 13. Questions ouvertes
```text
aucune question bloquante pour la clôture documentaire 0.3.11
```
Les choix précis de source/adapters live restent des décisions de `0.3.12+`, sans être figés par cette tranche documentaire.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
<!-- version: 37 -->
<!-- version: 38 -->
# Inventaire initial des composants KSP
@@ -45,8 +45,8 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse
| Backfill Desk | `ksp-app-backfill-desk` | app | Implémenté | `0.3.7`, extension `0.3.16` | contrôle du backfill RAW ; sélection des stratégies/sources ajoutée après le worker live |
| Store Desk | `ksp-app-store-desk` | app | Implémenté | `0.3.8` | inspection RAW read-only Transaction/Account/Observation via façade Store |
| RAW transaction common | `ksp-raw-transaction-lib` | lib | Implémenté | `0.3.10` | canonicalisation/wire RAW Transaction v1 source-neutral partagé entre producteurs |
| Worker lifecycle | `ksp-worker-api` | API | Retenu | `0.3.9` | lifecycle/health/progression génériques des services continus |
| RAW transaction worker | `ksp-worker-raw-transaction-ingest-lib` | worker/lib | Retenu | `0.3.11``0.3.14` | ingestion continue `RawTransaction` multi-source, déduplication/provenance/recovery |
| Worker lifecycle | `ksp-worker-api` | API | Implémenté | `0.3.9` | lifecycle/health/progression génériques des services continus |
| RAW transaction worker | `ksp-worker-raw-transaction-ingest-lib` | worker/lib | Implémenté | `0.3.11`, extensions `0.3.12+` | fondation source-neutral, puis sources live multi-source/recovery |
| RAW ingest Desk | `ksp-app-raw-transaction-ingest-desk` | app | Retenu | `0.3.15` | choix/supervision dune ou plusieurs sources/méthodes sans réimplémenter le worker |
| STRUCTURAL job | nom à fixer | job/lib | Retenu | couche STRUCTURAL | normalisation Solana générique RAW -> STRUCTURAL bornée/rejouable |
| STRUCTURAL worker | nom à fixer | worker/lib | Retenu | fin couche STRUCTURAL | backlog RAW -> STRUCTURAL continu |

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/005-DEPENDENCY_GRAPH.md -->
<!-- version: 26 -->
<!-- version: 27 -->
# Graphe de dépendances KSP
@@ -419,22 +419,22 @@ Il remplit RAW et ne décode aucun programme. Il ne dépend pas de Config : la c
ksp-worker-api
-> ksp-core-lib
ksp-worker-raw-transaction-ingest-lib
-> ksp-worker-api
-> ksp-onchain-transport-lib
-> ksp-raw-transaction-lib
-> ksp-store-lib
ksp-worker-raw-transaction-ingest-lib # fondation source-neutral matérialisée
-> ksp-core-lib
-> ksp-logging-lib
# Config reste possédé par la composition supérieure ; aucune dépendance backend/provider physique
-> ksp-raw-transaction-lib
-> ksp-store-lib # default-features = false ; aucun backend imposé
-> ksp-worker-api
-> sha2 / tokio # observation key + runtime privé
ksp-worker-control-lib
ksp-worker-control-lib # composant retenu, non matérialisé ici
-> ksp-worker-api
-> ksp-core-lib
```
`ksp-worker-api` est ouvert en `0.3.9` comme contrat générique de services continus et ne connaît ni Solana, ni Transport, ni Store, ni Tauri. Son premier consumer concret est prévu en `0.3.11` avec `ksp-worker-raw-transaction-ingest-lib`, puis ses sources live sont complées jusquen `0.3.14`.
`ksp-worker-api` est ouvert en `0.3.9` comme contrat générique de services continus et ne connaît ni Solana, ni Transport, ni Store, ni Tauri. `ksp-worker-raw-transaction-ingest-lib` est son premier consumer concret : sa fondation `0.3.11` est source-neutral, possède admission/persistence/snapshots/shutdown, et ne dépend pas encore de Transport. Les adapters live sont ajoutés ensuite sans déplacer Config ni backend physique dans le Worker.
Le worker RAW Transaction n'est pas défini comme « un worker WebSocket » ou « un worker gRPC ». Il reçoit une ou plusieurs stratégies d'acquisition construites au-dessus des façades KSP réellement disponibles ; celles-ci peuvent être alternatives, complémentaires (discovery + hydration), redondantes entre providers ou spécialisées live/catch-up/gap-repair. La transaction canonique reste identifiée indépendamment de la source et chaque acquisition utile conserve sa propre observation/provenance Store.
La cible live n'est pas « un worker WebSocket » ou « un worker gRPC ». Les tranches de sources peuvent ajouter `ksp-onchain-transport-lib` lorsque l'adapter productif le nécessite et composer des stratégies alternatives, complémentaires (discovery + hydration), redondantes entre providers ou spécialisées live/catch-up/gap-repair. La transaction canonique reste identifiée indépendamment de la source et chaque acquisition utile conserve sa propre observation/provenance Store.
RAW worker puis STRUCTURAL worker sont introduits à la fin de leur couche respective, lorsque persistence/backlog sont disponibles. Le traitement RAW -> STRUCTURAL borné est porté par un STRUCTURAL job distinct du service continu. Les workers DECODED/DOMAIN sont introduits avec les groupes Program concernés plutôt que tous anticipés en bloc.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md -->
<!-- version: 17 -->
<!-- version: 18 -->
# Acquisition, workers, jobs et pipelines spécialisés
@@ -102,6 +102,8 @@ ksp-worker-raw-transaction-ingest-lib
Sa responsabilité est l'acquisition **continue** de `RawTransaction` puis la persistance via `ksp-store-lib`. Il ne décode pas de Program, ne possède aucun SQL/backend physique et ne fait pas de la source réseau une partie de l'identité canonique de transaction.
La fondation matérialisée possède déjà le lifecycle continu, les settings techniques bornés, la queue d'admission privée bornée, la canonicalisation Common RAW, la persistance atomique backend-neutral, les snapshots latest-value et le shutdown borné. Elle ne possède encore aucune source réseau productive et n'a donc aucun edge Transport ; les adapters live/catch-up complètent ensuite ce même Worker sans ouvrir de second runtime parallèle.
Le modèle cible n'est pas :
```text
@@ -140,7 +142,7 @@ Le worker ne doit pas être réduit à un enum superficiel `Http | WebSocket | G
#### Résultat de l'audit `0.3.9`
L'audit exhaustif est synthétisé dans [`011-RAW_TRANSACTION_ACQUISITION.md`](011-RAW_TRANSACTION_ACQUISITION.md). Il confirme qu'un besoin d'acquisition Solana/provider ne remonte pas dans `ksp-worker-api` : le contrat générique reste fermé et le futur Worker concret porte ses propres capabilities de sources.
L'audit exhaustif est synthétisé dans [`011-RAW_TRANSACTION_ACQUISITION.md`](011-RAW_TRANSACTION_ACQUISITION.md). Il confirme qu'un besoin d'acquisition Solana/provider ne remonte pas dans `ksp-worker-api` : le contrat générique reste fermé et le Worker concret porte ses propres capabilities de sources, sans les ouvrir dans sa fondation source-neutral.
Les familles admises par la synthèse couvrent notamment :
@@ -479,14 +481,24 @@ Le Job conserve seul ses scopes, campagnes, checkpoints et lifecycle.
### RAW worker
Fondation source-neutral matérialisée :
```text
ksp-worker-raw-transaction-ingest-lib
-> ksp-core-lib
-> ksp-worker-api
-> ksp-onchain-transport-lib
-> ksp-raw-transaction-lib
-> ksp-interface-lib # seulement si un fait passif partagé aide réellement la composition live
-> ksp-store-lib # façade Store ; aucun backend physique direct
-> ksp-store-lib # façade Store ; default-features=false ; aucun backend physique direct
-> ksp-logging-lib
-> sha2 / tokio # observation key + runtime privé
```
Extension live ultérieure :
```text
ksp-worker-raw-transaction-ingest-lib
-> ksp-onchain-transport-lib # seulement lorsque les adapters sources productifs sont matérialisés
-> ksp-interface-lib # seulement si un fait passif partagé aide réellement la composition live
composition supérieure / future Desk
-> ksp-config-lib
@@ -495,7 +507,7 @@ composition supérieure / future Desk
-> ksp-store-lib
```
Le Worker conserve seul son runtime continu, ses sources actives, sa continuité et son lifecycle. Il n'appelle ni ne pilote le Job Backfill.
Le Worker conserve seul son runtime continu, ses sources actives lorsqu'elles existent, sa continuité et son lifecycle. Il n'appelle ni ne pilote le Job Backfill. La fondation n'expose aucun ingress public : les sources internes futures alimentent la queue bornée et subissent sa backpressure.
Les événements Interface peuvent servir de signal provider-neutral à la composition live, mais ne constituent jamais le backlog durable. Après crash ou perte d'un événement, la reprise s'appuie sur Store et sur les primitives de replay/hydratation appropriées.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md -->
<!-- version: 14 -->
<!-- version: 15 -->
# Applications, services, scenarios et control plane
@@ -138,7 +138,7 @@ Backfill Desk suit exactement cette règle : elle ouvre Store via `ksp-store-lib
Store Desk suit la même frontière sans Transport : Config sélectionne Logging + Store, `ksp-store-lib` fournit health, reads et inspection backend-neutral, et le Store ouvert reste côté Rust. Les DataTables frontend consomment des summaries server-side et counts exacts ; les détails chargent une seule entité avec preview bornée. Aucun command d'écriture, SQL, cursor opaque, backend physique ou secret Store n'est exposé à Tauri/TypeScript.
Raw Transaction Ingest Desk est la surface spécialisée de contrôle prévue après le premier worker concret. Elle peut sélectionner une ou plusieurs stratégies compatibles et afficher lifecycle/health/rates/backpressure/reconnect/recovery, mais la sélection d'une source ne déplace ni discovery, ni hydration, ni déduplication, ni provenance dans l'application. Les endpoints/credentials restent Config/Transport-owned et le détail des entités persistées reste Store Desk-owned.
Raw Transaction Ingest Desk est la surface spécialisée de contrôle prévue après la fondation du premier worker concret. Cette fondation expose déjà lifecycle, stop et snapshots source-neutral ; la Desk ne doit cependant sélectionner des sources ou afficher reconnect/recovery qu'après matérialisation des adapters live correspondants. La sélection d'une source ne déplace ni discovery, ni hydration, ni déduplication, ni provenance dans l'application. Les endpoints/credentials restent Config/Transport-owned et le détail des entités persistées reste Store Desk-owned.
Les couches N1N4 expriment des responsabilités et une direction de dépendances ; elles n'imposent pas de traverser toutes les couches intermédiaires.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md -->
<!-- version: 11 -->
<!-- version: 12 -->
# Acquisition et alimentation `RawTransaction`
@@ -149,7 +149,7 @@ Il peut utiliser **HTTP, WS, Yellowstone gRPC, replay provider ou archive** si c
### 3.2 Worker Raw Transaction Ingest : acquisition continue start/stop
`ksp-worker-raw-transaction-ingest-lib` a pour rôle de **remplir continuellement Store à partir du moment où il est démarré**.
`ksp-worker-raw-transaction-ingest-lib` a pour rôle cible de **remplir continuellement Store à partir du moment où il est démarré**. Sa fondation source-neutral matérialise déjà le runtime, l'admission, la canonicalisation Common RAW, la persistence et les snapshots, mais aucune source réseau productive n'est encore branchée.
Son contrôle métier V1 est volontairement court :
@@ -161,17 +161,17 @@ snapshot / notifications
Le caller ne lui fournit pas une signature, un `program_id`, une plage historique, une limite de campagne ou une requête de backfill. Les endpoints, réseaux, sources activées, capabilities et secrets proviennent de Config/composition, pas d'un payload métier de `start`.
À partir de son démarrage, le Worker :
La fondation actuelle, lorsqu'elle démarre sans adapter source productif, publie son lifecycle/snapshot puis reste contrôlable jusqu'au stop. Dès qu'une source interne est matérialisée, le pipeline cible devient :
```text
acquiert les nouvelles transactions disponibles
hydrate les signaux live incomplets si nécessaire
normalise puis persiste RawTransaction + observations
publie ses notifications indépendamment de leurs lecteurs
publie ses snapshots latest-value indépendamment de leurs lecteurs
continue jusqu'à stop ou fault
```
Le Worker peut utiliser **WS, Yellowstone gRPC, HTTP, block polling, provider streams ou sources EARLY** si ces capacités servent l'acquisition live.
Le Worker peut ensuite utiliser **WS, Yellowstone gRPC, HTTP, block polling, provider streams ou sources EARLY** si ces capacités servent l'acquisition live. Ces sources restent internes au Worker ; le caller ne pousse pas directement des ingress dans sa queue privée.
Il ne lance pas de campagne historique arbitraire.
@@ -648,7 +648,7 @@ Worker lifecycle
backend Store physique
```
Graphe conceptuel :
Graphe matérialisé après la fondation Worker :
```text
ksp-job-backfill-lib --------------------> ksp-raw-transaction-lib ----> ksp-store-api
@@ -657,12 +657,14 @@ ksp-worker-raw-transaction-ingest-lib ---> ksp-raw-transaction-lib ----> ksp-sto
ksp-job-backfill-lib --------------------> ksp-store-lib
ksp-worker-raw-transaction-ingest-lib ---> ksp-store-lib
ksp-job-backfill-lib --------------------> ksp-onchain-transport-lib
ksp-worker-raw-transaction-ingest-lib ---> ksp-onchain-transport-lib
ksp-worker-raw-transaction-ingest-lib -X-> ksp-onchain-transport-lib # aucun adapter live productif encore
aucun edge Job <-> Worker
aucun edge Transport <-> ksp-raw-transaction-lib
```
Les tranches live suivantes peuvent matérialiser l'edge Worker -> Transport lorsqu'un adapter source productif le nécessite ; cet edge n'appartient pas à la fondation source-neutral.
La migration doit préserver exactement les golden bytes/hash RAW v1 déjà prouvés. Aucun RAW v2 n'est justifié.
### 13.1 Transaction wire Legacy/V0/V1
@@ -711,9 +713,40 @@ Yellowstone Transaction/Block -> signal structuré + transaction wire fidèle
RAW v1 complet -> hydration HTTP avant persistence
```
Aucun adapter productif n'est ajouté en `pre.006`. Conformément à `TR-C2`, l'adapter `Transport DTO -> common` demeure réservé au Worker concret, désormais ouvert en `0.3.11`.
Aucun adapter productif n'est ajouté par la qualification cross-source. Conformément à `TR-C2`, l'adapter `Transport DTO -> common` demeure réservé au Worker concret. La fondation `0.3.11` est désormais matérialisée sans Transport ; le premier adapter productif reste donc une responsabilité des tranches live suivantes.
## 14. Handoff Worker live `0.3.11` à `0.3.14`
## 14. Handoff fondation Worker `0.3.11` vers live `0.3.12` à `0.3.14`
### 14.0 État fermé par la fondation source-neutral
La fondation du Worker est matérialisée avec :
```text
consumer de ksp-worker-api
settings réseau/Worker bornés
start/stop sur runtime Tokio caller-owned
supervision privée des tâches
mpsc central borné + backpressure
canonicalisation et assembly via ksp-raw-transaction-lib
observation key déterministe
persistence atomique via ksp-store-lib en mode Normal
concurrence Store bornée
snapshots concrete + projection WorkerSnapshotSource
faults Store/content/source/counter classifiés
shutdown deadline + abort/join sans tâche orpheline
```
Elle ne possède encore :
```text
aucun adapter HTTP/WS/Yellowstone productif
aucun edge ksp-onchain-transport-lib
aucune lecture Config
aucune API publique d'enqueue/source registration
aucun replay/gap-repair live
```
Cette frontière est volontaire : les tranches live ajoutent des sources au supervisor existant au lieu d'introduire un second runtime ou une API d'admission publique.
### 14.1 Contrat fonctionnel
@@ -937,7 +970,8 @@ Transaction V1 = wire source-neutral Legacy/V0/V1 dans common ; ac
Yellowstone pre.006 = transaction wire V1 qualifié ; RAW complet via hydration HTTP
TR-C2 = adapter productif Transport DTO -> common réservé au Worker concret
0.3.10 = common RAW + preuves cross-source
0.3.11 à 0.3.14 = Worker live multi-source par responsabilités bornées
0.3.11 = fondation Worker source-neutral, persistence et observabilité
0.3.12 à 0.3.14 = sources live multi-source, continuité et hardening par responsabilités bornées
0.3.16 = Job Backfill multi-stratégie historique
```

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 97 -->
<!-- version: 98 -->
# Séquence des releases fonctionnelles KSP
@@ -582,7 +582,8 @@ La séquence effective a évolué par sizing et validation réels. La référenc
0.3.8 ksp-app-store-desk RAW
0.3.9 ksp-worker-api + audit acquisition RawTransaction
0.3.10 common ksp-raw-transaction-lib + preuves cross-source
0.3.11-0.3.14 Worker RAW ingest découpé par responsabilité
0.3.11 fondation source-neutral ksp-worker-raw-transaction-ingest-lib
0.3.12-0.3.14 sources live, convergence et continuité Worker RAW ingest
0.3.15 ksp-app-raw-transaction-ingest-desk
0.3.16 Backfill multi-source / multi-stratégie
```

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md -->
<!-- version: 11 -->
<!-- version: 12 -->
# Plan v0.3.11 — fondation runtime du Worker RawTransaction ingest
@@ -756,12 +756,14 @@ Budget cible : **1015 min**. Tests externes exacts : API root, dependencies,
Budget cible : **1015 min**. Workspace tests/all-features, Clippy strict, suites ciblées, arbres normal/features, duplicate tree. Aucun nouveau scope fonctionnel.
État après matérialisation : **delta de gate préparé, validation opérateur requise**. Aucun code, test, manifest de crate, dépendance ou feature nest modifié. La tranche ne fait que porter le workspace en `0.3.11-pre.11`, enregistrer la clôture de `pre.010-fix.001` et demander le gate technique final workspace prévu par la validation, y compris les arbres Cargo Worker normal/features et `cargo tree --duplicates`.
État après matérialisation : **gate technique final opérateur validé**. Aucun code, test, manifest de crate, dépendance ou feature na été modifié. Le gate communiqué le 8 septembre 2026 est vert sur rustfmt check, audits Rust/Markdown, `cargo check --workspace`, Clippy strict, 56 tests Worker, `cargo test --workspace --all-targets --all-features`, les arbres Cargo Worker normal/features et `cargo tree --duplicates`. Le graphe normal Worker confirme l'absence de Transport/backend direct ; l'inventaire global de duplicates n'a révélé aucun nouvel edge/version imputable à cette tranche mécanique.
### `pre.012` — réconciliation documentaire
Budget cible : **1015 min**. README/USAGE Worker, plan, validation et architecture/références réellement affectées. Aucun CHANGELOG/ROADMAP/prompt suivant.
État après matérialisation : **réconciliation documentaire candidate préparée avec le bump prerelease mécanique `0.3.11-pre.12`**. `README.md` racine et les références architecture réellement affectées distinguent désormais explicitement la fondation source-neutral matérialisée des sources live `0.3.12+`; les nouveaux README/USAGE de la crate documentent uniquement la surface publique et les invariants d'utilisation actuels. Aucun code, test, manifest de crate, `CHANGELOG.md`, `ROADMAP.md` ou prompt suivant n'est modifié.
### `pre.013` — préparation publication
Budget cible : **510 min**. Prompt `0.3.12`, CHANGELOG, ROADMAP, Cargo/delta mécaniques uniquement.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md -->
<!-- version: 14 -->
<!-- version: 15 -->
# Validation v0.3.11 — fondation runtime du Worker RawTransaction ingest
@@ -1565,3 +1565,105 @@ Critère de passage : tous les audits, checks, Clippy, suites Worker et workspac
Si ce gate est vert, `pre.012` peut commencer la réconciliation documentaire uniquement. Toute correction technique révélée ici doit rester un `pre.011-fix.NNN` avant de passer à la documentation.
## 23. `pre.012` — réconciliation documentaire finale
### 23.1 Clôture opérateur de `pre.011`
Le gate technique final communiqué le 8 septembre 2026 est vert sur `0.3.11-pre.11` :
```text
cargo fmt --all -- --check: PASS
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (340 table(s), 792 file(s))
cargo check --workspace: PASS
cargo clippy --workspace --all-targets --all-features -- -D warnings: PASS
cargo test -p ksp-worker-raw-transaction-ingest-lib: PASS (56 tests)
cargo test --workspace --all-targets --all-features: PASS
cargo tree Worker --edges normal: exécuté
cargo tree Worker -e features: exécuté
cargo tree --duplicates: exécuté
```
Le graphe normal du Worker confirme les dépendances normales attendues :
```text
ksp-core-lib
ksp-logging-lib
ksp-raw-transaction-lib
ksp-store-lib
ksp-worker-api
sha2
tokio
```
Aucun `ksp-onchain-transport-lib`, backend Store direct, Config, Job ou SDK provider n'appartient au graphe normal du Worker. Le graphe features ne force pas la feature backend PostgreSQL de `ksp-store-lib`. `cargo tree --duplicates` expose des doublons workspace/transitifs déjà présents dans l'écosystème global ; `pre.011` n'ajoute aucune dépendance et n'introduit donc aucun nouveau duplicate par cette tranche mécanique.
La validation technique de la fondation `0.3.11` est fermée.
### 23.2 Références durables réconciliées
La tranche documentaire aligne les références suivantes sur l'état réellement validé :
```text
README.md
crates/ksp-worker-raw-transaction-ingest-lib/README.md
crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/architecture/005-DEPENDENCY_GRAPH.md
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md
docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md
docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md
docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md
docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md
```
Contrats réconciliés :
```text
Worker concret matérialisé, plus futur hypothétique
fondation 0.3.11 explicitement source-neutral
aucune source live ni edge Transport productif dans la fondation
admission mpsc privée et bornée
Common RAW unique pour canonicalisation/assembly
Store façade backend-neutral, mode Normal, concurrence bornée
snapshots latest-value concrets + projection Worker API
shutdown borné avec abort+join avant terminal timeout
séparation stricte Worker continu / Job Backfill historique
sources live et continuité reportées aux tranches 0.3.12+
```
### 23.3 Frontière documentaire
`pre.012` est strictement documentaire sur le fond, mais reste une prerelease non-fix. Conformément à `FILE_CONTRACTS.md`, `workspace.package.version` passe mécaniquement de `0.3.11-pre.11` à `0.3.11-pre.12`. Aucun changement code/build/runtime/configuration/migration n'est introduit ; aucun `Cargo.toml` de crate ne change.
La tranche ne modifie pas :
```text
CHANGELOG.md
ROADMAP.md
prompt 0.3.12
code Rust
tests
Cargo.toml de crate
configuration runtime
```
Ces surfaces de publication restent réservées à `pre.013`. Si un défaut technique est découvert après cette réconciliation, il ne doit pas être glissé dans `pre.012-fix.NNN` : le couloir technique approprié doit être rouvert puis la réconciliation documentaire rejouée.
### 23.4 Gate documentaire de `pre.012`
Le gate de cette tranche reste réduit à la réconciliation documentaire et aux validations minimales imposées par le bump prerelease mécanique :
```bash
cargo fmt --all -- --check
python3 scripts/audit_rust_workspace_rules.py
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
cargo check --workspace
cargo test -p ksp-worker-raw-transaction-ingest-lib
```
Aucun nouveau `cargo tree`, Clippy workspace ou `cargo test --workspace` n'est requis : le gate technique final `pre.011` possède déjà ces preuves et aucun code, test, dépendance ou feature n'est modifié par `pre.012`.