diff --git a/Cargo.toml b/Cargo.toml index d295fa6..9cbb9ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 412 +# version: 413 [workspace] resolver = "3" members = ["crates/ksp-app-config-desk", "crates/ksp-app-solprices-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-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"] [workspace.package] -version = "0.3.6-pre.11" +version = "0.3.6-pre.12" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/README.md b/README.md index f768a6e..31c85f6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ - + # Khadhroony Solana Project @@ -47,6 +47,12 @@ Les besoins du trading constituent une priorité produit à court terme mais ne - Aucun `rust-toolchain.toml` n'est utilisé. - Les environnements et contraintes des démonstrations doivent être visibles dans leur nomenclature lorsqu'ils ne sont pas sélectionnables. +## Fondations opérationnelles actuelles + +La couche RAW dispose d'une façade Store backend-neutral et d'un premier job historique concret. `ksp-job-api` porte les contrats passifs communs des jobs bornés ; `ksp-job-backfill-lib` compose Transport observé et Store pour découvrir, hydrater et persister des transactions historiques RAW avec concurrence bornée, checkpoint contigu caller-owned, annulation coopérative et snapshots latest-value. + +Ces contrats restent distincts des futurs workers continus : un job borné n'est ni un service worker ni un pipeline générique imposé aux autres couches. + ## Points d'entrée - [`RULES.md`](RULES.md) — index des règles normatives ; diff --git a/crates/ksp-job-api/README.md b/crates/ksp-job-api/README.md new file mode 100644 index 0000000..9206cab --- /dev/null +++ b/crates/ksp-job-api/README.md @@ -0,0 +1,72 @@ + + + +# ksp-job-api + +`ksp-job-api` fournit les contrats passifs et runtime-neutral communs aux jobs bornés de KSP. + +La crate possède l'identité logique d'un job, son lifecycle terminable, l'intention d'annulation coopérative et le contrat latest-value utilisé pour observer un snapshot complet. Elle ne possède aucun runtime concret, aucune politique métier de backfill, aucun Transport, aucun Store et aucun Worker. + +## Responsabilités + +La façade crate-root expose : + +- `JobId` et `JobKindCode`, bornés et validés ; +- `JobState` et `JobCompletion` ; +- `JobLifecycle`, propriétaire des transitions admises ; +- `JobCancellationToken`, cloneable et idempotent ; +- `JobNotificationSequence`, strictement monotone et sans wrap silencieux ; +- `JobNotification`, valeur observable complète à une position donnée ; +- `JobSnapshotSource`, contrat runtime-neutral de lecture courante et attente d'une valeur plus récente ; +- les codes d'erreur Job et les types `Error`/`Result` communs de Core. + +## Lifecycle + +Le lifecycle admis reste explicitement borné : + +```text +Created + | | +----------------------> Cancelled + v +Running + | | +----> Cancelling -----> Cancelled + | | | | +---------> Failed + | +-------------> Completed(Complete|Partial) + | + +------------------------> Completed(Complete|Partial) + +------------------------> Failed +``` + +Tout état terminal est immuable. Une transition invalide retourne `ERROR_CODE_JOB_TRANSITION_INVALID` sans modifier l'état source. + +## Observation latest-value + +`JobSnapshotSource` n'impose ni callback, ni queue d'événements, ni runtime async particulier. Un listener peut : + +1. lire la valeur complète courante ; +2. mémoriser sa `JobNotificationSequence` ; +3. attendre une valeur plus récente ; +4. recevoir directement la dernière valeur complète, même si plusieurs mises à jour intermédiaires ont été coalescées. + +Le snapshot concret appartient au job qui implémente la source. `ksp-job-api` ne connaît pas son contenu. + +## Annulation + +`JobCancellationToken` représente uniquement une intention coopérative partagée. Il ne tue pas une tâche, n'annule pas une I/O par lui-même et ne décide pas du résultat terminal. Le runtime concret reste responsable d'observer le token aux frontières sûres et de publier son état final. + +## Firewall + +La dépendance normale est volontairement minimale : + +```text +ksp-job-api + -> ksp-core-lib +``` + +La crate ne dépend pas de Tokio, Futures, Transport, Store, Config, Logging, serde ni d'une crate de job concret. + +## Documentation + +- [`USAGE.md`](USAGE.md) — utilisation durable des contrats Job ; +- [`../../docs/architecture/003-COMPONENT_CONTRACTS.md`](../../docs/architecture/003-COMPONENT_CONTRACTS.md) — contrats de composants ; +- [`../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md`](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md) — séparation workers/jobs et premier backfill RAW. diff --git a/crates/ksp-job-api/USAGE.md b/crates/ksp-job-api/USAGE.md new file mode 100644 index 0000000..5bba28f --- /dev/null +++ b/crates/ksp-job-api/USAGE.md @@ -0,0 +1,141 @@ + + + +# Utilisation de ksp-job-api + +Cette page décrit la façade publique durable de `ksp-job-api`. Les consumers utilisent uniquement les exports du crate-root. + +## Construire une identité de job + +```rust +fn job_identity() -> ksp_job_api::Result<(ksp_job_api::JobId, ksp_job_api::JobKindCode)> { + let id = match ksp_job_api::JobId::new("raw-backfill-mainnet-0001") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + let kind = match ksp_job_api::JobKindCode::new("raw_transaction_backfill") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + return std::result::Result::Ok((id, kind)); +} +``` + +`JobId` identifie un job logique et ses reprises contrôlées. `JobKindCode` identifie une famille de jobs. Les deux sont bornés et utilisent un alphabet sûr ; leur `Debug` n'est pas une surface destinée à transporter un payload métier. + +## Piloter un lifecycle passif + +```rust +fn lifecycle(id: ksp_job_api::JobId, kind: ksp_job_api::JobKindCode) -> ksp_job_api::Result { + let mut lifecycle = ksp_job_api::JobLifecycle::new(id, kind); + if let std::result::Result::Err(error) = lifecycle.start() { + return std::result::Result::Err(error); + } + if let std::result::Result::Err(error) = lifecycle.complete(ksp_job_api::JobCompletion::Complete) { + return std::result::Result::Err(error); + } + return std::result::Result::Ok(lifecycle); +} +``` + +Le producer ne doit pas forcer un état directement. Il utilise les opérations de `JobLifecycle`, qui refusent les transitions hors matrice. + +Pour une annulation observée pendant l'exécution : + +```rust +if let std::result::Result::Err(error) = lifecycle.mark_cancelling() { + return std::result::Result::Err(error); +} +if let std::result::Result::Err(error) = lifecycle.mark_cancelled() { + return std::result::Result::Err(error); +} +``` + +## Partager une intention d'annulation + +```rust +let token = ksp_job_api::JobCancellationToken::new(); +let listener = token.clone(); + +assert!(!listener.is_cancellation_requested()); +assert!(token.request_cancellation()); +assert!(listener.is_cancellation_requested()); +assert!(!token.request_cancellation()); +``` + +Le premier appel qui change l'état retourne `true`. Les demandes suivantes sont idempotentes et retournent `false`. + +Le token ne doit pas être interprété comme une primitive de kill : le runtime concret décide où l'annulation peut interrompre l'admission ou une attente et quelles opérations déjà engagées doivent être drainées. + +## Publier une valeur latest-value + +Un producer concret peut construire une notification complète : + +```rust +#[derive(Clone)] +struct Snapshot { + completed: usize, +} + +let id = ksp_job_api::JobId::new("job-0001")?; +let kind = ksp_job_api::JobKindCode::new("example")?; +let sequence = ksp_job_api::JobNotificationSequence::initial(); +let notification = ksp_job_api::JobNotification::new( + id, + kind, + sequence, + ksp_job_api::JobState::Running, + Snapshot { completed: 0 }, +); + +assert_eq!(notification.sequence().value(), 0); +assert_eq!(notification.state(), ksp_job_api::JobState::Running); +``` + +Le `Debug` de `JobNotification` masque volontairement le snapshot. Le type concret `S` doit lui-même rester sûr à exposer lorsque le consumer accède explicitement à `snapshot()`. + +## Implémenter une source de snapshots + +Une implémentation concrète possède son runtime et expose seulement le contrat `JobSnapshotSource` : + +```rust +async fn observe(source: &S) +where + S: ksp_job_api::JobSnapshotSource, +{ + let current = source.current(); + let observed = current.sequence(); + let newer = source.wait_for_change(observed).await; + assert!(newer.sequence().is_after(observed)); +} +``` + +`wait_for_change` retourne la dernière valeur complète connue après coalescence éventuelle. Un consumer ne doit donc pas supposer qu'il recevra chaque mise à jour intermédiaire. + +## Faire avancer une séquence + +```rust +let first = ksp_job_api::JobNotificationSequence::initial(); +let second = match first.next() { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), +}; +assert!(second.is_after(first)); +``` + +L'épuisement de `u64` est une erreur explicite ; la séquence ne wrappe jamais silencieusement. + +## Frontières à respecter + +Ne pas ajouter à `ksp-job-api` : + +```text +Tokio/Futures runtime concret +Transport ou Store +Config/Logging +DTO métier d'un job précis +scheduler, worker ou control plane +persistence de checkpoint +``` + +Ces responsabilités appartiennent aux crates concrètes et à la composition supérieure. diff --git a/crates/ksp-job-backfill-lib/README.md b/crates/ksp-job-backfill-lib/README.md new file mode 100644 index 0000000..eeb1c3f --- /dev/null +++ b/crates/ksp-job-backfill-lib/README.md @@ -0,0 +1,123 @@ + + + +# ksp-job-backfill-lib + +`ksp-job-backfill-lib` implémente le premier job historique concret de KSP : un backfill borné de transactions Solana vers la couche RAW durable. + +La crate compose les contrats Job, Transport observé et Store backend-neutral sans posséder leurs politiques internes. Elle couvre l'admission, la découverte historique, l'hydratation `getTransaction`, la conversion RAW v1, la persistance atomique, la concurrence bornée, la frontier contiguë, le checkpoint caller-owned, l'annulation coopérative et les snapshots latest-value. + +## Identité + +L'identité logique d'une transaction reste : + +```text +(RawNetworkId, RawTransactionSignature) +``` + +Le rôle HTTP, le provider, l'endpoint et le protocole ne font pas partie de cette identité. Ils décrivent la sélection et/ou la provenance d'acquisition. + +Le fingerprint d'un scope est déterministe sur sa sémantique de découverte et son réseau ; il n'intègre pas `JobId`, provider, endpoint, protocole ou rôle Transport. + +## Scopes + +Quatre scopes sont exposés : + +```text +LatestAddress +BeforeAddress +AfterAddress +ExplicitSignatures +``` + +La requête borne explicitement page size, nombre de pages, nombre de candidats et concurrence d'hydratation. Les signatures explicites sont dédupliquées de façon stable à la première occurrence. + +## Hydratation et RAW v1 + +L'hydratation passe uniquement par la voie observée de `ksp-onchain-transport-lib`. + +Un résultat disponible produit en mémoire : + +- un `RawTransaction` canonique ; +- une `RawTransactionObservation` liée à la même référence logique ; +- une provenance contenant le provider et l'endpoint réellement gagnants ; +- un payload JSON canonique `ksp.solana.raw_transaction`, version `1` ; +- un digest SHA-256 des bytes canoniques. + +Un `getTransaction = null` devient `BackfillHydrationOutcome::Missing` et ne fabrique ni payload ni provenance. + +## Persistance + +La persistance utilise exclusivement `ksp-store-lib` avec `default-features = false` côté dépendance de crate : + +```text +ksp-job-backfill-lib + -> ksp-store-lib + -X-> backend imposé par le job +``` + +Le chemin d'écriture est l'acquisition atomique `RawTransaction + RawTransactionObservation` en mode normal. La crate distingue insertion, déjà présent, tombstone purgé, observation nouvelle/existante, missing et conflit. Un conflit de contenu n'est jamais converti en succès idempotent. + +## Concurrence et checkpoint + +L'exécution maintient au plus `hydration_concurrency` candidats actifs. Les terminaisons hors ordre sont réconciliées par index stable ; le checkpoint n'avance que sur un préfixe **contigu** d'outcomes durablement sûrs. + +`BackfillCheckpoint` est opaque et caller-owned. Il lie : + +```text +JobId +scope fingerprint +completed contiguous prefix +private Before resume cursor +``` + +La crate ne persiste pas elle-même ce checkpoint. Une reprise crash-safe durable nécessite donc que le caller choisisse explicitement où conserver le checkpoint retourné. + +## Runtime et annulation + +`BackfillJobRuntime` est un coordinator single-run. `BackfillJobHandle` peut être cloné pour : + +- demander une annulation coopérative ; +- lire l'état de cette demande ; +- obtenir une source latest-value indépendante. + +L'annulation arrête l'admission de nouveau travail et peut interrompre certaines attentes pré-Store. Une persistance Store déjà soumise est toujours drainée avant publication terminale. + +Les snapshots exposent uniquement des compteurs, phases, boundary, checkpoint et code d'échec sûrs ; ils ne contiennent ni payload RAW, ni URL/credential Transport. + +## Dépendances + +Les dépendances normales sont : + +```text +ksp-core-lib +ksp-job-api +ksp-logging-lib +ksp-onchain-transport-lib +ksp-store-lib (default-features = false) +futures-util +serde_json +sha2 +tokio (macros + sync, détail runtime privé) +``` + +La crate ne dépend pas de Config, `ksp-store-api` directement, `ksp-store-postgres-lib` ni d'un SDK provider. + +## Hors périmètre + +La crate ne possède pas : + +- application desktop ou CLI ; +- Worker API / worker live ; +- retry, pacing ou sélection d'endpoint Transport ; +- backend Store concret ; +- decoding Program ou matérialisation CORE/DECODE/SPECIALIZED ; +- table dédiée de checkpoint ; +- control plane Job générique. + +## Documentation + +- [`USAGE.md`](USAGE.md) — construction des scopes/requêtes, runtime, snapshots et reprise ; +- [`../ksp-job-api/README.md`](../ksp-job-api/README.md) — contrats Job runtime-neutral ; +- [`../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md`](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md) — architecture durable acquisition/jobs ; +- [`../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md`](../../docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md) — frontière RAW/Store. diff --git a/crates/ksp-job-backfill-lib/USAGE.md b/crates/ksp-job-backfill-lib/USAGE.md new file mode 100644 index 0000000..0d22c9c --- /dev/null +++ b/crates/ksp-job-backfill-lib/USAGE.md @@ -0,0 +1,206 @@ + + + +# Utilisation de ksp-job-backfill-lib + +Cette page décrit l'utilisation durable de la façade publique de `ksp-job-backfill-lib`. Elle suppose qu'un caller a déjà construit un `HttpTransportPool` et un `Store` compatibles avec le même réseau logique. + +## Construire une signature et un scope + +```rust +let anchor = match ksp_job_backfill_lib::BackfillSignature::new( + "1111111111111111111111111111111111111111111111111111111111111111", +) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), +}; + +let address = ksp_core_lib::Pubkey::new_from_array([7_u8; 32]); +let scope = ksp_job_backfill_lib::BackfillScope::before_address(address, anchor); +``` + +Les autres formes sont : + +```rust +let latest = ksp_job_backfill_lib::BackfillScope::latest_address(address); +let before = ksp_job_backfill_lib::BackfillScope::before_address(address, anchor.clone()); +let after = ksp_job_backfill_lib::BackfillScope::after_address(address, anchor.clone()); +let explicit = ksp_job_backfill_lib::BackfillScope::explicit_signatures(vec![anchor]); +``` + +`ExplicitSignatures` déduplique la liste en conservant la première occurrence. Les scopes address utilisent `getSignaturesForAddress` ; le scope explicite n'effectue aucune découverte address. + +## Construire une requête bornée + +```rust +fn request(scope: ksp_job_backfill_lib::BackfillScope) -> ksp_core_lib::Result { + let job_id = match ksp_job_api::JobId::new("raw-backfill-0001") { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + 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 role = ksp_onchain_transport_lib::HttpRoleName::new("historical"); + + return ksp_job_backfill_lib::BackfillRequest::new( + job_id, + network, + role, + ksp_job_backfill_lib::BackfillCommitment::Finalized, + scope, + 500, + 20, + 5_000, + 16, + std::option::Option::None, + ); +} +``` + +Bornes publiques : + +```text +page_size 1 ..= 1_000 +max_pages 1 ..= 10_000 +max_candidates 1 ..= 10_000 +hydration_concurrency 1 ..= 64 +``` + +Le `min_context_slot` n'est pas admis pour `ExplicitSignatures`. + +## Comprendre le fingerprint + +```rust +let fingerprint = request.scope_fingerprint(); +let bytes: &[u8; 32] = fingerprint.as_bytes(); +``` + +Le fingerprint représente le scope sémantique et le réseau. Il ne change pas uniquement parce que le rôle Transport, le provider ou l'endpoint d'acquisition change. + +Ne pas utiliser le fingerprint comme identité de transaction : l'identité durable reste `(network, signature)`. + +## Exécuter le runtime complet + +```rust +async fn run_backfill( + request: ksp_job_backfill_lib::BackfillRequest, + transport: &ksp_onchain_transport_lib::HttpTransportPool, + store: &ksp_store_lib::Store, +) -> ksp_core_lib::Result { + let runtime = match ksp_job_backfill_lib::BackfillJobRuntime::new(request) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), + }; + return runtime.run(transport, store).await; +} +``` + +Le Store et la requête doivent cibler le même `RawNetworkId`. Un mismatch est rejeté avant l'écriture. + +## Observer la progression + +Obtenir le handle avant de déplacer le runtime dans `run` : + +```rust +let runtime = ksp_job_backfill_lib::BackfillJobRuntime::new(request)?; +let handle = runtime.handle(); +let snapshots = handle.snapshots(); + +let current = ksp_job_api::JobSnapshotSource::current(&snapshots); +let observed = current.sequence(); +let newer = ksp_job_api::JobSnapshotSource::wait_for_change(&snapshots, observed).await; + +assert!(newer.sequence().is_after(observed)); +``` + +Chaque listener peut cloner sa propre `BackfillSnapshotSource`. La source est latest-value : plusieurs mises à jour intermédiaires peuvent être coalescées, mais la valeur retournée est toujours un snapshot complet. + +Les compteurs publics du snapshot couvrent notamment : + +```text +candidates_selected / admitted / finished +entities_inserted / existing / purged +observations_inserted / existing +missing / conflicts / holes +maximum_in_flight +contiguous_completed +checkpoint +failure_code +``` + +## Demander une annulation + +```rust +let accepted = handle.cancel(); +if accepted { + assert!(handle.is_cancellation_requested()); +} +``` + +L'annulation est coopérative. Elle peut stopper de nouvelles admissions et certaines attentes avant persistance. Une écriture Store déjà soumise est drainée ; le caller ne doit donc pas supposer qu'une demande d'annulation rend immédiatement toutes les opérations in-flight inexistantes. + +Une demande faite après publication terminale est rejetée (`false`). + +## Reprendre avec un checkpoint + +Le snapshot ou le batch d'exécution peut fournir un `BackfillCheckpoint` sûr. Pour une reprise contrôlée : + +```rust +let resumed = match request.with_checkpoint(checkpoint) { + std::result::Result::Ok(value) => value, + std::result::Result::Err(error) => return std::result::Result::Err(error), +}; +``` + +Le checkpoint doit appartenir au même `JobId` et au même fingerprint de scope. + +Sémantique de reprise : + +```text +LatestAddress repart du latest courant ; frontier contiguë conservée dans le nouveau run +BeforeAddress reprend avec le dernier cursor before prouvé +AfterAddress rejoue le scope et saute seulement le préfixe contigu prouvé +ExplicitSignatures rejoue la liste et saute seulement le préfixe contigu prouvé +``` + +`BackfillCheckpoint` n'est pas persisté automatiquement. Si le caller exige une reprise après crash/process restart, il doit stocker ce checkpoint dans une surface durable appropriée puis le réinjecter explicitement. + +## Utiliser les primitives séparément + +La façade expose aussi les étapes pour des compositions/tests spécialisés : + +```text +discover_backfill_candidates +hydrate_backfill_candidate +persist_backfill_hydration +execute_backfill_discovery +``` + +`hydrate_backfill_candidate` ne persiste rien. `persist_backfill_hydration` n'effectue aucun appel Transport. `execute_backfill_discovery` combine hydratation/persistance sur un résultat de découverte déjà validé. + +Pour un flux applicatif normal qui veut lifecycle + snapshots + annulation, préférer `BackfillJobRuntime::run`. + +## Interpréter les outcomes de persistance + +Les outcomes distinguent explicitement : + +```text +entity: Inserted | AlreadyPresent | SkippedPurged | Conflict +observation: Inserted | AlreadyPresent | NotRecorded | NotApplicable +``` + +`Missing` ne provoque aucune écriture Store. Un conflit de contenu reste observable comme conflit et ne doit pas être traité comme une relance idempotente réussie. + +## Frontières à respecter + +Le caller ne doit pas : + +- pré-lire le Store pour décider s'il faut hydrater une transaction ; +- appeler directement `ksp-store-postgres-lib` depuis le job ; +- ajouter une politique de retry/pacing qui concurrence Transport ; +- utiliser provider/endpoint comme identité transactionnelle ; +- inventer une provenance pour `getTransaction = null` ; +- interpréter un checkpoint caller-owned comme une garantie de persistence crash-safe automatique ; +- utiliser le job RAW comme decoder Program ou processor CORE. diff --git a/deltas/0.3.6/pre.012.md b/deltas/0.3.6/pre.012.md new file mode 100644 index 0000000..69fc632 --- /dev/null +++ b/deltas/0.3.6/pre.012.md @@ -0,0 +1,204 @@ + + + +# Delta `0.3.6-pre.012` — réconciliation documentaire finale Job/Backfill + +## 1. Base requise + +Base directe attendue : + +```text +0.3.6-pre.11 +``` + +Le gate technique final de `pre.011` est fermé : format en mode check, audits Rust/Markdown, `cargo check --workspace`, Clippy workspace/all-targets/all-features avec `-D warnings` et tests workspace/all-targets/all-features passent. Le run opérateur agrège `1_404` tests passés, `0` échec et `15` tests explicitement ignorés/opt-in. Les graphes Cargo de `ksp-job-api` et `ksp-job-backfill-lib` ainsi que l'inventaire des doublons workspace ont été exécutés et revus. + +## 2. Objectif + +Réconcilier exclusivement la documentation durable avec la surface Job/Backfill effectivement validée, sans rouvrir le comportement Rust ni commencer la publication. + +La tranche couvre : + +```text +README racine +README/USAGE de ksp-job-api +README/USAGE de ksp-job-backfill-lib +index documentaires +architectures concernées par Jobs/Backfill +plan 027 +validation 023 +``` + +Elle ne modifie aucun `src/**`, test, manifeste de crate, dépendance, feature, Config, Store, Transport, `CHANGELOG.md`, `ROADMAP.md` ou prompt suivant. + +## 3. Version + +Conformément au workflow de prerelease non-fix : + +```text +workspace.package.version = 0.3.6-pre.12 +``` + +Aucune autre propriété Cargo n'est modifiée. + +## 4. Contrat durable `ksp-job-api` + +Le nouveau README décrit la crate comme API passive et runtime-neutral possédant : + +```text +JobId / JobKindCode +JobState / JobCompletion / JobLifecycle +JobCancellationToken +JobNotificationSequence / JobNotification +JobSnapshotSource / JobSnapshotFuture +``` + +Le nouveau USAGE fournit des exemples de consommation via la façade crate-root pour l'identité, le lifecycle, l'annulation et le contrat latest-value. Il ne contient aucune note de prerelease, preuve de gate ou historique de version. + +La frontière de dépendance reste explicite : dépendance normale uniquement vers `ksp-core-lib`, aucune dépendance Transport/Store/Tokio ou domaine métier. + +## 5. Contrat durable `ksp-job-backfill-lib` + +Le README et le USAGE décrivent désormais la surface concrète du premier job historique RAW : + +```text +4 scopes : LatestAddress / BeforeAddress / AfterAddress / ExplicitSignatures +identité logique = (RawNetworkId, Signature) +fingerprint sémantique indépendant du JobId et de la source Transport +hydratation getTransaction observée +RAW transaction format v1 déterministe +persistance atomique via ksp-store-lib en mode Normal +concurrence d'hydratation bornée +frontier contiguë +checkpoint caller-owned +runtime concret + handle + snapshots latest-value +annulation coopérative avec drainage des persistances Store déjà soumises +``` + +La documentation distingue explicitement un checkpoint retourné au caller d'une persistance crash-safe automatique : la crate ne possède pas de stockage durable de checkpoint. + +Le Store reste consommé uniquement par `ksp-store-lib` avec `default-features = false`; aucun backend physique ou `ksp-store-api` n'est exposé aux consommateurs Backfill. + +## 6. Architecture et inventaires + +Les documents durables suivants sont réconciliés avec le vertical désormais prouvé : + +```text +docs/architecture/002-LAYERS_AND_DEPENDENCIES.md +docs/architecture/003-COMPONENT_CONTRACTS.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 +``` + +Ils enregistrent notamment : + +- `ksp-job-api` comme API Job passive et runtime-neutral ; +- `ksp-job-backfill-lib` comme première implementation concrète bornée, distincte d'un worker live permanent ; +- les frontières Transport/Store/Job ; +- la responsabilité caller-owned du checkpoint ; +- les dépendances runtime privées du Backfill ; +- l'absence de justification actuelle pour une couche générique de contrôle supplémentaire. + +`004-COMPONENT_INVENTORY.md` introduit le statut durable `Implémenté` pour une surface techniquement validée mais pas encore publiée stable et l'applique aux deux composants Job de `0.3.6`. + +## 7. Index et README racine + +Les index `docs/`, `docs/plans/` et `docs/validation/` référencent désormais les documents actuels jusqu'aux plans `027` et validations `023`. + +Le README racine décrit la fondation opérationnelle actuelle Store/Job/Backfill sans journaliser les prereleases. + +## 8. Hors scope préservé + +```text +CHANGELOG.md +ROADMAP.md +prompt 0.3.7 +src/** +tests/** +Cargo.toml de crates +dépendances/features +nouveau runtime +nouveau backend Store +application Backfill Desk +worker live +smoke live PostgreSQL +``` + +La préparation `CHANGELOG` / `ROADMAP` / prompt reste réservée à `pre.013`. + +## 9. Fichiers ajoutés + +```text +crates/ksp-job-api/README.md +crates/ksp-job-api/USAGE.md +crates/ksp-job-backfill-lib/README.md +crates/ksp-job-backfill-lib/USAGE.md +deltas/0.3.6/pre.012.md +``` + +## 10. Fichiers modifiés + +```text +Cargo.toml +README.md +docs/000-README.md +docs/architecture/002-LAYERS_AND_DEPENDENCIES.md +docs/architecture/003-COMPONENT_CONTRACTS.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/plans/000-README.md +docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md +docs/validation/000-README.md +docs/validation/023-V0_3_6_JOB_API_BACKFILL.md +``` + +## 11. Fichiers supprimés + +Aucun. + +## 12. Validations de génération + +Les contrôles statiques applicables sont rejoués sur l'overlay complet : + +```text +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/0.3.6 +python3 scripts/tests/test_audit_markdown_tables.py +contrôle différentiel exact contre pre.011 +contrôle des versions d'en-tête +contrôle que src/tests/manifests de crates restent byte-identical +replay exact de l'archive sur pre.011 +``` + +Cargo/rustc/rustfmt ne sont pas disponibles dans l'environnement de génération ; aucun nouveau résultat Cargo post-overlay n'est revendiqué ici. Les preuves techniques larges restent celles du gate `pre.011`. + +## 13. Gate opérateur après application + +```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/0.3.6 +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-job-api +cargo test -p ksp-job-backfill-lib +``` + +Aucun `cargo tree`, test workspace all-features ou smoke live n'est requis par cette tranche documentaire ; ces preuves sont déjà fermées par `pre.011` et aucun graphe de dépendance n'est modifié. + +## 14. Questions ouvertes + +Aucune question de design pour `0.3.6`. + +## 15. Suite + +Après gate documentaire vert : + +```text +0.3.6-pre.013 — préparation publication minimale + prompt 0.3.7 +0.3.6-rel.001 — stabilisation/tag v0.3.6 +``` diff --git a/docs/000-README.md b/docs/000-README.md index 5f4a538..039db00 100644 --- a/docs/000-README.md +++ b/docs/000-README.md @@ -1,5 +1,5 @@ - + # Documentation KSP @@ -59,7 +59,11 @@ docs/ │ ├── 020-V0_2_13_INTERFACE_PLAN.md │ ├── 021-V0_2_14_PROGRAM_API_PLAN.md │ ├── 022-V0_3_1_STORE_RAW_PLAN.md -│ └── 023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md +│ ├── 023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md +│ ├── 024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md +│ ├── 025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md +│ ├── 026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md +│ └── 027-V0_3_6_JOB_API_BACKFILL_PLAN.md ├── validation/ │ ├── 000-README.md │ ├── 001-V0_1_4_CONFIG_DESKTOP.md @@ -80,7 +84,11 @@ docs/ │ ├── 016-V0_2_13_INTERFACE.md │ ├── 017-V0_2_14_PROGRAM_API.md │ ├── 018-V0_3_1_STORE_RAW.md -│ └── 019-V0_3_2_STORE_POSTGRES_FOUNDATION.md +│ ├── 019-V0_3_2_STORE_POSTGRES_FOUNDATION.md +│ ├── 020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md +│ ├── 021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md +│ ├── 022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md +│ └── 023-V0_3_6_JOB_API_BACKFILL.md └── rules/ ├── FILE_CONTRACTS.md ├── PROMPT_STRUCTURE.md @@ -97,7 +105,7 @@ D'autres sous-répertoires seront ajoutés uniquement lorsque leur rôle aura é ## Documents de planification -Le plan historique de la phase fondatrice clôturée est conservé dans [`plans/001-V0_0_3_PLAN.md`](plans/001-V0_0_3_PLAN.md). La séquence active des premières releases fonctionnelles est définie dans [`plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`](plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md). Le plan détaillé de la release stable `0.1.1` est conservé comme historique clôturé dans [`plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md`](plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.2` est conservé comme historique clôturé dans [`plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md`](plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.3 — Configuration foundation` est conservé comme historique clôturé dans [`plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.4 — ksp-app-config-desk` est conservé comme historique clôturé dans [`plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md`](plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md), avec sa matrice finale [`validation/001-V0_1_4_CONFIG_DESKTOP.md`](validation/001-V0_1_4_CONFIG_DESKTOP.md). Son prompt d'ouverture historique reste [`../prompts/004-V0_1_4_START_PROMPT.md`](../prompts/004-V0_1_4_START_PROMPT.md). La release stable `0.2.0` clôt l'audit de bot3 et le découpage de la série. Son plan directeur est conservé comme historique clôturé dans [`plans/007-V0_2_0_SERIES_PLANNING.md`](plans/007-V0_2_0_SERIES_PLANNING.md), avec sa matrice finale [`validation/002-V0_2_0_SERIES_PLANNING.md`](validation/002-V0_2_0_SERIES_PLANNING.md). La release stable `0.2.1 — HTTP Solana foundation` a été ouverte par [`../prompts/006-V0_2_1_START_PROMPT.md`](../prompts/006-V0_2_1_START_PROMPT.md). Son gate de sizing et sa matrice exhaustive sont conservés dans [`plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md), avec la validation finale [`validation/003-V0_2_1_ONCHAIN_HTTP.md`](validation/003-V0_2_1_ONCHAIN_HTTP.md), README/USAGE Transport et le smoke Devnet opt-in de composition Config -> Transport. Le prompt [`../prompts/007-V0_2_2_START_PROMPT.md`](../prompts/007-V0_2_2_START_PROMPT.md) a ouvert la release stable `0.2.2 — HTTP Accounts + Tokens + Cluster`. Son plan clôturé [`plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) conserve l'audit et l'implémentation des 22 wrappers typés, tandis que [`validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) enregistre les validations déterministes, les graphes Cargo et les deux smokes Devnet passés avant publication. Le prompt [`../prompts/008-V0_2_3_START_PROMPT.md`](../prompts/008-V0_2_3_START_PROMPT.md) a ouvert la release stable `0.2.3 — HTTP Transactions`. Son plan clôturé [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) conserve l'audit et l'implémentation des 11 wrappers ; le réaudit [`validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) confirme la complétude des 37 wrappers HTTP typés et [`validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](validation/006-V0_2_3_HTTP_TRANSACTIONS.md) enregistre les validations finales, graphes Cargo et deux smokes Devnet passés avant publication. Le prompt [`../prompts/009-V0_2_4_START_PROMPT.md`](../prompts/009-V0_2_4_START_PROMPT.md) a ouvert la release stable `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`. Son plan clôturé [`plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) conserve l’implémentation des 15 wrappers et la compliance `52/52 + 14/14`; la matrice finale [`validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) enregistre le réaudit SIMD/inventaire, les canaries globales et les preuves opérateur avant publication. Le prompt [`../prompts/010-V0_2_5_START_PROMPT.md`](../prompts/010-V0_2_5_START_PROMPT.md), finalisé par `0.2.4-pre.009-fix.001`, ouvre `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`. Son plan historique clôturé [`plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) part du gate `pre.001` (héritage, threat model offline, VIEW/OWNER indépendants et niveau B read-only), puis matérialise la crate en `pre.002`, le wire/transcript en `pre.003`, les primitives Argon2id/XChaCha20-Poly1305 en `pre.004`, les payloads/create/open en `pre.005`, la persistence en `pre.006`, l'administration/signature en `pre.007` et les adapters transfer en `pre.008`. `pre.009` ferme l'audit adversarial/interoperability/compliance dans [`validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) avant la documentation finale `pre.010` ; `pre.010` finalise [`../crates/ksp-wallet-lib/README.md`](../crates/ksp-wallet-lib/README.md), [`../crates/ksp-wallet-lib/USAGE.md`](../crates/ksp-wallet-lib/USAGE.md), la spec, les graphes et la matrice ; `pre.010-fix.001`–`fix.003` ferment ensuite la mise à niveau Dalek et la normalisation Rust/audit structurel. `0.2.5-rel.001` publie la release stable et [`../prompts/011-V0_2_6_START_PROMPT.md`](../prompts/011-V0_2_6_START_PROMPT.md) ouvre `0.2.6 — Wallet Desk`. Le gate `0.2.6-pre.001` est conservé dans [`plans/013-V0_2_6_WALLET_DESK_PLAN.md`](plans/013-V0_2_6_WALLET_DESK_PLAN.md) : il réaudite Config Desk et les APIs finales, retient le gabarit desktop, fixe `std.wallet`, la composition Config/Wallet/HTTP/Logging, les secrets `KSP_SECRET_WALLET_PASS_*`, les frontières VIEW/OWNER et la trajectoire de validation. `pre.002`–`pre.014` matérialisent ensuite le shell Tauri, Config Wallet/composite, inventory, create/open, balance HTTP, import/export, metadata, rotations, révocation VIEW forte, compliance et polish desktop. `pre.015` fige le wire binaire `.kspwallet` V2, `pre.016` matérialise les APIs génériques/versionnées et le runtime V2, puis `pre.017` ajoute la migration explicite OWNER-authentifiée V1 -> V2. `pre.018` ferme le runtime Tauri packagé Config/resources et la documentation candidate ; `pre.018-fix.001` corrige le canari d'ownership Config, après quoi le gate workspace et le build final Linux sont verts. `pre.018-fix.002` renforce uniquement le contrat de reprise `0.2.7`. `0.2.6-rel.001` publie cette surface stable et [`../prompts/012-V0_2_7_START_PROMPT.md`](../prompts/012-V0_2_7_START_PROMPT.md) devient le prochain point d'entrée. Le gate `0.2.7-pre.001` ouvre la release WebSocket standard dans [`plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) ; la matrice normative puis finale est conservée dans [`validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`](validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md). `0.2.7-pre.014` ferme la candidate technique/documentaire après validation 18/18, smoke WebSocket Devnet et audit du graphe Cargo ; `pre.014-fix.001` renforce uniquement le prompt suivant. `0.2.7-rel.001` publie `0.2.7 — WebSocket Solana standard` stable et [`../prompts/013-V0_2_8_START_PROMPT.md`](../prompts/013-V0_2_8_START_PROMPT.md) ouvre `0.2.8 — Helius LaserStream WebSocket`. Le plan historique clôturé [`plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md`](plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md) et la matrice finale [`validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md`](validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md) conservent la release stable `0.2.8 — Helius LaserStream WebSocket` publiée par `rel.001` : protocol `helius_laserstream`, sept familles standard Helius (`account/logs/program/root/signature/slot/slotsUpdates`), extension `transactionSubscribe`/`transactionUnsubscribe`, `block/vote` absents, heartbeat Ping 60 s, Config/secrets redacted, lifecycle adversarial et graphes Cargo finaux validés. [`../prompts/014-V0_2_9_START_PROMPT.md`](../prompts/014-V0_2_9_START_PROMPT.md) devient le contrat actif pour ouvrir Yellowstone gRPC standard/provider-neutral depuis le tag stable `v0.2.8`. La release stable `0.2.9` est conservée dans [`plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md`](plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md) et [`validation/012-V0_2_9_YELLOWSTONE_GRPC.md`](validation/012-V0_2_9_YELLOWSTONE_GRPC.md) : stratégie proto Apache + client KSP/Tonic, moteur N1, standard N2, Config V3, profils PublicNode Mainnet/Testnet authentifiés par `x-token` secret et smoke live `Subscribe` validé sur les deux réseaux. La candidate `0.2.10 — OrbitFlare Yellowstone gRPC` est réconciliée dans [`plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md`](plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md) et [`validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md`](validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md) : Devnet `http://devnet.rpc.orbitflare.com:10000`, License Key `ORBIT-*` injectée comme metadata secrète `x-token`, Config Transport V3 inchangée, live `Subscribe -> Slot + Ping` passé, aucun overlay provider et aucun heartbeat supplémentaire. La candidate `0.2.11 — Off-chain price transport` est réconciliée dans [`plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md`](plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md) et [`validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md`](validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md) : SOL/USD V1, huit adapters REST sans SDK provider, décimal exact, registry/availability/rate limits possédés par Off-chain Transport, Config `std.offchain_transport`, refresh individuel/multiple provider-neutral et smoke live keyless final `7/7` après correction CoinMarketCap V2. [`../crates/ksp-offchain-transport-lib/README.md`](../crates/ksp-offchain-transport-lib/README.md) et [`../crates/ksp-offchain-transport-lib/USAGE.md`](../crates/ksp-offchain-transport-lib/USAGE.md) deviennent les références durables ; la future `ksp-app-solprices-desk` reste une HID sans logique provider. La release stable `0.2.12 — SOL Prices Desk + intégration prix Wallet Desk` est conservée dans [`plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md`](plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md) et [`validation/015-V0_2_12_SOL_PRICES_DESK.md`](validation/015-V0_2_12_SOL_PRICES_DESK.md) : `ksp-app-solprices-desk` fournit le refresh manuel row/selected/all provider-neutral, états/timestamps exacts et diagnostics sûrs sur ports 1434/1435 ; Wallet Desk réutilise `MarketPriceService::refresh_all` pendant le refresh balance pour afficher une moyenne SOL/USD consumer-owned et l'équivalent USD exact, sans provider concret ni fallback Off-chain. Les gates finaux workspace/live et les trois builds Tauri Linux sont verts avant publication. `0.2.13 — Interface / wire foundation` est réconciliée comme candidate dans [`plans/020-V0_2_13_INTERFACE_PLAN.md`](plans/020-V0_2_13_INTERFACE_PLAN.md) avec la matrice finale candidate [`validation/016-V0_2_13_INTERFACE.md`](validation/016-V0_2_13_INTERFACE.md) : `ksp-interface-lib` expose le `Pubkey` Core, `ProgramAccountMeta` et `ProgramInstruction`, bornés à `255` account metas et `10_240` bytes de data, avec façade crate-root exacte, diagnostics bornés, consumer externe et firewall `Interface -> Core` validés. Le gate technique final `pre.006` est intégralement vert ; [`../crates/ksp-interface-lib/README.md`](../crates/ksp-interface-lib/README.md) et [`../crates/ksp-interface-lib/USAGE.md`](../crates/ksp-interface-lib/USAGE.md) deviennent les références durables avant préparation de publication. Le prompt d’ouverture historique reste [`../prompts/018-V0_2_13_START_PROMPT.md`](../prompts/018-V0_2_13_START_PROMPT.md). `0.2.14 — Program API foundation` est réconciliée comme candidate dans [`plans/021-V0_2_14_PROGRAM_API_PLAN.md`](plans/021-V0_2_14_PROGRAM_API_PLAN.md) avec la matrice finale candidate [`validation/017-V0_2_14_PROGRAM_API.md`](validation/017-V0_2_14_PROGRAM_API.md) : `ksp-program-api` fournit une façade instruction-only ouverte, `ProgramInstructionRecognition`, `ProgramInstructionDecodeOutcome` et `ProgramInstructionDecoder`, avec output associé possédé par l’implémentation, Program Pubkeys opaques/non enregistrés acceptés, canari externe et firewall `Program API -> Core + Interface`. Le gate technique final `pre.006` est intégralement vert ; [`../crates/ksp-program-api/README.md`](../crates/ksp-program-api/README.md) et [`../crates/ksp-program-api/USAGE.md`](../crates/ksp-program-api/USAGE.md) deviennent les références durables avant préparation de publication. Le prompt d’ouverture historique reste [`../prompts/019-V0_2_14_START_PROMPT.md`](../prompts/019-V0_2_14_START_PROMPT.md). `0.3.1 — Store API RAW foundation` est réconciliée comme candidate dans [`plans/022-V0_3_1_STORE_RAW_PLAN.md`](plans/022-V0_3_1_STORE_RAW_PLAN.md) avec la matrice [`validation/018-V0_3_1_STORE_RAW.md`](validation/018-V0_3_1_STORE_RAW.md) : `ksp-store-api` reste Core-only et backend-agnostic, expose les modèles RAW transaction/account et observations, queries cursorisées, outcomes, capabilities fines et lifecycle de rétention/tombstone, sans backend runtime, PostgreSQL, processing ledger ni N2/N3/N4. Le gate `pre.008` a été reconstruit après `cargo clean` et validé sur le workspace complet et les trois builds Tauri ; `pre.009` réconcilie la documentation durable avant la préparation de publication `pre.010`. `0.3.2 — Store/PostgreSQL runtime foundation` est réconciliée comme candidate dans [`plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) avec la matrice finale [`validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) : `ksp-store-lib` fournit la façade runtime backend-neutral, `ksp-store-postgres-lib` possède le backend physique tokio-postgres/Deadpool/Rustls et les migrations metadata-only, tandis que `std.store` sélectionne des targets PostgreSQL séparés par réseau. Le gate technique `pre.010` valide workspace, graphes, trois builds Tauri et la fondation PostgreSQL réelle sur un serveur major 17 ; [`../crates/ksp-store-lib/README.md`](../crates/ksp-store-lib/README.md), [`../crates/ksp-store-lib/USAGE.md`](../crates/ksp-store-lib/USAGE.md), [`../crates/ksp-store-postgres-lib/README.md`](../crates/ksp-store-postgres-lib/README.md) et [`../crates/ksp-store-postgres-lib/USAGE.md`](../crates/ksp-store-postgres-lib/USAGE.md) deviennent les références durables avant la lane de publication. `0.3.3 — Store/PostgreSQL RawTransaction vertical slice` est réconciliée comme candidate dans [`plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md`](plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md) avec la matrice finale [`validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md`](validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md) : les six capabilities `RawTransaction*` sont implémentées côté backend et façade, V001 matérialise canonical/observations/archive avec binding réseau, navigation keyset et rétention atomique, et le gate final rejoue le workspace complet ainsi que le live PostgreSQL 17. `RawAccountState` physique reste réservé à `0.3.4`. +Le plan historique de la phase fondatrice clôturée est conservé dans [`plans/001-V0_0_3_PLAN.md`](plans/001-V0_0_3_PLAN.md). La séquence active des premières releases fonctionnelles est définie dans [`plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md`](plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md). Le plan détaillé de la release stable `0.1.1` est conservé comme historique clôturé dans [`plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md`](plans/003-V0_1_1_CORE_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.2` est conservé comme historique clôturé dans [`plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md`](plans/004-V0_1_2_LOGGING_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.3 — Configuration foundation` est conservé comme historique clôturé dans [`plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md`](plans/005-V0_1_3_CONFIG_FOUNDATION_PLAN.md). Le plan détaillé de la release stable `0.1.4 — ksp-app-config-desk` est conservé comme historique clôturé dans [`plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md`](plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md), avec sa matrice finale [`validation/001-V0_1_4_CONFIG_DESKTOP.md`](validation/001-V0_1_4_CONFIG_DESKTOP.md). Son prompt d'ouverture historique reste [`../prompts/004-V0_1_4_START_PROMPT.md`](../prompts/004-V0_1_4_START_PROMPT.md). La release stable `0.2.0` clôt l'audit de bot3 et le découpage de la série. Son plan directeur est conservé comme historique clôturé dans [`plans/007-V0_2_0_SERIES_PLANNING.md`](plans/007-V0_2_0_SERIES_PLANNING.md), avec sa matrice finale [`validation/002-V0_2_0_SERIES_PLANNING.md`](validation/002-V0_2_0_SERIES_PLANNING.md). La release stable `0.2.1 — HTTP Solana foundation` a été ouverte par [`../prompts/006-V0_2_1_START_PROMPT.md`](../prompts/006-V0_2_1_START_PROMPT.md). Son gate de sizing et sa matrice exhaustive sont conservés dans [`plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md`](plans/008-V0_2_1_ONCHAIN_HTTP_PLAN.md), avec la validation finale [`validation/003-V0_2_1_ONCHAIN_HTTP.md`](validation/003-V0_2_1_ONCHAIN_HTTP.md), README/USAGE Transport et le smoke Devnet opt-in de composition Config -> Transport. Le prompt [`../prompts/007-V0_2_2_START_PROMPT.md`](../prompts/007-V0_2_2_START_PROMPT.md) a ouvert la release stable `0.2.2 — HTTP Accounts + Tokens + Cluster`. Son plan clôturé [`plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md`](plans/009-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER_PLAN.md) conserve l'audit et l'implémentation des 22 wrappers typés, tandis que [`validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md`](validation/004-V0_2_2_HTTP_ACCOUNTS_TOKENS_CLUSTER.md) enregistre les validations déterministes, les graphes Cargo et les deux smokes Devnet passés avant publication. Le prompt [`../prompts/008-V0_2_3_START_PROMPT.md`](../prompts/008-V0_2_3_START_PROMPT.md) a ouvert la release stable `0.2.3 — HTTP Transactions`. Son plan clôturé [`plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md`](plans/010-V0_2_3_HTTP_TRANSACTIONS_PLAN.md) conserve l'audit et l'implémentation des 11 wrappers ; le réaudit [`validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md`](validation/005-V0_2_3_KSP_TRANSPORT_007_RETRO_AUDIT.md) confirme la complétude des 37 wrappers HTTP typés et [`validation/006-V0_2_3_HTTP_TRANSACTIONS.md`](validation/006-V0_2_3_HTTP_TRANSACTIONS.md) enregistre les validations finales, graphes Cargo et deux smokes Devnet passés avant publication. Le prompt [`../prompts/009-V0_2_4_START_PROMPT.md`](../prompts/009-V0_2_4_START_PROMPT.md) a ouvert la release stable `0.2.4 — HTTP Blocks + Economics + compliance HTTP finale`. Son plan clôturé [`plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md`](plans/011-V0_2_4_HTTP_BLOCKS_ECONOMICS_PLAN.md) conserve l’implémentation des 15 wrappers et la compliance `52/52 + 14/14`; la matrice finale [`validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md`](validation/007-V0_2_4_HTTP_FINAL_COMPLIANCE.md) enregistre le réaudit SIMD/inventaire, les canaries globales et les preuves opérateur avant publication. Le prompt [`../prompts/010-V0_2_5_START_PROMPT.md`](../prompts/010-V0_2_5_START_PROMPT.md), finalisé par `0.2.4-pre.009-fix.001`, ouvre `0.2.5 — Wallet foundation` sur la base stable `v0.2.4`. Son plan historique clôturé [`plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md`](plans/012-V0_2_5_WALLET_FOUNDATION_PLAN.md) part du gate `pre.001` (héritage, threat model offline, VIEW/OWNER indépendants et niveau B read-only), puis matérialise la crate en `pre.002`, le wire/transcript en `pre.003`, les primitives Argon2id/XChaCha20-Poly1305 en `pre.004`, les payloads/create/open en `pre.005`, la persistence en `pre.006`, l'administration/signature en `pre.007` et les adapters transfer en `pre.008`. `pre.009` ferme l'audit adversarial/interoperability/compliance dans [`validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md`](validation/008-V0_2_5_WALLET_SECURITY_COMPLIANCE.md) avant la documentation finale `pre.010` ; `pre.010` finalise [`../crates/ksp-wallet-lib/README.md`](../crates/ksp-wallet-lib/README.md), [`../crates/ksp-wallet-lib/USAGE.md`](../crates/ksp-wallet-lib/USAGE.md), la spec, les graphes et la matrice ; `pre.010-fix.001`–`fix.003` ferment ensuite la mise à niveau Dalek et la normalisation Rust/audit structurel. `0.2.5-rel.001` publie la release stable et [`../prompts/011-V0_2_6_START_PROMPT.md`](../prompts/011-V0_2_6_START_PROMPT.md) ouvre `0.2.6 — Wallet Desk`. Le gate `0.2.6-pre.001` est conservé dans [`plans/013-V0_2_6_WALLET_DESK_PLAN.md`](plans/013-V0_2_6_WALLET_DESK_PLAN.md) : il réaudite Config Desk et les APIs finales, retient le gabarit desktop, fixe `std.wallet`, la composition Config/Wallet/HTTP/Logging, les secrets `KSP_SECRET_WALLET_PASS_*`, les frontières VIEW/OWNER et la trajectoire de validation. `pre.002`–`pre.014` matérialisent ensuite le shell Tauri, Config Wallet/composite, inventory, create/open, balance HTTP, import/export, metadata, rotations, révocation VIEW forte, compliance et polish desktop. `pre.015` fige le wire binaire `.kspwallet` V2, `pre.016` matérialise les APIs génériques/versionnées et le runtime V2, puis `pre.017` ajoute la migration explicite OWNER-authentifiée V1 -> V2. `pre.018` ferme le runtime Tauri packagé Config/resources et la documentation candidate ; `pre.018-fix.001` corrige le canari d'ownership Config, après quoi le gate workspace et le build final Linux sont verts. `pre.018-fix.002` renforce uniquement le contrat de reprise `0.2.7`. `0.2.6-rel.001` publie cette surface stable et [`../prompts/012-V0_2_7_START_PROMPT.md`](../prompts/012-V0_2_7_START_PROMPT.md) devient le prochain point d'entrée. Le gate `0.2.7-pre.001` ouvre la release WebSocket standard dans [`plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md`](plans/014-V0_2_7_ONCHAIN_WEBSOCKET_PLAN.md) ; la matrice normative puis finale est conservée dans [`validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md`](validation/010-V0_2_7_ONCHAIN_WEBSOCKET.md). `0.2.7-pre.014` ferme la candidate technique/documentaire après validation 18/18, smoke WebSocket Devnet et audit du graphe Cargo ; `pre.014-fix.001` renforce uniquement le prompt suivant. `0.2.7-rel.001` publie `0.2.7 — WebSocket Solana standard` stable et [`../prompts/013-V0_2_8_START_PROMPT.md`](../prompts/013-V0_2_8_START_PROMPT.md) ouvre `0.2.8 — Helius LaserStream WebSocket`. Le plan historique clôturé [`plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md`](plans/015-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET_PLAN.md) et la matrice finale [`validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md`](validation/011-V0_2_8_HELIUS_LASERSTREAM_WEBSOCKET.md) conservent la release stable `0.2.8 — Helius LaserStream WebSocket` publiée par `rel.001` : protocol `helius_laserstream`, sept familles standard Helius (`account/logs/program/root/signature/slot/slotsUpdates`), extension `transactionSubscribe`/`transactionUnsubscribe`, `block/vote` absents, heartbeat Ping 60 s, Config/secrets redacted, lifecycle adversarial et graphes Cargo finaux validés. [`../prompts/014-V0_2_9_START_PROMPT.md`](../prompts/014-V0_2_9_START_PROMPT.md) devient le contrat actif pour ouvrir Yellowstone gRPC standard/provider-neutral depuis le tag stable `v0.2.8`. La release stable `0.2.9` est conservée dans [`plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md`](plans/016-V0_2_9_YELLOWSTONE_GRPC_PLAN.md) et [`validation/012-V0_2_9_YELLOWSTONE_GRPC.md`](validation/012-V0_2_9_YELLOWSTONE_GRPC.md) : stratégie proto Apache + client KSP/Tonic, moteur N1, standard N2, Config V3, profils PublicNode Mainnet/Testnet authentifiés par `x-token` secret et smoke live `Subscribe` validé sur les deux réseaux. La candidate `0.2.10 — OrbitFlare Yellowstone gRPC` est réconciliée dans [`plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md`](plans/017-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC_PLAN.md) et [`validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md`](validation/013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md) : Devnet `http://devnet.rpc.orbitflare.com:10000`, License Key `ORBIT-*` injectée comme metadata secrète `x-token`, Config Transport V3 inchangée, live `Subscribe -> Slot + Ping` passé, aucun overlay provider et aucun heartbeat supplémentaire. La candidate `0.2.11 — Off-chain price transport` est réconciliée dans [`plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md`](plans/018-V0_2_11_OFFCHAIN_PRICE_TRANSPORT_PLAN.md) et [`validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md`](validation/014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md) : SOL/USD V1, huit adapters REST sans SDK provider, décimal exact, registry/availability/rate limits possédés par Off-chain Transport, Config `std.offchain_transport`, refresh individuel/multiple provider-neutral et smoke live keyless final `7/7` après correction CoinMarketCap V2. [`../crates/ksp-offchain-transport-lib/README.md`](../crates/ksp-offchain-transport-lib/README.md) et [`../crates/ksp-offchain-transport-lib/USAGE.md`](../crates/ksp-offchain-transport-lib/USAGE.md) deviennent les références durables ; la future `ksp-app-solprices-desk` reste une HID sans logique provider. La release stable `0.2.12 — SOL Prices Desk + intégration prix Wallet Desk` est conservée dans [`plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md`](plans/019-V0_2_12_SOL_PRICES_DESK_PLAN.md) et [`validation/015-V0_2_12_SOL_PRICES_DESK.md`](validation/015-V0_2_12_SOL_PRICES_DESK.md) : `ksp-app-solprices-desk` fournit le refresh manuel row/selected/all provider-neutral, états/timestamps exacts et diagnostics sûrs sur ports 1434/1435 ; Wallet Desk réutilise `MarketPriceService::refresh_all` pendant le refresh balance pour afficher une moyenne SOL/USD consumer-owned et l'équivalent USD exact, sans provider concret ni fallback Off-chain. Les gates finaux workspace/live et les trois builds Tauri Linux sont verts avant publication. `0.2.13 — Interface / wire foundation` est réconciliée comme candidate dans [`plans/020-V0_2_13_INTERFACE_PLAN.md`](plans/020-V0_2_13_INTERFACE_PLAN.md) avec la matrice finale candidate [`validation/016-V0_2_13_INTERFACE.md`](validation/016-V0_2_13_INTERFACE.md) : `ksp-interface-lib` expose le `Pubkey` Core, `ProgramAccountMeta` et `ProgramInstruction`, bornés à `255` account metas et `10_240` bytes de data, avec façade crate-root exacte, diagnostics bornés, consumer externe et firewall `Interface -> Core` validés. Le gate technique final `pre.006` est intégralement vert ; [`../crates/ksp-interface-lib/README.md`](../crates/ksp-interface-lib/README.md) et [`../crates/ksp-interface-lib/USAGE.md`](../crates/ksp-interface-lib/USAGE.md) deviennent les références durables avant préparation de publication. Le prompt d’ouverture historique reste [`../prompts/018-V0_2_13_START_PROMPT.md`](../prompts/018-V0_2_13_START_PROMPT.md). `0.2.14 — Program API foundation` est réconciliée comme candidate dans [`plans/021-V0_2_14_PROGRAM_API_PLAN.md`](plans/021-V0_2_14_PROGRAM_API_PLAN.md) avec la matrice finale candidate [`validation/017-V0_2_14_PROGRAM_API.md`](validation/017-V0_2_14_PROGRAM_API.md) : `ksp-program-api` fournit une façade instruction-only ouverte, `ProgramInstructionRecognition`, `ProgramInstructionDecodeOutcome` et `ProgramInstructionDecoder`, avec output associé possédé par l’implémentation, Program Pubkeys opaques/non enregistrés acceptés, canari externe et firewall `Program API -> Core + Interface`. Le gate technique final `pre.006` est intégralement vert ; [`../crates/ksp-program-api/README.md`](../crates/ksp-program-api/README.md) et [`../crates/ksp-program-api/USAGE.md`](../crates/ksp-program-api/USAGE.md) deviennent les références durables avant préparation de publication. Le prompt d’ouverture historique reste [`../prompts/019-V0_2_14_START_PROMPT.md`](../prompts/019-V0_2_14_START_PROMPT.md). `0.3.1 — Store API RAW foundation` est réconciliée comme candidate dans [`plans/022-V0_3_1_STORE_RAW_PLAN.md`](plans/022-V0_3_1_STORE_RAW_PLAN.md) avec la matrice [`validation/018-V0_3_1_STORE_RAW.md`](validation/018-V0_3_1_STORE_RAW.md) : `ksp-store-api` reste Core-only et backend-agnostic, expose les modèles RAW transaction/account et observations, queries cursorisées, outcomes, capabilities fines et lifecycle de rétention/tombstone, sans backend runtime, PostgreSQL, processing ledger ni N2/N3/N4. Le gate `pre.008` a été reconstruit après `cargo clean` et validé sur le workspace complet et les trois builds Tauri ; `pre.009` réconcilie la documentation durable avant la préparation de publication `pre.010`. `0.3.2 — Store/PostgreSQL runtime foundation` est réconciliée comme candidate dans [`plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) avec la matrice finale [`validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) : `ksp-store-lib` fournit la façade runtime backend-neutral, `ksp-store-postgres-lib` possède le backend physique tokio-postgres/Deadpool/Rustls et les migrations metadata-only, tandis que `std.store` sélectionne des targets PostgreSQL séparés par réseau. Le gate technique `pre.010` valide workspace, graphes, trois builds Tauri et la fondation PostgreSQL réelle sur un serveur major 17 ; [`../crates/ksp-store-lib/README.md`](../crates/ksp-store-lib/README.md), [`../crates/ksp-store-lib/USAGE.md`](../crates/ksp-store-lib/USAGE.md), [`../crates/ksp-store-postgres-lib/README.md`](../crates/ksp-store-postgres-lib/README.md) et [`../crates/ksp-store-postgres-lib/USAGE.md`](../crates/ksp-store-postgres-lib/USAGE.md) deviennent les références durables avant la lane de publication. `0.3.3 — Store/PostgreSQL RawTransaction vertical slice` est réconciliée comme candidate dans [`plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md`](plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md) avec la matrice finale [`validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md`](validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md) : les six capabilities `RawTransaction*` sont implémentées côté backend et façade, V001 matérialise canonical/observations/archive avec binding réseau, navigation keyset et rétention atomique, et le gate final rejoue le workspace complet ainsi que le live PostgreSQL 17. `RawAccountState` physique reste réservé à `0.3.4`. `0.3.4 — Store/PostgreSQL RawAccountState` est conservée dans [`plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md`](plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md) et [`validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md`](validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md) ; elle complète la surface RAW backend/façade à dix capabilities. `0.3.5 — Interface acquisition events` est conservée dans [`plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md`](plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md) et [`validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md`](validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md) ; elle ajoute les faits passifs provider-neutral de slot et d'exécution de transaction sans déplacer l'ownership Transport/Store. La candidate `0.3.6 — Job API + RAW transaction backfill` est réconciliée dans [`plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md`](plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md) avec [`validation/023-V0_3_6_JOB_API_BACKFILL.md`](validation/023-V0_3_6_JOB_API_BACKFILL.md) : `ksp-job-api` reste Core-only et runtime-neutral, tandis que `ksp-job-backfill-lib` fournit le premier runtime historique borné vers RAW via Transport observé + façade Store, avec provenance, idempotence, concurrence bornée, frontier/checkpoint contigus, annulation et snapshots latest-value. [`../crates/ksp-job-api/README.md`](../crates/ksp-job-api/README.md), [`../crates/ksp-job-api/USAGE.md`](../crates/ksp-job-api/USAGE.md), [`../crates/ksp-job-backfill-lib/README.md`](../crates/ksp-job-backfill-lib/README.md) et [`../crates/ksp-job-backfill-lib/USAGE.md`](../crates/ksp-job-backfill-lib/USAGE.md) deviennent les références de crate durables. ## Spécifications de formats diff --git a/docs/architecture/002-LAYERS_AND_DEPENDENCIES.md b/docs/architecture/002-LAYERS_AND_DEPENDENCIES.md index c58fe44..b770f39 100644 --- a/docs/architecture/002-LAYERS_AND_DEPENDENCIES.md +++ b/docs/architecture/002-LAYERS_AND_DEPENDENCIES.md @@ -1,5 +1,5 @@ - + # Couches et dépendances KSP @@ -27,7 +27,7 @@ Les niveaux architecturaux N1–N4 décrivent les familles de composants du proj - `ksp-store-api` / `ksp-store-lib` ; - `ksp-materializer-api` / implementations lorsque DECODE s'ouvre ; -- `ksp-job-api` et jobs ; +- `ksp-job-api`, `ksp-job-backfill-lib` puis les jobs concrets introduits par les couches ; - `ksp-worker-api` et workers ; - processors/pipelines spécialisés réellement réutilisés. @@ -138,11 +138,11 @@ Des applications spécialisées sont ajoutées au fur et à mesure pour valider ## Workers et jobs -Un worker est un service continu/autonome ; un job est borné/terminable. +Un worker est un service continu/autonome ; un job est borné/terminable. `ksp-job-api` porte le lifecycle commun et l'observation latest-value sans runtime concret. Le premier job, `ksp-job-backfill-lib`, fournit un runtime single-run historique vers RAW ; il compose Transport et Store sans devenir worker ni service permanent. -Ils utilisent des APIs lifecycle distinctes et ne s'appellent pas entre eux pour transférer les payloads du data plane. +Workers et jobs utilisent des APIs lifecycle distinctes et ne s'appellent pas entre eux pour transférer les payloads du data plane. Un checkpoint de job peut être caller-owned sans devenir automatiquement une persistence de control plane. -Le Store reste le point durable de synchronisation entre couches de processing. +Le Store reste le point durable de synchronisation des données entre couches de processing ; les snapshots Job décrivent l'état opérationnel du job et ne remplacent pas les données RAW persistées. ## Firewall des dépendances externes diff --git a/docs/architecture/003-COMPONENT_CONTRACTS.md b/docs/architecture/003-COMPONENT_CONTRACTS.md index 3364689..4cdb28a 100644 --- a/docs/architecture/003-COMPONENT_CONTRACTS.md +++ b/docs/architecture/003-COMPONENT_CONTRACTS.md @@ -1,5 +1,5 @@ - + # Contrats initiaux des composants KSP @@ -180,13 +180,13 @@ Les workers DECODE/SPECIALIZED sont introduits avec les groupes Program réels, ## Jobs -`ksp-job-api` est la lifecycle API des travaux déclenchés/terminables. +`ksp-job-api` est l'API passive et runtime-neutral des travaux bornés/terminables. Elle possède `JobId`, `JobKindCode`, le lifecycle `Created/Running/Cancelling/Completed/Cancelled/Failed`, l'intention d'annulation coopérative et le contrat latest-value `JobNotification` / `JobSnapshotSource`. Sa dépendance normale reste exclusivement `ksp-core-lib`. -Le premier job retenu est le backfill RAW. +Le premier job concret est `ksp-job-backfill-lib`. Il couvre un backfill historique `RawTransaction` : quatre scopes bornés, découverte/hydratation Transport observée, conversion RAW v1, persistance atomique par `ksp-store-lib`, concurrence bornée, frontier/checkpoint contigus caller-owned, annulation coopérative et snapshots complets sûrs. Il ne dépend ni de Config, ni d'un backend Store concret, ni d'un Worker. -Les jobs de replay suivent ensuite les frontières durables ouvertes : RAW -> CORE, CORE -> DECODE, DECODE -> SPECIALIZED. +Les jobs de replay suivants pourront suivre les frontières durables ouvertes : RAW -> CORE, CORE -> DECODE, DECODE -> SPECIALIZED. Ils ne sont pas forcés d'adopter le contrat métier du backfill RAW ; seuls les contrats vraiment communs appartiennent à `ksp-job-api`. -Aucune `ksp-job-control-lib` n'est prévue sans duplication concrète. +Aucune `ksp-job-control-lib` n'est créée sans duplication concrète. ## Scenarios diff --git a/docs/architecture/004-COMPONENT_INVENTORY.md b/docs/architecture/004-COMPONENT_INVENTORY.md index c430d37..e987ff9 100644 --- a/docs/architecture/004-COMPONENT_INVENTORY.md +++ b/docs/architecture/004-COMPONENT_INVENTORY.md @@ -1,5 +1,5 @@ - + # Inventaire initial des composants KSP @@ -10,6 +10,7 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse ## Statuts - `Stable` — implémenté et publié ; +- `Implémenté` — présent et techniquement validé, en attente de publication stable ; - `Retenu` — composant/contrat décidé ; - `Pressenti` — direction décidée mais périmètre exact à confirmer ; - `À la demande` — créé seulement au premier besoin réel ; @@ -36,11 +37,11 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse | Program API | `ksp-program-api` | API | Stable | `0.2.14` | contrats extensibles Program | | Program impl. | `ksp-program-lib` | lib | Retenu | vertical slices ultérieurs | implementations Program officielles | | Program extension | `ksp-program--lib` | lib externe | À la demande | dès besoin | implementation externe de `ksp-program-api` | -| Store API | `ksp-store-api` | API | Retenu | `0.3.1` | RAW transaction/account, observations, queries, outcomes, rétention et capabilities backend | -| Store runtime | `ksp-store-lib` | lib | Retenu | `0.3.2`–`0.3.4` | fondation puis conformance RAW par slices, dispatch features/config | -| Store PostgreSQL | `ksp-store-postgres-lib` | lib | Retenu | `0.3.2`–`0.3.4` | fondation, RawTransaction puis RawAccountState/complétude | -| Job lifecycle | `ksp-job-api` | API | Retenu | `0.3.6` | lifecycle des jobs terminables | -| Backfill | `ksp-job-backfill-lib` | lib | Retenu | `0.3.6` | Job borné : découverte/hydratation historique vers RAW via Transport + `ksp-store-lib` | +| Store API | `ksp-store-api` | API | Stable | `0.3.1` | RAW transaction/account, observations, queries, outcomes, rétention et capabilities backend | +| Store runtime | `ksp-store-lib` | lib | Stable | `0.3.2`–`0.3.4` | façade backend-neutral et conformance RAW 10/10 | +| Store PostgreSQL | `ksp-store-postgres-lib` | lib | Stable | `0.3.2`–`0.3.4` | backend référence : fondation, RawTransaction et RawAccountState | +| Job lifecycle | `ksp-job-api` | API | Implémenté | `0.3.6` | identité/lifecycle/annulation/notifications latest-value runtime-neutral | +| Backfill | `ksp-job-backfill-lib` | lib | Implémenté | `0.3.6` | backfill `RawTransaction` borné via Transport observé + Store, checkpoint et runtime | | Backfill Desk | nom à fixer | app | Retenu | `0.3.7` | contrôle/inspection du backfill RAW | | Worker lifecycle | `ksp-worker-api` | API | Retenu | fin couche RAW | lifecycle des services continus | | RAW worker | `ksp-worker-raw-retriever` ou nom révisé | worker | Retenu | fin couche RAW | acquisition live vers RAW | @@ -149,9 +150,8 @@ Market Desk est progressive : V1 après les DEX prioritaires, puis enrichissemen ## Questions restantes -- noms exacts de Price Desk et Backfill Desk ; -- surface exacte Yellowstone après audit normatif de `0.2.9-pre.001` ; +- nom exact de Backfill Desk ; - nécessité future d'un pool automatique WS ; -- types exacts `ksp-program-api`/`ksp-materializer-api`/`ksp-store-api` ; +- types exacts `ksp-materializer-api` lors de l'ouverture DECODE ; - nom/packaging précis du premier RAW worker et du CORE normalizer ; - granularité des workers DECODE/SPECIALIZED par groupe. diff --git a/docs/architecture/005-DEPENDENCY_GRAPH.md b/docs/architecture/005-DEPENDENCY_GRAPH.md index 4594b01..9a94c99 100644 --- a/docs/architecture/005-DEPENDENCY_GRAPH.md +++ b/docs/architecture/005-DEPENDENCY_GRAPH.md @@ -1,5 +1,5 @@ - + # Graphe de dépendances KSP @@ -375,10 +375,14 @@ ksp-job-backfill-lib -> ksp-core-lib -> ksp-logging-lib -> ksp-onchain-transport-lib - -> ksp-store-lib # façade backend-neutral ; dépendance sans feature backend imposée + -> ksp-store-lib # default-features = false ; aucun backend imposé + -> futures-util / tokio # runtime privé du job, jamais dans ksp-job-api + -> serde_json / sha2 # canonicalisation RAW v1 et digest ``` -Il remplit RAW et ne décode aucun programme. Il ne dépend pas de Config : l'application supérieure construit explicitement Transport, Store et la requête Job. Le réseau appartient au scope/à l'identité durable ; rôle, provider, endpoint et protocole restent des choix ou provenances d'acquisition et ne deviennent jamais une clé de transaction. +Il remplit RAW et ne décode aucun programme. Il ne dépend pas de Config : la composition supérieure construit explicitement Transport, Store et `BackfillRequest`. Le réseau appartient au scope/à l'identité durable `(network, signature)` ; rôle, provider, endpoint et protocole restent des choix ou provenances d'acquisition et ne deviennent jamais une clé de transaction. + +`ksp-job-api` ne dépend en retour d'aucun runtime ou domaine concret. `ksp-job-backfill-lib` ne dépend ni directement de `ksp-store-api`, ni de `ksp-store-postgres-lib`; la façade Store demeure l'unique frontière runtime de persistance. ## Workers diff --git a/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md b/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md index d6dc6ae..94aae45 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 @@ -78,12 +78,17 @@ D1 RAW Le job : -- utilise `ksp-job-api` pour son lifecycle ; -- gère scope/range/pagination/checkpoint ; -- porte explicitement le réseau logique du Store dans le scope et dans l'identité de chaque transaction candidate ; -- traite rôle HTTP, provider, endpoint et protocole comme sélection/provenance d'acquisition, jamais comme identité transactionnelle ; -- n'effectue aucun décodage Program ; -- n'écrit pas directement des faits CORE/DECODE/SPECIALIZED. +- utilise `ksp-job-api` pour identité, lifecycle, annulation abstraite et observation latest-value ; +- expose `LatestAddress`, `BeforeAddress`, `AfterAddress` et `ExplicitSignatures` avec bornes explicites de pages/candidats/concurrence ; +- porte explicitement le réseau logique du Store dans le scope et dans l'identité `(network, signature)` de chaque transaction candidate ; +- exclut rôle HTTP, provider, endpoint et protocole du fingerprint sémantique et de l'identité transactionnelle ; +- hydrate uniquement via la voie observée `getTransaction`, afin de conserver la provenance du provider/endpoint réellement gagnant ; +- produit un RAW v1 canonique déterministe puis persiste transaction + observation atomiquement via `ksp-store-lib` en mode normal ; +- respecte les tombstones `Purged`, distingue missing/conflit/idempotence et ne pré-lit pas le Store avant hydratation ; +- limite les hydrations concurrentes, avance seulement une frontier contiguë durable et retourne un checkpoint opaque caller-owned ; +- arrête coopérativement les nouvelles admissions lors d'une annulation et draine une persistence Store déjà soumise ; +- publie des snapshots latest-value sûrs sans payload RAW ni secrets/URLs Transport ; +- n'effectue aucun décodage Program et n'écrit aucun fait CORE/DECODE/SPECIALIZED. ### Worker RAW live @@ -240,31 +245,27 @@ Une capability comme `reconfigure` n'est pas imposée à tous les workers. ## Job API -`ksp-job-api` reste distinct de Worker API. +`ksp-job-api` reste distinct de Worker API et volontairement runtime-neutral. -Concepts candidats : +Contrats communs actuels : ```text JobId -JobDescriptor +JobKindCode JobState -JobProgress -JobOutcome -JobCapabilities +JobCompletion +JobLifecycle +JobCancellationToken +JobNotificationSequence +JobNotification +JobSnapshotSource ``` -Un job est borné/terminable et peut exposer selon besoin : +Le lifecycle commun est borné aux transitions explicitement validées entre `Created`, `Running`, `Cancelling` et les états terminaux `Completed(Complete|Partial)`, `Cancelled`, `Failed`. Il ne définit ni `pause`, ni `resume`, ni scheduler, ni runtime d'exécution générique. -```text -start -pause -resume -cancel -status -progress -``` +`JobSnapshotSource` suit une sémantique latest-value : un listener lit une valeur complète courante puis peut attendre une séquence plus récente ; les valeurs intermédiaires peuvent être coalescées. Le snapshot métier reste possédé par le job concret. -Les types exacts sont décidés à `0.3.6` avec le premier vrai backfill, après clôture des trois slices Store/PostgreSQL `0.3.2`–`0.3.4` et de la tranche Interface `0.3.5`. +L'annulation commune est une intention coopérative. Le job concret décide quelles attentes peuvent être interrompues et quelles opérations engagées doivent être drainées. Aucune `ksp-job-control-lib` n'est créée sans duplication concrète. @@ -309,15 +310,11 @@ Les états exacts seront définis avec le premier processor durable, mais doiven ## Reprise après crash -Un worker/job doit reconstruire son état depuis : +Un worker/job qui promet une reprise après crash doit reconstruire son état depuis des données durables : inputs persistés, claims/leases/outcomes lorsqu'ils existent, cursors/checkpoints et versions de processor. -- inputs persistés ; -- claims/leases ; -- outcomes ; -- cursors/checkpoints ; -- versions de processor. +Le premier backfill RAW retourne un `BackfillCheckpoint` caller-owned lié au `JobId` et au fingerprint de scope. La crate ne persiste pas ce checkpoint elle-même : tant qu'un caller ne l'enregistre pas durablement, il s'agit d'une primitive de reprise contrôlée, pas d'une promesse crash-safe automatique. -La mémoire du processus ne constitue jamais l'unique source de reprise. +La mémoire du processus ne constitue jamais l'unique source d'une garantie de reprise durable. ## Logging @@ -346,7 +343,9 @@ ksp-job-backfill-lib -> ksp-core-lib -> ksp-logging-lib -> ksp-onchain-transport-lib - -> ksp-store-lib # façade Store ; aucun backend imposé par la crate Job + -> ksp-store-lib # façade Store ; default-features=false côté Job + -> futures-util/tokio # runtime privé de Backfill + -> serde_json/sha2 # RAW v1 canonique + digest ``` ### RAW worker @@ -393,8 +392,7 @@ selon les capacités réellement introduites. - nom final de la crate pipeline RAW si la réutilisation justifie une crate dédiée ; - nom final du worker RAW ; -- contrat exact de `ksp-job-api` ; -- modèle de claim/lease PostgreSQL ; +- modèle de claim/lease PostgreSQL pour les futurs processors continus ; - taille de batch et stratégie backpressure ; - découpage des workers DECODE/SPECIALIZED par groupe lorsque les premiers groupes existent ; - mécanisme IPC des applications de contrôle futures. diff --git a/docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md b/docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md index 3214ea6..d214b93 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 @@ -356,15 +356,13 @@ Le choix du mécanisme exact est reporté à la release fonctionnelle concernée ## Jobs -Les jobs restent distincts des workers. +Les jobs restent distincts des workers. `ksp-job-api` fournit les contrats runtime-neutral communs ; le premier job concret `ksp-job-backfill-lib` est une bibliothèque single-run, pas un service worker autonome. -Une app spécialisée peut déclencher/suivre un job concret via `ksp-job-api` et la composition adaptée. +Une app spécialisée peut construire les ressources Config/Transport/Store, créer un `BackfillJobRuntime`, conserver son `BackfillJobHandle`, observer les snapshots latest-value et demander une annulation coopérative. Elle ne réimplémente ni découverte/hydratation, ni frontier/checkpoint, ni persistance RAW. -Aucune `ksp-job-control-lib` générique n'est introduite. +Aucune `ksp-job-control-lib` générique n'est introduite. Le handle concret suffit tant qu'aucune duplication entre plusieurs jobs ne justifie une couche de gouvernance commune. -Le fait qu'un worker soit un process/service indépendant ne force pas les jobs à adopter exactement le même modèle de déploiement. - -Le packaging/exécution des jobs sera déterminé avec les premiers jobs réels. +Le fait qu'un worker soit un process/service indépendant ne force pas les jobs à adopter exactement le même modèle de déploiement. Le packaging des futurs jobs reste décidé par leur besoin réel ; le premier backfill prouve qu'un runtime de bibliothèque composable est suffisant pour un job déclenché par une application. ## Scenarios : logique dans la bibliothèque @@ -547,7 +545,7 @@ control/application adapters | +--> ksp-worker-control-lib --> ksp-worker-api --> worker service | - +--> ksp-job-api -----------> concrete job + +--> ksp-job-api -----------> ksp-job-backfill-lib / concrete jobs | +--> ksp-scenario--lib ``` diff --git a/docs/plans/000-README.md b/docs/plans/000-README.md index f173d5a..345c70b 100644 --- a/docs/plans/000-README.md +++ b/docs/plans/000-README.md @@ -1,5 +1,5 @@ - + # Plans KSP @@ -33,6 +33,9 @@ Un plan décrit le périmètre, les décisions déjà acquises, les questions ou - [`022-V0_3_1_STORE_RAW_PLAN.md`](022-V0_3_1_STORE_RAW_PLAN.md) — plan candidat réconcilié de `0.3.1 — Store API RAW foundation`; il fixe `ksp-store-api` seul, les modèles transaction/account + observations, queries/outcomes/capabilities, rétention/tombstone, la frontière event-only/Interface et le report de `ksp-store-lib` + PostgreSQL à `0.3.2`. - [`023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md`](023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md) — plan candidat réconcilié de `0.3.2 — Store/PostgreSQL runtime foundation`; il fixe le split façade/backend, `std.store` multi-target réseau-spécifique, tokio-postgres/Deadpool/Rustls, migrations metadata-only, health/readiness, live PostgreSQL et les reports des vertical slices RAW vers `0.3.3`/`0.3.4`. - [`024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md`](024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md) — plan candidat réconcilié de `0.3.3 — Store/PostgreSQL RawTransaction vertical slice`; il fixe V001, binding réseau, mappings entiers exacts, écritures/observations atomiques, pagination keyset/cursor, rétention/tombstone/ForceRehydrate, hardening et preuve PostgreSQL 17. +- [`025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md`](025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md) — plan historique clôturé de `0.3.4 — Store/PostgreSQL RawAccountState + complétude RAW`; il complète le backend/façade à dix capabilities RAW et ferme V002. +- [`026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md`](026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md) — plan historique clôturé de `0.3.5 — Interface acquisition events`; il fixe les faits passifs provider-neutral `SlotLifecycleEvent` et `TransactionExecutionEvent` sans runtime ni persistence. +- [`027-V0_3_6_JOB_API_BACKFILL_PLAN.md`](027-V0_3_6_JOB_API_BACKFILL_PLAN.md) — plan candidat de `0.3.6 — Job API + RAW transaction backfill`; il fixe le contrat Job runtime-neutral, les quatre scopes historiques, RAW v1, provenance observée, persistance Store normale, concurrence/frontier/checkpoint et runtime latest-value annulable. Le `pre.001` de chaque release fonctionnelle peut introduire son propre plan détaillé lorsque la release s'ouvre. diff --git a/docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md b/docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md index 95983fe..56b6537 100644 --- a/docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md +++ b/docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md @@ -1,5 +1,5 @@ - + # Plan v0.3.6 — Job API et premier backfill RAW @@ -528,17 +528,17 @@ La tranche n'élargit aucune API de production et ne modifie aucune dépendance ### `pre.011` — Gate technique final -**Statut : matérialisé ; gate opérateur final à exécuter.** +**Statut : réalisé ; gate opérateur final intégralement vert.** Budget cible : **15-20 min**. Entrée : hardening `pre.010` intégralement vert avec 47 unitaires + 20 canaries. La tranche ne rouvre aucun code, test fonctionnel, manifeste de crate, dépendance, README/USAGE, CHANGELOG/ROADMAP ou prompt suivant ; elle synchronise uniquement la version workspace, le plan, la validation et son delta. -Le gate final rejoue le workspace en configuration large : format en mode check, audits Rust/Markdown, `cargo check --workspace`, Clippy `--all-targets --all-features -- -D warnings`, tests `--workspace --all-targets --all-features`, puis graphes de `ksp-job-api`, `ksp-job-backfill-lib` et doublons workspace. Les arbres sont ici justifiés par la clôture technique finale même sans nouveau changement de dépendances dans `pre.011`. Le smoke PostgreSQL reste opt-in et conditionnel à une URI dédiée explicitement disponible ; son absence ne bloque pas la preuve déterministe. Sortie attendue : preuve technique finale consignée, sans réconciliation documentaire durable avant `pre.012`. +Le gate final rejoue le workspace en configuration large : format en mode check, audits Rust/Markdown, `cargo check --workspace`, Clippy `--all-targets --all-features -- -D warnings`, tests `--workspace --all-targets --all-features`, puis graphes de `ksp-job-api`, `ksp-job-backfill-lib` et doublons workspace. Les arbres sont ici justifiés par la clôture technique finale même sans nouveau changement de dépendances dans `pre.011`. Le gate opérateur est vert : audits propres, check/Clippy sans warning, `1_404` tests passés et `15` tests explicitement ignorés/opt-in sans aucun échec ; les graphes Job restent conformes et l'inventaire `cargo tree --duplicates` a été revu sans défaut propre au vertical Job nécessitant une correction. Le smoke PostgreSQL dédié n'a pas été exécuté faute d'URI explicitement fournie et reste non bloquant. Sortie : preuve technique finale fermée avant réconciliation documentaire. ### `pre.012` — Réconciliation documentaire finale -**Statut : planifié.** +**Statut : matérialisé ; gate documentaire à exécuter.** -Budget cible : **10-15 min**. Entrée : gate technique final vert. Aligner architecture, index, README, USAGE, plan et validation sur la surface prouvée. Sortie : documentation durable cohérente, sans CHANGELOG, ROADMAP ni prompt suivant. +Budget cible : **10-15 min**. Entrée : gate technique final vert. La tranche crée les README/USAGE durables de `ksp-job-api` et `ksp-job-backfill-lib`, réconcilie les architectures Jobs/Backfill, les index `docs/`, le README racine, ce plan et la validation sur la surface réellement prouvée. Elle documente notamment le lifecycle Job exact, la sémantique latest-value, les quatre scopes, l'identité `(network, signature)`, la provenance observée, RAW v1, la persistence Store normale, la frontier/checkpoint caller-owned, les limites de reprise crash-safe et l'annulation avec drainage Store. Sortie attendue : documentation durable cohérente et version-neutral côté USAGE, sans CHANGELOG, ROADMAP ni prompt suivant. ### `pre.013` — Préparation de publication minimale diff --git a/docs/validation/000-README.md b/docs/validation/000-README.md index 4195412..711efdc 100644 --- a/docs/validation/000-README.md +++ b/docs/validation/000-README.md @@ -1,5 +1,5 @@ - + # Validations KSP @@ -29,3 +29,6 @@ Documents : - [`018-V0_3_1_STORE_RAW.md`](018-V0_3_1_STORE_RAW.md) — matrice candidate finale de `0.3.1 — Store API RAW foundation` : modèles transaction/account, observations, capabilities backend, pagination sans policy executor, outcomes, rétention/tombstone, hardening, gate complet `pre.008` et reports explicites vers `0.3.2+`. - [`019-V0_3_2_STORE_POSTGRES_FOUNDATION.md`](019-V0_3_2_STORE_POSTGRES_FOUNDATION.md) — matrice candidate finale de `0.3.2 — Store/PostgreSQL runtime foundation` : feature graph, settings/Config, pool/TLS, migrations metadata-only, health, hardening, graphes, builds Tauri et preuve PostgreSQL réelle major 17. - [`020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md`](020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md) — matrice candidate finale de `0.3.3 — Store/PostgreSQL RawTransaction vertical slice` : six capabilities backend/façade, V001 et compatibilité schéma, atomicité/idempotence/conflit, keyset/cursor, rétention/races/rehydrate, hardening et replay PostgreSQL 17 final. +- [`021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md`](021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md) — matrice finale de `0.3.4 — RawAccountState + complétude RAW` : quatre capabilities account supplémentaires, V002, pagination/idempotence et conformance Store 10/10. +- [`022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md`](022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md) — matrice finale de `0.3.5 — Interface acquisition events` : événements passifs slot/transaction, façade crate-root, bornes/debug et firewall Interface. +- [`023-V0_3_6_JOB_API_BACKFILL.md`](023-V0_3_6_JOB_API_BACKFILL.md) — matrice candidate de `0.3.6 — Job API + RAW transaction backfill` : lifecycle/notifications runtime-neutral, scopes, provenance, RAW v1, Store/idempotence, concurrence/checkpoint, annulation/snapshots, hardening externe et gate workspace final. diff --git a/docs/validation/023-V0_3_6_JOB_API_BACKFILL.md b/docs/validation/023-V0_3_6_JOB_API_BACKFILL.md index 3bfb723..c6be7c8 100644 --- a/docs/validation/023-V0_3_6_JOB_API_BACKFILL.md +++ b/docs/validation/023-V0_3_6_JOB_API_BACKFILL.md @@ -1,5 +1,5 @@ - + # Validation v0.3.6 — Job API et premier backfill RAW @@ -71,7 +71,8 @@ Aucune entrée absolue, traversée, avec séparateur inversé ou lien symbolique - [X] Les documents d'architecture courants sont réconciliés sur `ksp-job-backfill-lib`; les anciens plans historiques restent historiques et ne sont pas réécrits. - [X] `ksp-job-api` et `ksp-job-backfill-lib` sont obligatoires en parallèle dans la release finale. - [X] Worker API, application et pipeline RAW partagé sont explicitement hors v0.3.6. -- [ ] Architecture, README, roadmap et contrats finaux réconciliés avant publication. +- [X] Architecture, README, index et contrats de crate durables réconciliés sur la surface finale prouvée. +- [ ] ROADMAP et CHANGELOG synchronisés uniquement dans la lane de publication `pre.013`. ## 5. Contrat `ksp-job-api` @@ -261,20 +262,34 @@ Les arbres Cargo sont rejoués ici au titre de la clôture technique finale, mê Le smoke PostgreSQL reste conditionnel à une URI dédiée explicitement disponible. En l'absence d'environnement live fourni, il reste non exécuté et non bloquant ; aucune réussite live n'est inventée. -**Statut : matérialisé ; gate opérateur final à exécuter.** +**Statut : réalisé ; gate opérateur final intégralement vert.** -## 16. Preuves d'intégration et fermeture +Preuve opérateur : `cargo fmt --all -- --check`, audits Rust/Markdown, `cargo check --workspace`, Clippy workspace/all-targets/all-features avec `-D warnings`, puis `cargo test --workspace --all-targets --all-features` passent. Le run agrège `1_404` tests passés, `0` échec et `15` tests ignorés explicitement opt-in/operator-only. Les graphes normal/features de `ksp-job-api` et `ksp-job-backfill-lib` sont cohérents ; `cargo tree --duplicates` a été exécuté et revu. Aucun smoke PostgreSQL dédié n'est revendiqué sans URI explicitement fournie. + +## 16. Réconciliation documentaire finale `pre.012` + +- [X] README racine réconcilié sans historique de prerelease. +- [X] `ksp-job-api/README.md` et `USAGE.md` décrivent la façade runtime-neutral, le lifecycle, l'annulation et le contrat latest-value. +- [X] `ksp-job-backfill-lib/README.md` et `USAGE.md` décrivent scopes, request bounds, runtime, provenance, Store, checkpoint, annulation et reprise sans note de version. +- [X] Architectures Layers, Contracts, Inventory, Dependency Graph, Acquisition/Jobs et Apps/Control réconciliées sur le premier job concret. +- [X] Index `docs/`, plans et validations synchronisés jusqu'aux documents `027` / `023`. +- [X] Les documents durables distinguent checkpoint caller-owned et garantie de reprise crash-safe ; aucune persistence automatique du checkpoint n'est promise. +- [X] CHANGELOG, ROADMAP et prompt suivant restent hors de cette tranche. + +**Statut : matérialisé ; gate documentaire à exécuter.** + +## 17. Preuves d'intégration et fermeture - [X] Fake Transport et fake Store déterministes sans backend direct exécutés avec succès au gate `pre.007`; fake processor concurrent `pre.008-fix.001` exécuté avec succès. -- [ ] Vertical découverte, hydratation, conversion, persistance et observation couvert. -- [ ] Smoke Devnet plus PostgreSQL configuré exécuté si l'environnement explicite est disponible. -- [ ] Aucun endpoint payant, credential ou donnée sensible requis par les tests normaux. -- [ ] Gates technique, documentaire et de publication séparés. -- [ ] CHANGELOG et ROADMAP alignés seulement après preuve technique. -- [ ] Archives de release minimales et vérifiées. +- [X] Vertical découverte, hydratation, conversion, persistance, observation, concurrence, checkpoint et runtime couvert par les gates déterministes. +- [ ] Smoke Devnet plus PostgreSQL configuré exécuté si l'environnement explicite est disponible ; non bloquant sans environnement fourni. +- [X] Aucun endpoint payant, credential ou donnée sensible requis par les tests normaux. +- [X] Gates technique, documentaire et de publication séparés. +- [ ] CHANGELOG et ROADMAP alignés seulement après preuve technique, dans `pre.013`. +- [X] Archives de prerelease minimales et vérifiées jusqu'au gate technique final. - [ ] Version stable publiée uniquement après tous les critères obligatoires. -## 17. Règle de vérité +## 18. Règle de vérité Une case n'est cochée que par une preuve effectivement exécutée ou un audit effectivement réalisé. L'absence de `cargo`, de PostgreSQL configuré ou d'accès live est rapportée comme non exécutée ; elle n'est jamais convertie en succès implicite.