From a8cabbebd5f22911de7ca7d7728ddf1218336bbd Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Tue, 8 Sep 2026 18:58:34 +0200 Subject: [PATCH] v0.3.11-pre.012 --- Cargo.toml | 4 +- README.md | 4 +- .../README.md | 158 ++++++++++++++ .../USAGE.md | 206 ++++++++++++++++++ deltas/0.3.11/pre.012.md | 169 ++++++++++++++ docs/architecture/004-COMPONENT_INVENTORY.md | 6 +- docs/architecture/005-DEPENDENCY_GRAPH.md | 20 +- .../009-ACQUISITION_WORKERS_AND_JOBS.md | 24 +- ...010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md | 4 +- .../011-RAW_TRANSACTION_ACQUISITION.md | 54 ++++- docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md | 5 +- ...ANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md | 6 +- ...AW_TRANSACTION_INGEST_WORKER_FOUNDATION.md | 104 ++++++++- 13 files changed, 724 insertions(+), 40 deletions(-) create mode 100644 crates/ksp-worker-raw-transaction-ingest-lib/README.md create mode 100644 crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md create mode 100644 deltas/0.3.11/pre.012.md diff --git a/Cargo.toml b/Cargo.toml index d466eba..e9b10ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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" diff --git a/README.md b/README.md index 725c1a6..8729c59 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ - + # 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 diff --git a/crates/ksp-worker-raw-transaction-ingest-lib/README.md b/crates/ksp-worker-raw-transaction-ingest-lib/README.md new file mode 100644 index 0000000..92caca2 --- /dev/null +++ b/crates/ksp-worker-raw-transaction-ingest-lib/README.md @@ -0,0 +1,158 @@ + + + +# 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) + -> 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. diff --git a/crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md b/crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md new file mode 100644 index 0000000..6650aa1 --- /dev/null +++ b/crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md @@ -0,0 +1,206 @@ + + + +# 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 { + 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_core_lib::Result { + 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. diff --git a/deltas/0.3.11/pre.012.md b/deltas/0.3.11/pre.012.md new file mode 100644 index 0000000..5f3dbbb --- /dev/null +++ b/deltas/0.3.11/pre.012.md @@ -0,0 +1,169 @@ + + + +# 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. diff --git a/docs/architecture/004-COMPONENT_INVENTORY.md b/docs/architecture/004-COMPONENT_INVENTORY.md index 04e41b4..e67d089 100644 --- a/docs/architecture/004-COMPONENT_INVENTORY.md +++ b/docs/architecture/004-COMPONENT_INVENTORY.md @@ -1,5 +1,5 @@ - + # 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 d’une 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 | diff --git a/docs/architecture/005-DEPENDENCY_GRAPH.md b/docs/architecture/005-DEPENDENCY_GRAPH.md index e92a069..ca62761 100644 --- a/docs/architecture/005-DEPENDENCY_GRAPH.md +++ b/docs/architecture/005-DEPENDENCY_GRAPH.md @@ -1,5 +1,5 @@ - + # 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étées jusqu’en `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. diff --git a/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md b/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md index f24f9e4..510a807 100644 --- a/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md +++ b/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md @@ -1,5 +1,5 @@ - + # 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. diff --git a/docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md b/docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md index 27ff773..0926b1a 100644 --- a/docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md +++ b/docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md @@ -1,5 +1,5 @@ - + # 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 N1–N4 expriment des responsabilités et une direction de dépendances ; elles n'imposent pas de traverser toutes les couches intermédiaires. diff --git a/docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md b/docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md index c1a882e..186ee36 100644 --- a/docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md +++ b/docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md @@ -1,5 +1,5 @@ - + # 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 ``` diff --git a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md index 34edcf2..ed362ae 100644 --- a/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md +++ b/docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md @@ -1,5 +1,5 @@ - + # 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 ``` diff --git a/docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md b/docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md index 0a9da64..da82126 100644 --- a/docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md +++ b/docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md @@ -1,5 +1,5 @@ - + # Plan v0.3.11 — fondation runtime du Worker RawTransaction ingest @@ -756,12 +756,14 @@ Budget cible : **10–15 min**. Tests externes exacts : API root, dependencies, Budget cible : **10–15 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 n’est 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 n’a é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 : **10–15 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 : **5–10 min**. Prompt `0.3.12`, CHANGELOG, ROADMAP, Cargo/delta mécaniques uniquement. diff --git a/docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md b/docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md index daa50d8..92ca881 100644 --- a/docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md +++ b/docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md @@ -1,5 +1,5 @@ - + # 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`. +