From 80be36bfdd36d45c48d9a91e133d62a0fa9d64e7 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Mon, 31 Aug 2026 13:07:56 +0200 Subject: [PATCH] v0.3.5-pre.007 --- Cargo.toml | 4 +- crates/ksp-interface-lib/README.md | 110 ++++++++++--- crates/ksp-interface-lib/USAGE.md | 109 +++++++++++-- deltas/0.3.5/pre.007.md | 154 ++++++++++++++++++ docs/IDEAS.md | 10 +- .../002-LAYERS_AND_DEPENDENCIES.md | 4 +- docs/architecture/003-COMPONENT_CONTRACTS.md | 8 +- docs/architecture/004-COMPONENT_INVENTORY.md | 4 +- docs/architecture/005-DEPENDENCY_GRAPH.md | 11 +- docs/architecture/006-WIRE_AND_PROGRAM.md | 34 +++- .../009-ACQUISITION_WORKERS_AND_JOBS.md | 5 +- ...0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md | 17 +- ...022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md | 84 +++++++++- 13 files changed, 479 insertions(+), 75 deletions(-) create mode 100644 deltas/0.3.5/pre.007.md diff --git a/Cargo.toml b/Cargo.toml index 52ebad3..61f8b65 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 389 +# version: 390 [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-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.5-pre.6" +version = "0.3.5-pre.7" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/crates/ksp-interface-lib/README.md b/crates/ksp-interface-lib/README.md index 34be8b0..6985eaa 100644 --- a/crates/ksp-interface-lib/README.md +++ b/crates/ksp-interface-lib/README.md @@ -1,9 +1,11 @@ - + # ksp-interface-lib -`ksp-interface-lib` est la façade wire officielle KSP destinée aux contrats passifs partagés par les implémentations Program Solana officielles ou externes. La crate expose uniquement des structures de représentation/admission ; elle ne possède ni transport, ni exécution, ni persistence, ni comportement métier Program. +`ksp-interface-lib` possède les contrats passifs KSP qui doivent être partagés entre plusieurs composants sans imposer leur runtime d'origine. Sa surface couvre actuellement deux familles distinctes : les contrats wire Program génériques et un petit ensemble de faits d'acquisition provider-neutral dont la sémantique commune a été démontrée. + +La crate reste une façade de représentation. Elle ne possède ni transport réseau, ni event bus, ni worker/job, ni persistence, ni exécution, ni comportement métier Program. ## Ownership @@ -15,9 +17,9 @@ Error / ErrorCode / Result Program IDs fondamentaux ``` -`Pubkey` est réexporté depuis le crate-root Interface afin qu'un consumer wire n'introduise aucun wrapper d'identité parallèle. Les Program IDs restent possédés et répertoriés par Core. +`Pubkey` est réexporté depuis le crate-root Interface afin qu'un consumer n'introduise aucun wrapper d'identité parallèle. Les Program IDs restent possédés et répertoriés par Core. -La dependency direction candidate `0.2.13` reste strictement : +Le graphe normal reste strictement : ```text ksp-interface-lib @@ -25,9 +27,11 @@ ksp-interface-lib └── solana-pubkey ``` -## Surface publique `0.2.13` +La crate ne possède aucune feature Cargo, aucune `dev-dependency` et aucune `build-dependency` runtime propre. -La façade crate-root expose exactement : +## Surface publique + +La façade crate-root expose : ```text Pubkey @@ -36,10 +40,17 @@ MAX_PROGRAM_INSTRUCTION_ACCOUNTS ProgramInstruction MAX_PROGRAM_INSTRUCTION_DATA_LEN ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED +SlotLifecycleStage +SlotLifecycleEvent +TransactionSignature +TransactionExecutionOutcome +TransactionExecutionEvent ``` Aucun module interne n'est public. +## Contrats Program passifs + ### `ProgramAccountMeta` `ProgramAccountMeta` représente un compte ordonné d'une instruction avec : @@ -68,16 +79,14 @@ data: Vec Les cas vides sont valides et une `program_id` inconnue du registry KSP reste admissible. -## Bornes d'admission - -Interface applique deux limites locales : +### Bornes d'admission | Limite | Valeur | |------------------------------------|----------| | `MAX_PROGRAM_INSTRUCTION_ACCOUNTS` | `255` | | `MAX_PROGRAM_INSTRUCTION_DATA_LEN` | `10_240` | -Ces valeurs sont des **bornes d'admission Interface**. Elles ne constituent pas une garantie qu'une instruction donnée tient dans toutes les contraintes d'une transaction Solana top-level. La limite CPI de comptes uniques n'est notamment pas transformée en règle artificielle sur la liste d'account metas. +Ces valeurs sont des **bornes d'admission Interface**. Elles ne constituent pas une garantie qu'une instruction donnée respecte à elle seule toutes les contraintes d'une transaction Solana complète. Un dépassement utilise le code commun : @@ -89,21 +98,74 @@ Le contexte d'erreur est limité aux métadonnées sûres `field`, `actual_len` Le `Debug` de `ProgramInstruction` est volontairement borné : il affiche `program_id`, `account_count` et `data_len`, jamais les accounts complets ni les octets du payload. +## Faits passifs d'acquisition + +Les événements Interface sont des **projections provider-neutral supplémentaires**. Ils ne remplacent jamais les DTOs riches de `ksp-onchain-transport-lib` et ne deviennent jamais la source de vérité durable d'un backlog. + +La conversion depuis un DTO HTTP/WS/gRPC/provider appartient à la composition ou au consumer qui connaît les deux contrats. `ksp-interface-lib` ne dépend donc pas de Transport. + +### `SlotLifecycleEvent` + +`SlotLifecycleEvent` conserve exactement : + +```text +slot: u64 +stage: SlotLifecycleStage +``` + +Les stages actuellement représentés sont : + +```text +Processed +FirstShredReceived +Completed +CreatedBank +Dead +OptimisticallyConfirmed +Rooted +``` + +`SlotLifecycleStage` est `#[non_exhaustive]` afin qu'un consumer externe traite explicitement l'évolution future de l'enum. + +Parent, timestamp, diagnostics de slot mort, source/provider, filter/session metadata et autres détails Transport ne sont pas copiés dans ce contrat minimal. + +### `TransactionExecutionEvent` + +`TransactionExecutionEvent` conserve exactement : + +```text +slot: u64 +signature: TransactionSignature +outcome: TransactionExecutionOutcome +``` + +`TransactionSignature` contient exactement les 64 bytes canoniques déjà décodés d'une signature Solana. Son `Debug` ne rend pas les bytes. + +`TransactionExecutionOutcome` distingue uniquement : + +```text +Succeeded +Failed +``` + +L'enum est `#[non_exhaustive]`. Le contrat ne contient aucun log, payload RAW, erreur provider, commitment, provenance, network id, source metadata ni détail d'exécution arbitraire. Une source ambiguë ou insuffisante doit rester dans son owner Transport au lieu de forcer un événement Interface. + ## Codecs et runtime -La foundation `0.2.13` n'ajoute aucun codec par réflexe : +La crate n'ajoute aucun codec ou runtime par réflexe : ```text serde / serde_json absents -borsh absent -wincode absent -bincode absent -solana-instruction absent +borsh absent tant qu'aucun wire réel ne le requiert +wincode absent tant qu'aucun wire réel ne le requiert +bincode interdit pour les codecs wire KSP +transport/runtime réseau absent +logging runtime absent ``` -Des codecs/layouts/discriminants spécifiques pourront être ajoutés ultérieurement uniquement lorsqu'un vertical Program réel en démontre le besoin et que leur ownership wire appartient bien à Interface. +Des codecs/layouts/discriminants spécifiques peuvent être ajoutés uniquement lorsqu'un protocole réel en démontre le besoin et que leur ownership wire appartient bien à Interface. -La crate ne produit aucun événement runtime. Elle ne dépend donc pas de `ksp-logging-lib` et ne possède ni `constants.rs` ni `TRACING_TARGET`. Si un futur comportement Interface exige réellement du logging, le runtime devra passer par la façade Logging KSP plutôt que par une dépendance directe à Tracing. +Les événements passifs ne constituent pas un comportement runtime. La crate ne dépend donc pas de `ksp-logging-lib` et ne possède ni `constants.rs` ni `TRACING_TARGET`. ## Frontières @@ -112,20 +174,20 @@ La crate ne produit aucun événement runtime. Elle ne dépend donc pas de `ksp- ```text RPC / WebSocket / gRPC provider DTOs Transport -wallet / signature +sessions / reconnect / backpressure Config / environnement -persistence / Store +persistence / Store / cursor / retention +notifications post-commit Store +worker / job / scheduler / event bus Program decoding / recognition / proofs execution policy / signers -transaction replay / CPI path / runtime logs -lifecycle réseau +RawTransaction / RawAccountState ``` -La foundation Program API est reportée à `0.2.14`. Les wires génériques d'acquisition/CORE restent reportés à `0.3.2+`. +Les données persistantes/replayables restent dans `ksp-store-api`. Les notifications post-commit de données persistées restent un contrat Store API lorsqu'un publisher/consumer réel les justifie. Les faits réseau riches restent Transport-owned. ## Références - [Usage public](USAGE.md) -- [Plan `0.2.13`](../../docs/plans/020-V0_2_13_INTERFACE_PLAN.md) -- [Validation `0.2.13`](../../docs/validation/016-V0_2_13_INTERFACE.md) - [Architecture Wire + Program](../../docs/architecture/006-WIRE_AND_PROGRAM.md) +- [Architecture Acquisition/Workers/Jobs](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md) diff --git a/crates/ksp-interface-lib/USAGE.md b/crates/ksp-interface-lib/USAGE.md index 9af5c9e..7bd1ccc 100644 --- a/crates/ksp-interface-lib/USAGE.md +++ b/crates/ksp-interface-lib/USAGE.md @@ -1,9 +1,9 @@ - + # Usage de ksp-interface-lib -Cette page décrit la façade publique matérialisée par `0.2.13`. Les modules internes ne font pas partie du contrat consommable : utiliser uniquement les exports du crate-root. +Cette page décrit l'utilisation durable de la façade publique. Les modules internes ne font pas partie du contrat consommable : utiliser uniquement les exports du crate-root. ## Construire des account metas @@ -52,9 +52,9 @@ match result { L'ordre et les doublons des accounts sont conservés. Les octets `data` restent opaques : `ProgramInstruction` ne les sérialise, désérialise ni interprète. -Les `Vec` fournis à `try_new` sont consommés par la structure après validation des bornes ; aucun clone ou reformatage interne n'est requis par le contrat actuel. +Les `Vec` fournis à `try_new` sont consommés par la structure après validation des bornes ; aucun clone ou reformatage interne n'est requis par le contrat. -## Bornes +## Respecter les bornes Program Les limites publiques sont : @@ -63,9 +63,9 @@ assert_eq!(ksp_interface_lib::MAX_PROGRAM_INSTRUCTION_ACCOUNTS, 255); assert_eq!(ksp_interface_lib::MAX_PROGRAM_INSTRUCTION_DATA_LEN, 10_240); ``` -`255` account metas et `10_240` bytes de data sont admis. `256` account metas ou `10_241` bytes sont refusés par `try_new` avant création d'un `ProgramInstruction` valide. +`255` account metas et `10_240` bytes de data sont admis. `256` account metas ou `10_241` bytes sont refusés par `ProgramInstruction::try_new`. -Ces limites sont des bornes locales Interface et ne promettent pas qu'une instruction admise respecte à elle seule toutes les contraintes de taille/account-set d'une transaction Solana complète. +Ces limites sont locales à Interface et ne promettent pas qu'une instruction admise respecte à elle seule toutes les contraintes d'une transaction Solana complète. ## Observer une erreur de limite @@ -92,31 +92,108 @@ maximum_len Le contenu du payload et les account metas arbitraires ne sont pas projetés dans le diagnostic. -## Debug borné +## Construire un événement de lifecycle de slot -Le `Debug` de `ProgramInstruction` contient uniquement : +Un producer/composer qui a déjà établi la correspondance sémantique avec son DTO Transport peut construire le fait passif partagé : -```text -program_id -account_count -data_len +```rust +let event = ksp_interface_lib::SlotLifecycleEvent::new( + 42, + ksp_interface_lib::SlotLifecycleStage::Processed, +); + +assert_eq!(event.slot(), 42); +assert_eq!(event.stage(), ksp_interface_lib::SlotLifecycleStage::Processed); ``` -Il ne faut donc pas attendre de ce rendu une sérialisation wire ou un dump du payload. +Les stages actuellement disponibles sont : + +```text +Processed +FirstShredReceived +Completed +CreatedBank +Dead +OptimisticallyConfirmed +Rooted +``` + +Un consumer externe doit traiter `SlotLifecycleStage` comme une enum évolutive `#[non_exhaustive]` et prévoir un fallback dans ses `match`. + +Le type ne contient volontairement ni timestamp, ni parent, ni diagnostic, ni source/provider, ni identifiant de subscription. + +## Construire un événement d'exécution de transaction + +Une signature doit d'abord être disponible sous sa forme canonique de 64 bytes : + +```rust +let signature = ksp_interface_lib::TransactionSignature::new([7_u8; 64]); + +let event = ksp_interface_lib::TransactionExecutionEvent::new( + 123, + signature, + ksp_interface_lib::TransactionExecutionOutcome::Succeeded, +); + +assert_eq!(event.slot(), 123); +assert_eq!(event.signature().as_bytes(), &[7_u8; 64]); +assert_eq!( + event.outcome(), + ksp_interface_lib::TransactionExecutionOutcome::Succeeded, +); +``` + +`TransactionExecutionOutcome` distingue uniquement `Succeeded` et `Failed` et reste `#[non_exhaustive]`. + +Le `Debug` de `TransactionSignature` et de `TransactionExecutionEvent` n'affiche pas les bytes de signature. + +## Convertir depuis Transport + +Ne pas ajouter `ksp-onchain-transport-lib` comme dépendance de `ksp-interface-lib` pour fournir des `From`. + +La conversion appartient au composant qui connaît les deux côtés : + +```text +Transport DTO riche + | + | conversion explicite dans composition/consumer + v +Interface event passif minimal +``` + +Ne construire un événement Interface que si la source fournit suffisamment d'information pour le fait commun exact. Si l'état est ambigu, conserver le DTO dans son owner Transport ou déclencher une hydratation adaptée ; ne pas inventer de valeur par défaut. + +## Ne pas utiliser les événements comme stockage durable + +`SlotLifecycleEvent` et `TransactionExecutionEvent` sont des faits passifs, pas des modèles RAW replayables. + +Ils ne remplacent pas : + +```text +RawTransaction +RawTransactionObservation +RawAccountState +RawAccountObservation +Store backlog / cursor / retention +``` + +Les consumers qui ont besoin de reprise après crash ou de replay doivent s'appuyer sur `ksp-store-lib`/`ksp-store-api` selon leur responsabilité, pas sur un event Interface en mémoire. ## Dépendances à ne pas ajouter côté consumer -Un consumer de la façade Interface n'a pas besoin d'ajouter un SDK Program Solana uniquement pour reconstruire `ProgramInstruction`. La crate utilise le `Pubkey` canonique partagé avec Core et conserve son propre contrat passif. +Un consumer de la façade Interface n'a pas besoin d'ajouter un SDK Program Solana uniquement pour reconstruire `ProgramInstruction`, ni un runtime Transport pour manipuler les événements passifs déjà normalisés. -La foundation ne fournit volontairement pas : +La crate ne fournit volontairement pas : ```text serde générique Borsh / Wincode générique solana-instruction interop automatique transport réseau +converters provider automatiques Program decoder/preparer signing/execution +persistence/event bus ``` -Ces surfaces doivent être introduites dans leur owner respectif lorsqu'un cas réel le justifie, pas comme dépendances implicites d'un consumer Interface. +Ces surfaces doivent être introduites dans leur owner respectif lorsqu'un cas réel le justifie. diff --git a/deltas/0.3.5/pre.007.md b/deltas/0.3.5/pre.007.md new file mode 100644 index 0000000..ac517a7 --- /dev/null +++ b/deltas/0.3.5/pre.007.md @@ -0,0 +1,154 @@ +# Delta `0.3.5-pre.007` + +## Objet + +Réconcilier la documentation durable avec la surface Interface réellement acquise après le gate technique final propre de `pre.006`, sans rouvrir le code ni les contrats publics. + +## Base + +```text +0.3.5-pre.006 +workspace.package.version = 0.3.5-pre.6 +``` + +La base opérateur inclut les corrections locales de numéros d'en-tête signalées après l'overlay `pre.006` : + +```text +Cargo.toml header 389 +docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md header 8 +``` + +Ces corrections d'en-tête ne changent pas le contenu fonctionnel du gate validé. + +## Gate d'entrée + +Le gate `pre.006` est intégralement propre : + +```text +General Rust rule audit: clean +Rust export completeness audit: 0 candidate(s) +KSP workspace Rust rule audit: clean +Markdown table audit: clean (240 table(s), 145 file(s)) +cargo check --workspace: PASS +cargo clippy --workspace --all-targets: PASS +cargo test -p ksp-interface-lib: PASS +cargo test --workspace: PASS +``` + +Les graphes confirment : + +```text +ksp-interface-lib -> ksp-core-lib uniquement +aucune feature Interface +aucune dev/build dependency Interface +aucun duplicate dependency nouveau imputable à 0.3.5 +``` + +Les tests live/réseau et probes diagnostiques restent `ignored` conformément à leur contrat. + +## Réconciliation + +La documentation durable était encore partiellement figée sur la foundation Program-only : + +```text +README Interface -> rôle Program-only et affirmation « aucun événement runtime » +USAGE Interface -> page explicitement matérialisée par 0.2.13 +architecture -> rôle Interface décrit surtout comme façade wire Program +TransactionLogEvent -> idée différée encore enfermée dans le plan/validation de release +``` + +`pre.007` corrige ces incohérences sans transformer Interface en runtime : + +```text +Program wire contracts -> Interface +provider-neutral passive acquisition -> Interface lorsque convergence exacte démontrée +rich HTTP/WS/gRPC/provider DTOs -> Transport +persistent/replayable RAW -> Store API +post-commit durable-data wake-up -> Store API +converters Transport -> Interface -> composition/consumer +backlog/recovery -> Store +``` + +La surface durable documentée contient exactement les deux familles acquisition acquises : + +```text +SlotLifecycleEvent +TransactionExecutionEvent +``` + +`TransactionLogEvent` est transféré dans `docs/IDEAS.md` et reste soumis à un futur gate consumer + bornes + convergence multi-source. + +## Version + +```text +workspace.package.version = 0.3.5-pre.7 +``` + +## Fichiers + +Modifiés : + +```text +Cargo.toml +crates/ksp-interface-lib/README.md +crates/ksp-interface-lib/USAGE.md +docs/IDEAS.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/006-WIRE_AND_PROGRAM.md +docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md +docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md +docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md +``` + +Ajouté : + +```text +deltas/0.3.5/pre.007.md +``` + +Explicitement inchangés : + +```text +CHANGELOG.md +ROADMAP.md +prompts/** +crates/ksp-interface-lib/src/** +crates/ksp-interface-lib/tests/** +crates/ksp-interface-lib/unit_tests/** +crates/ksp-interface-lib/Cargo.toml +crates/ksp-onchain-transport-lib/** +crates/ksp-store-api/** +crates/ksp-store-lib/** +crates/ksp-store-postgres-lib/** +crates/ksp-program-api/** +``` + +## Gate d'assemblage + +Les contrôles statiques disponibles dans l'environnement d'assemblage sont propres : + +```text +General Rust rule audit: clean +Rust export completeness audit: 0 candidate(s) +KSP workspace Rust rule audit: clean +Markdown table audit: clean (240 table(s), 146 file(s)) +``` + +Aucun code Rust n'est modifié par cette tranche. Les commandes Cargo restent à confirmer dans le repository opérateur après application de l'overlay. + +## Gate demandé + +```bash +cargo fmt --all +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.5 +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-interface-lib +cargo test -p ksp-program-api +``` + +Aucun smoke réseau n'est requis. Après gate propre, la tranche suivante est la préparation de publication minimale `0.3.5-pre.008`. diff --git a/docs/IDEAS.md b/docs/IDEAS.md index 9b6f8b2..36bf7ac 100644 --- a/docs/IDEAS.md +++ b/docs/IDEAS.md @@ -1,5 +1,5 @@ - + # Idées à explorer @@ -96,6 +96,14 @@ Aucun `ksp-data-api` global n'est prévu actuellement. Les modèles appartiennen Réévaluer seulement si les premières implémentations montrent une duplication réellement nuisible impossible à résoudre sans contrat commun supplémentaire. +### Événement passif de logs transaction + +**Status :** À explorer après la première surface d'événements Interface + +Conserver `TransactionLogEvent` comme idée différée, sans type public tant qu'un consumer concret et des bornes sûres ne sont pas démontrés. Le futur gate doit comparer au minimum `logsSubscribe` et les formes transaction/meta des transports réellement consommés, sans supposer que leur richesse, leur volumétrie ou leur disponibilité sont identiques. + +Un éventuel contrat partagé doit rester un fait passif provider-neutral, distinct de `TransactionExecutionEvent` et des logs replayables contenus dans `RawTransaction`. Il ne doit créer ni `RawLog` Store par défaut, ni event bus Interface, ni wrapper d'un DTO Transport. + ### Mesure du trafic et metering futur **Status :** À explorer plus tard diff --git a/docs/architecture/002-LAYERS_AND_DEPENDENCIES.md b/docs/architecture/002-LAYERS_AND_DEPENDENCIES.md index 74e9d82..c58fe44 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 @@ -150,7 +150,7 @@ Les exécutables et couches supérieures n'importent pas directement les crates Exceptions bas niveau explicitement autorisées restent limitées aux primitives stables décidées par les règles KSP. -`ksp-interface-lib` concentre les interfaces/wires officielles ou compatibles afin d'éviter les doublons de générations et les dépendances protocolaires dans les couches supérieures. +`ksp-interface-lib` concentre les contrats passifs KSP réellement partagés — wires officiels/compatibles et faits provider-neutral admis — afin d'éviter les doublons de générations, les dépendances protocolaires dans les couches supérieures et la promotion accidentelle d'un DTO Transport en contrat transversal. Les converters depuis Transport restent dans la composition. ## Principe contract-first diff --git a/docs/architecture/003-COMPONENT_CONTRACTS.md b/docs/architecture/003-COMPONENT_CONTRACTS.md index f2b2cfd..3364689 100644 --- a/docs/architecture/003-COMPONENT_CONTRACTS.md +++ b/docs/architecture/003-COMPONENT_CONTRACTS.md @@ -1,5 +1,5 @@ - + # Contrats initiaux des composants KSP @@ -94,13 +94,13 @@ Il ne possède pas `WalletPolicy` ni les règles d'autorisation d'exécution. Le wallet temporaire JSON historique n'est pas migré. -## Interface / wire +## Interface / contrats passifs -`ksp-interface-lib` est la façade wire officielle KSP et expose aussi une API publique wire réutilisable par `ksp-program-lib` et les extensions Program externes. +`ksp-interface-lib` possède les contrats passifs KSP réellement partagés entre composants : façade wire officielle lorsqu'un protocole commun l'exige, et faits d'acquisition provider-neutral lorsqu'une sémantique commune exacte est démontrée. Sa surface publique est réutilisable notamment par `ksp-program-lib`, les extensions Program externes et les composants de composition/acquisition qui ne doivent pas dépendre d'un DTO Transport particulier. Aucune `ksp-interface-api` séparée n'est retenue actuellement. -La crate sélectionne entre réexport contrôlé, wrapper ou implémentation wire compatible selon stabilité, ownership et graphe de dépendances des interfaces externes. +La crate sélectionne entre réexport contrôlé, wrapper ou implémentation KSP-owned selon stabilité, ownership et graphe de dépendances. Elle ne possède ni Transport/runtime, ni Store/persistence, ni event bus ; les conversions depuis les DTOs Transport restent dans la composition. ## Program diff --git a/docs/architecture/004-COMPONENT_INVENTORY.md b/docs/architecture/004-COMPONENT_INVENTORY.md index 7082b05..8541bcb 100644 --- a/docs/architecture/004-COMPONENT_INVENTORY.md +++ b/docs/architecture/004-COMPONENT_INVENTORY.md @@ -1,5 +1,5 @@ - + # Inventaire initial des composants KSP @@ -32,7 +32,7 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse | Yellowstone | `ksp-onchain-transport-lib` | lib | Stable | `0.2.9` | client gRPC standard/provider-neutral | | Off-chain price | `ksp-offchain-transport-lib` | lib | Stable | `0.2.11` | prix SOL/USD multi-provider, limits et availability | | SOL Prices Desk | `ksp-app-solprices-desk` | app | Stable | `0.2.12` | HID provider-agnostic pour visualisation/refresh prix | -| Wire | `ksp-interface-lib` | lib | Stable | `0.2.13` | façade wire officielle + API publique wire | +| Interface passive | `ksp-interface-lib` | lib | Stable | `0.2.13` | façade wire + contrats passifs partagés, dont événements acquisition provider-neutral | | 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` | diff --git a/docs/architecture/005-DEPENDENCY_GRAPH.md b/docs/architecture/005-DEPENDENCY_GRAPH.md index aafcbd5..d0bef04 100644 --- a/docs/architecture/005-DEPENDENCY_GRAPH.md +++ b/docs/architecture/005-DEPENDENCY_GRAPH.md @@ -1,5 +1,5 @@ - + # Graphe de dépendances KSP @@ -169,16 +169,17 @@ Le Wallet stocke/ouvre/signe. Il ne décide pas si une dépense est autorisée. `WalletPolicy` historique migre conceptuellement vers execution policy, pas vers `ksp-wallet-lib`. -## Interface / wire +## Interface / contrats passifs ```text ksp-interface-lib -> ksp-core-lib - -> ksp-logging-lib lorsque runtime logging réel - -> official/compatible wire dependencies retenues + -> official/compatible wire dependencies uniquement lorsqu'un protocole réel les exige ``` -`ksp-interface-lib` contient **à la fois** la façade wire officielle et une API publique wire utilisable par les implémentations Program officielles/externes. +`ksp-interface-lib` contient la façade wire officielle **et** les contrats passifs KSP-owned dont la sémantique est réellement partagée, y compris des faits d'acquisition provider-neutral. Les composants Program et les composants de composition peuvent consommer ces contrats sans importer un runtime Transport. + +Un événement passif n'autorise aucune dépendance Interface vers Transport, Store, worker/job ou logging runtime. Les converters depuis des DTOs Transport restent dans la composition. Aucune `ksp-interface-api` séparée n'est retenue actuellement. diff --git a/docs/architecture/006-WIRE_AND_PROGRAM.md b/docs/architecture/006-WIRE_AND_PROGRAM.md index b1534bd..b1bad73 100644 --- a/docs/architecture/006-WIRE_AND_PROGRAM.md +++ b/docs/architecture/006-WIRE_AND_PROGRAM.md @@ -1,5 +1,5 @@ - + # Wire, Program API et implémentations Program @@ -22,7 +22,7 @@ Les types Rust exacts restent volontairement à définir lors de la première im ## `ksp-interface-lib` -`ksp-interface-lib` est la façade wire officielle KSP pour les programmes Solana supportés officiellement. +`ksp-interface-lib` est la façade des contrats passifs KSP réellement partagés. Elle possède notamment les wires officiels nécessaires aux programmes Solana supportés et peut aussi posséder des faits d'acquisition provider-neutral lorsqu'ils ne sont ni des DTOs Transport ni des modèles persistants Store. Elle possède ou réexporte de manière contrôlée les contrats nécessaires tels que : @@ -38,29 +38,51 @@ Les Program IDs fondamentaux restent possédés par `ksp-core-lib`. `ksp-interface-lib` ne possède pas : -- RPC/WS/provider ; -- wallet/signature ; -- persistence ; +- RPC/WS/gRPC/provider DTOs ou sessions ; +- event bus, worker, job ou scheduler ; +- wallet/signature capability ; +- persistence, Store, cursor ou retention ; - matérialisation ; - interprétation canonique/métier d'une instruction ; - policy/safety ; - lifecycle d'exécution réseau. +Les événements d'acquisition admis dans Interface sont de simples faits passifs supplémentaires. Ils ne remplacent pas le DTO Transport riche et leurs conversions appartiennent à la composition qui connaît les deux contrats. + ## API publique de `ksp-interface-lib` `ksp-interface-lib` reste une seule crate pour l'instant : aucune `ksp-interface-api` séparée n'est créée. -La façade doit néanmoins exposer une API publique wire stable et réutilisable par : +La façade doit néanmoins exposer une API publique stable et réutilisable par : ```text ksp-program-lib external ksp-program--lib +compositions/acquisition consumers utilisant un fait passif partagé ``` Une implementation externe peut donc expérimenter contre les mêmes contrats wire publics avant intégration officielle dans KSP. Lorsqu'un wire externe devient officiel, son intégration dans `ksp-interface-lib` doit rester compatible avec l'API publique retenue, sauf évolution de contrat explicitement versionnée/documentée. Si une future contrainte de dépendances démontre qu'un split `ksp-interface-api` apporte une valeur réelle, il pourra être étudié selon `KSP-API-007`; la symétrie avec Program ne suffit pas. +## Événements passifs d'acquisition + +Interface peut posséder un événement d'acquisition seulement si plusieurs sources/consumers partagent exactement le même fait et que le type reste plus petit que les DTOs producteurs. Le contrat ne doit pas accumuler des champs `Option` pour simuler l'union de protocoles hétérogènes. + +La frontière durable est : + +```text +DTO Transport riche et lossless + | + | conversion explicite par composition/consumer + v +événement Interface passif provider-neutral +``` + +Un événement Interface ne devient ni un message de bus obligatoire ni une donnée durable. Les informations replayables appartiennent à `ksp-store-api`; les détails de transport, provider, commitment, session, timestamp source-specific et diagnostics qui ne font pas partie du fait commun restent Transport-owned. + +Les familles actuellement démontrées sont le lifecycle de slot et le résultat d'exécution d'une transaction. Toute nouvelle famille exige un nouveau gate de convergence, consumer et bornes. + ## Propriété des codecs wire Pour le code KSP officiel, les dépendances directement utilisées pour encoder/décoder les formats wire, notamment `borsh`, `wincode` ou codecs équivalents, appartiennent normalement à `ksp-interface-lib`. diff --git a/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md b/docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md index 469345a..e077666 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 @@ -353,11 +353,14 @@ ksp-job-backfill ksp-worker-raw-retriever -> ksp-worker-api -> ksp-onchain-transport-lib + -> ksp-interface-lib # seulement si un fait passif partagé aide la composition live -> ksp-store-lib # façade Store ; backend sélectionné par feature + Config -> ksp-config-lib -> ksp-logging-lib ``` +Les événements Interface peuvent servir de signal provider-neutral à la composition live, mais ne constituent jamais le backlog durable. Après crash ou perte d'un événement, la reprise s'appuie sur Store et sur les primitives de replay/hydratation appropriées. + ### CORE replay/worker ```text diff --git a/docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md b/docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md index 5c758c4..3cfa66e 100644 --- a/docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md +++ b/docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md @@ -1,5 +1,5 @@ - + # Plan `0.3.5` — Interface passive acquisition events @@ -12,16 +12,16 @@ v0.3.4 workspace.package.version = 0.3.4 ``` -Version de travail ouverte par cette tranche : +Version de travail à la réconciliation documentaire finale : ```text -workspace.package.version = 0.3.5-pre.1 -label = 0.3.5-pre.001 +workspace.package.version = 0.3.5-pre.7 +label = 0.3.5-pre.007 ``` -`0.3.5-pre.001` est un gate de lecture, inventaire, convergence sémantique, threat model, sizing et planification. Il ne modifie aucun contrat public Rust, aucun DTO Transport, aucun modèle Store, aucun runtime et aucune persistence. +La release est fonctionnellement fermée. `pre.001` a ouvert l'audit ; son fix a établi l'intersection exacte de sept stages slot et rouvert le candidat transaction execution. `pre.002` a matérialisé `SlotLifecycleEvent`, `pre.003` a admis `TransactionExecutionEvent`, `pre.004`/`pre.005` ont fermé les canaris de complétude et le hardening, puis `pre.006` a validé le gate workspace et le graphe Cargo final. -Le résultat du gate reste volontairement étroit. `pre.001-fix.001` a corrigé deux conclusions trop conservatrices : le lifecycle de slot possède une intersection de **sept** stages communs après normalisation sémantique explicite et `TransactionExecutionEvent` a été rouvert comme candidat actif. `pre.002` matérialise `SlotLifecycleEvent`; `pre.003` ferme ensuite le gate transaction execution et admet une seconde famille passive compacte sans déplacer les DTOs Transport ni les modèles RAW Store. +`pre.007` ne modifie aucun contrat Rust. Elle réconcilie les documents durables avec la surface réellement acquise et transfère l'idée `TransactionLogEvent` vers `docs/IDEAS.md` au lieu de laisser un TODO caché dans le plan de release. ## 2. Mission @@ -655,9 +655,10 @@ La release reste dimensionnée pour une seule session. `SlotLifecycleEvent` est ### `0.3.5-pre.007` — réconciliation documentaire finale -- plan + validation ; +- plan + validation réconciliés avec le gate `pre.006` propre ; - README/USAGE Interface durables et version-neutral ; -- architecture durable uniquement si le rôle Interface doit être explicité ; +- rôle Interface explicité dans les documents d'architecture réellement devenus incomplets ; +- `TransactionLogEvent` transféré dans `docs/IDEAS.md` comme idée différée ; - aucun CHANGELOG/ROADMAP/prompt suivant dans cette tranche. ### `0.3.5-pre.008` — préparation de publication diff --git a/docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md b/docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md index 451cd9c..361f722 100644 --- a/docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md +++ b/docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md @@ -1,11 +1,11 @@ - + # Validation `0.3.5` — Interface passive acquisition events ## 1. Portée -Ce document est ouvert par `0.3.5-pre.001`, corrigé par `0.3.5-pre.001-fix.001`, enrichi par `0.3.5-pre.002`, `pre.003`, `pre.004` puis `pre.005`. `pre.002` matérialise `SlotLifecycleEvent`; `pre.003` ferme le gate `TransactionExecutionEvent` et admet la seconde famille passive minimale ; `pre.004` verrouille les canaris externes et la complétude de cette surface sans ajouter de contrat de production ; `pre.005` ajoute le hardening adversarial et les canaris anti-duplication finaux, toujours sans nouvelle surface de production. +Ce document suit toute la fermeture de `0.3.5`. `pre.002` matérialise `SlotLifecycleEvent`; `pre.003` admet `TransactionExecutionEvent`; `pre.004` verrouille les canaris externes et la complétude ; `pre.005` ajoute le hardening adversarial ; son fix corrige uniquement un faux négatif du canari de manifeste ; `pre.006` ferme le gate technique final ; `pre.007` réconcilie la documentation durable sans modifier la surface Rust. Base : @@ -17,7 +17,7 @@ workspace.package.version = 0.3.4 Version de travail : ```text -0.3.5-pre.5.fix.1 +0.3.5-pre.7 ``` ## 2. Gate d'entrée `v0.3.4` @@ -827,7 +827,7 @@ cargo tree -p ksp-interface-lib -e features cargo tree --duplicates ``` -Aucun smoke réseau n'est requis : `0.3.5` ne modifie aucun moteur Transport et les contrats Interface sont passifs. Les résultats `cargo tree` restent à capturer côté opérateur avant de considérer `pre.006` clôturée. +Aucun smoke réseau n'est requis : `0.3.5` ne modifie aucun moteur Transport et les contrats Interface sont passifs. Les résultats `cargo tree` sont capturés dans le résultat opérateur de clôture ci-dessous. ## 36. Fichiers de `pre.006` @@ -857,4 +857,80 @@ README.md ROADMAP.md CHANGELOG.md ``` +## 37. Résultat du gate technique final `pre.006` + +Le gate opérateur du `2026-08-31` est propre après correction locale des numéros d'en-tête réellement modifiés dans `Cargo.toml` et ce document de validation : + +```text +General Rust rule audit: clean +Rust export completeness audit: 0 candidate(s) +KSP workspace Rust rule audit: clean +Markdown table audit: clean (240 table(s), 145 file(s)) +cargo check --workspace: PASS +cargo clippy --workspace --all-targets: PASS +cargo test -p ksp-interface-lib: PASS +cargo test --workspace: PASS +``` + +Les tests live/réseau et probes diagnostiques restent explicitement `ignored` conformément à leur contrat ; aucun test non ignoré n'échoue. + +Les trois preuves Cargo finales confirment : + +```text +cargo tree -p ksp-interface-lib --edges normal + ksp-interface-lib -> ksp-core-lib -> solana-pubkey -> solana-address + +cargo tree -p ksp-interface-lib -e features + aucune feature propre Interface ; seule la feature default de ksp-core-lib est activée + +cargo tree --duplicates + doublons du workspace global présents, aucun nouveau doublon imputable à ksp-interface-lib/0.3.5 +``` + +Le manifeste Interface reste sans `[features]`, `[dev-dependencies]` ni `[build-dependencies]`. La surface fonctionnelle finale demeure exactement : + +```text +ProgramAccountMeta / ProgramInstruction +SlotLifecycleEvent / SlotLifecycleStage +TransactionSignature / TransactionExecutionEvent / TransactionExecutionOutcome +``` + +Aucun serde, codec, logging, runtime, Transport ou Store n'est entré dans le graphe Interface. + +## 38. Réconciliation documentaire finale — `pre.007` + +`pre.007` ne modifie aucun code Rust ni manifeste de crate. La version workspace devient : + +```text +0.3.5-pre.7 +``` + +La réconciliation ferme les incohérences documentaires restantes : + +- `crates/ksp-interface-lib/README.md` décrit désormais les contrats Program et les deux familles d'événements passifs sans présenter Interface comme un runtime ; +- `crates/ksp-interface-lib/USAGE.md` devient version-neutral et documente la construction/consommation des événements via le crate-root ; +- les documents d'architecture concernés distinguent explicitement contrat passif Interface, DTO riche Transport et modèle replayable Store ; +- le futur RAW worker peut dépendre d'Interface pour un fait passif partagé, mais son backlog/recovery reste Store-owned ; +- `TransactionLogEvent` reste hors scope et est transféré vers `docs/IDEAS.md` avec un nouveau gate consumer/bornes obligatoire ; +- `CHANGELOG.md`, `ROADMAP.md` et le prompt `0.3.6` restent réservés à la tranche de publication suivante. + +Fichiers modifiés par la tranche : + +```text +Cargo.toml +crates/ksp-interface-lib/README.md +crates/ksp-interface-lib/USAGE.md +docs/IDEAS.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/006-WIRE_AND_PROGRAM.md +docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md +docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md +docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md +deltas/0.3.5/pre.007.md +``` + +Aucun autre fichier ne doit être modifié.