v0.3.5-pre.001
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 382
|
||||
# version: 383
|
||||
|
||||
[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.4"
|
||||
version = "0.3.5-pre.1"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
119
deltas/0.3.5/pre.001.md
Normal file
119
deltas/0.3.5/pre.001.md
Normal file
@@ -0,0 +1,119 @@
|
||||
<!-- file: deltas/0.3.5/pre.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.5-pre.001` — audit et planification Interface acquisition events
|
||||
|
||||
## Base requise
|
||||
|
||||
```text
|
||||
v0.3.4
|
||||
workspace.package.version = 0.3.4
|
||||
```
|
||||
|
||||
Le log opérateur fourni avec l'archive d'entrée montre le gate stable `v0.3.4` propre. Cette tranche part exclusivement de l'archive `khadhroony-solana-project-v0.3.4.zip` fournie par l'opérateur.
|
||||
|
||||
## Objectif
|
||||
|
||||
Exécuter le gate `pre.001` prescrit par `prompts/024-V0_3_5_START_PROMPT.md` : lecture, inventaire producer/consumer, audit sémantique multi-transport actuel, ownership Interface/Transport/Store, threat model, sizing et planification.
|
||||
|
||||
Aucun modèle Rust n'est implémenté dans cette tranche.
|
||||
|
||||
## Décisions prises
|
||||
|
||||
Une seule famille passe le gate d'admission Interface :
|
||||
|
||||
```text
|
||||
SlotLifecycleEvent
|
||||
+ Processed
|
||||
+ FirstShredReceived
|
||||
+ Completed
|
||||
+ CreatedBank
|
||||
+ Dead
|
||||
```
|
||||
|
||||
Cette intersection correspond uniquement aux faits communs démontrés entre Solana WebSocket et Yellowstone. Les metadata riches restent Transport.
|
||||
|
||||
Décisions négatives :
|
||||
|
||||
```text
|
||||
Root -X-> Finalized
|
||||
OptimisticConfirmation -X-> Confirmed
|
||||
logsSubscribe -> reporté
|
||||
TransactionStatusObservation -> reporté
|
||||
vote -> reporté
|
||||
account/program -> Store/Transport
|
||||
transaction/block -> Store/Transport
|
||||
Yellowstone Entry -> Transport
|
||||
Helius Enhanced transaction -> Transport
|
||||
notification after commit -> Store API selon KSP-NOTIFY-001..006
|
||||
```
|
||||
|
||||
La release est redimensionnée autour d'une seule famille et réserve explicitement les couloirs hardening, gate technique final, réconciliation documentaire puis publication.
|
||||
|
||||
## Fichiers ajoutés
|
||||
|
||||
```text
|
||||
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.001.md
|
||||
```
|
||||
|
||||
## Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
```
|
||||
|
||||
Modifications Cargo :
|
||||
|
||||
```text
|
||||
header version: 382 -> 383
|
||||
workspace.package.version: 0.3.4 -> 0.3.5-pre.1
|
||||
```
|
||||
|
||||
## Fichiers supprimés
|
||||
|
||||
Aucun.
|
||||
|
||||
## Validations exécutées
|
||||
|
||||
```text
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
-> General Rust rule audit: clean
|
||||
-> Rust export completeness audit: 0 candidate(s)
|
||||
-> KSP workspace Rust rule audit: clean
|
||||
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.5
|
||||
-> Markdown table audit: clean (251 table(s), 137 file(s))
|
||||
```
|
||||
|
||||
## Validations non exécutées dans l'environnement d'assemblage
|
||||
|
||||
`cargo` n'est pas installé dans l'environnement d'assemblage. Les commandes suivantes ne sont donc pas déclarées réussies :
|
||||
|
||||
```text
|
||||
cargo fmt --all
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-interface-lib
|
||||
```
|
||||
|
||||
Elles doivent être rejouées par l'opérateur après application de l'overlay.
|
||||
|
||||
## Questions ouvertes
|
||||
|
||||
Aucune question bloquante pour `pre.002`.
|
||||
|
||||
Les familles logs/status/vote/root restent volontairement reportées et ne doivent être rouvertes que si un nouveau producer/consumer concret apporte une convergence qui n'existe pas dans ce gate.
|
||||
|
||||
## Suite prévue
|
||||
|
||||
```text
|
||||
pre.002 implémentation SlotLifecycleEvent/Stage
|
||||
pre.003 canaris externes + complétude API
|
||||
pre.004 hardening final
|
||||
pre.005 gate technique final
|
||||
pre.006 réconciliation documentaire finale
|
||||
pre.007 préparation de publication
|
||||
rel.001 stable 0.3.5
|
||||
```
|
||||
672
docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md
Normal file
672
docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md
Normal file
@@ -0,0 +1,672 @@
|
||||
<!-- file: docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Plan `0.3.5` — Interface passive acquisition events
|
||||
|
||||
## 1. Statut de la release
|
||||
|
||||
Base canonique auditée :
|
||||
|
||||
```text
|
||||
v0.3.4
|
||||
workspace.package.version = 0.3.4
|
||||
```
|
||||
|
||||
Version de travail ouverte par cette tranche :
|
||||
|
||||
```text
|
||||
workspace.package.version = 0.3.5-pre.1
|
||||
label = 0.3.5-pre.001
|
||||
```
|
||||
|
||||
`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.
|
||||
|
||||
Le résultat du gate est volontairement étroit : **une seule famille satisfait actuellement les critères d'admission Interface**, le lifecycle de slot sur une intersection minimale de statuts réellement commune entre les surfaces Solana WebSocket et Yellowstone. Toutes les autres familles restent Transport, Store ou reportées.
|
||||
|
||||
## 2. Mission
|
||||
|
||||
La release doit étendre `ksp-interface-lib` seulement lorsqu'un consumer de composition peut recevoir un fait passif KSP-owned sans dépendre du protocole producteur et sans créer un second modèle RAW.
|
||||
|
||||
Le contrat cible reste :
|
||||
|
||||
```text
|
||||
producer Transport
|
||||
-> DTO Transport riche et lossless
|
||||
-> conversion explicite à la composition
|
||||
-> fait Interface passif minimal, seulement si la sémantique commune est prouvée
|
||||
```
|
||||
|
||||
Le type Interface ne remplace jamais le DTO Transport. Les informations source-specific qui ne font pas partie du fait commun restent disponibles sur le DTO Transport et ne sont pas copiées dans Interface.
|
||||
|
||||
## 3. Sources relues
|
||||
|
||||
### 3.1 Sources internes
|
||||
|
||||
Le gate a relu les familles prescrites par le prompt :
|
||||
|
||||
```text
|
||||
RULES.md
|
||||
docs/000-README.md
|
||||
|
||||
docs/rules/RULES_GENERAL.md
|
||||
docs/rules/RULES_KSP.md
|
||||
docs/rules/RULES_RUST.md
|
||||
docs/rules/RULES_DEPENDENCIES.md
|
||||
docs/rules/RULES_DOCUMENTATION.md
|
||||
docs/rules/FILE_CONTRACTS.md
|
||||
docs/rules/VERSION_WORKFLOW.md
|
||||
docs/rules/PROMPT_STRUCTURE.md
|
||||
|
||||
docs/architecture/000-README.md
|
||||
docs/architecture/001-PROJECT_OBJECTIVES.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/008-DATA_MATERIALIZATION_AND_STORE.md
|
||||
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
|
||||
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md
|
||||
|
||||
docs/plans/020-V0_2_13_INTERFACE_PLAN.md
|
||||
docs/validation/016-V0_2_13_INTERFACE.md
|
||||
docs/plans/022-V0_3_1_STORE_RAW_PLAN.md
|
||||
docs/validation/018-V0_3_1_STORE_RAW.md
|
||||
docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md
|
||||
docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md
|
||||
docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md
|
||||
docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md
|
||||
docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md
|
||||
docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md
|
||||
```
|
||||
|
||||
Les sources Rust relues couvrent `ksp-interface-lib`, `ksp-store-api`, la façade/backend Store et les modules HTTP/WS/gRPC/Helius event-like de `ksp-onchain-transport-lib` demandés par le prompt.
|
||||
|
||||
### 3.2 Surface Interface/Store stable constatée
|
||||
|
||||
Inventaire crate-root actuel de `ksp-interface-lib` :
|
||||
|
||||
```text
|
||||
Pubkey
|
||||
ProgramAccountMeta
|
||||
ProgramInstruction
|
||||
MAX_PROGRAM_INSTRUCTION_ACCOUNTS
|
||||
MAX_PROGRAM_INSTRUCTION_DATA_LEN
|
||||
ERROR_CODE_PROGRAM_INSTRUCTION_LIMIT_EXCEEDED
|
||||
```
|
||||
|
||||
Modules de production actuels :
|
||||
|
||||
```text
|
||||
error
|
||||
program_account_meta
|
||||
program_instruction
|
||||
```
|
||||
|
||||
Le manifeste Interface ne possède qu'une dependency normale :
|
||||
|
||||
```text
|
||||
ksp-core-lib
|
||||
```
|
||||
|
||||
Le consumer runtime/public actuel identifié est `ksp-program-api`, qui réutilise `ProgramAccountMeta` et `ProgramInstruction`. Aucun consumer actuel n'impose encore un event d'acquisition.
|
||||
|
||||
La surface Store stable expose exactement dix capabilities RAW :
|
||||
|
||||
```text
|
||||
RawTransactionRead
|
||||
RawTransactionWrite
|
||||
RawTransactionObservationRead
|
||||
RawTransactionObservationWrite
|
||||
RawTransactionRetentionRead
|
||||
RawTransactionRetentionWrite
|
||||
RawAccountStateRead
|
||||
RawAccountStateWrite
|
||||
RawAccountObservationRead
|
||||
RawAccountObservationWrite
|
||||
```
|
||||
|
||||
### 3.3 Sources externes courantes auditées le 2026-08-31
|
||||
|
||||
L'audit externe a porté sur les documents normatifs/courants suivants :
|
||||
|
||||
```text
|
||||
Solana RPC WebSocket:
|
||||
- slotSubscribe
|
||||
- slotsUpdatesSubscribe
|
||||
- rootSubscribe / index WebSocket
|
||||
- signatureSubscribe
|
||||
- logsSubscribe
|
||||
- voteSubscribe
|
||||
- accountSubscribe
|
||||
- programSubscribe
|
||||
|
||||
Solana RPC HTTP:
|
||||
- getSignatureStatuses
|
||||
- getTransaction
|
||||
- getBlock
|
||||
|
||||
Yellowstone gRPC upstream et version KSP :
|
||||
- KSP stable déclare `yellowstone-grpc-proto = ^12.6`
|
||||
- geyser.proto / SlotStatus / SubscribeUpdateSlot
|
||||
- transaction_status
|
||||
- account / transaction / block / block_meta / entry update families
|
||||
- upstream courant comparé pour vérifier que l'intersection SlotStatus retenue n'est pas une hypothèse obsolète
|
||||
|
||||
Helius:
|
||||
- LaserStream-powered standard WebSockets
|
||||
- Enhanced WebSocket transactionSubscribe
|
||||
```
|
||||
|
||||
Les conclusions externes qui structurent le plan sont :
|
||||
|
||||
- `slotSubscribe` signale le traitement d'un nouveau slot et transporte `slot`, `parent` et le root courant ;
|
||||
- `slotsUpdatesSubscribe` est instable et publie `firstShredReceived`, `completed`, `createdBank`, `frozen`, `dead`, `optimisticConfirmation` et `root`, avec metadata conditionnelle ;
|
||||
- Yellowstone expose `Processed`, `Confirmed`, `Finalized`, `FirstShredReceived`, `Completed`, `CreatedBank` et `Dead` ;
|
||||
- `signatureSubscribe` est un abonnement one-shot à une signature, éventuellement précédé de `receivedSignature`, et n'est pas un snapshot HTTP ;
|
||||
- `getSignatureStatuses` reste un snapshot queryable avec confirmations/status/confirmationStatus ;
|
||||
- `voteSubscribe` publie des votes gossip pré-consensus, sans garantie qu'ils entrent dans le ledger ;
|
||||
- Helius conserve les méthodes standard Solana et possède en plus des extensions Enhanced WebSocket, notamment `transactionSubscribe`, qui restent provider-specific.
|
||||
|
||||
## 4. Invariants d'ownership
|
||||
|
||||
Les règles directement structurantes restent :
|
||||
|
||||
```text
|
||||
KSP-TRANSPORT-002..004
|
||||
KSP-STORE-001..002
|
||||
KSP-NOTIFY-001..006
|
||||
KSP-PROC-007..008
|
||||
KSP-REL-005..016
|
||||
DEP-KSP-*
|
||||
DEP-LOG-*
|
||||
DEP-STORE-*
|
||||
DEP-WORKER-*
|
||||
DEP-JOB-*
|
||||
```
|
||||
|
||||
Le graphe cible reste :
|
||||
|
||||
```text
|
||||
ksp-interface-lib
|
||||
└── ksp-core-lib
|
||||
```
|
||||
|
||||
Et les frontières restent :
|
||||
|
||||
```text
|
||||
Interface -X-> Transport
|
||||
Interface -X-> Store API / Store
|
||||
Interface -X-> Program API / Program Lib
|
||||
Interface -X-> Config / Wallet
|
||||
Transport -X-> Store API
|
||||
Store API -X-> Transport
|
||||
composition supérieure = owner des conversions
|
||||
```
|
||||
|
||||
`ksp-program-api` reste un consumer de la surface Program-facing existante de `ksp-interface-lib`. Il n'a aucune raison de re-exporter les futurs événements d'acquisition.
|
||||
|
||||
## 5. Critères d'admission d'une famille Interface
|
||||
|
||||
Une famille n'est admise que si toutes les conditions suivantes sont vraies :
|
||||
|
||||
1. le type est passif et ne possède aucun lifecycle/runtime ;
|
||||
2. le fait est provider-neutral ;
|
||||
3. il ne duplique pas un modèle persistant/replayable de `ksp-store-api` ;
|
||||
4. l'intersection sémantique entre producers est précise et documentable ;
|
||||
5. au moins deux producers/converters peuvent produire exactement ce fait, ou plusieurs consumers ont un besoin identique déjà démontré ;
|
||||
6. le type n'est pas une union d'options destinée à masquer des sémantiques différentes ;
|
||||
7. les détails non communs peuvent rester sur les DTOs Transport sans forcer Interface à devenir lossless pour le protocole source ;
|
||||
8. un usage de composition proche est identifiable.
|
||||
|
||||
Une égalité de noms ne suffit pas. Une proximité de commitment ne suffit pas. Une possibilité théorique de conversion ne suffit pas.
|
||||
|
||||
## 6. Inventaire producer -> nature de fait
|
||||
|
||||
| Producer / surface | Nature du fait | Champs structurants obligatoires | Optionalité utile | Ordre / lifecycle | Timestamp semantics | Error semantics | Metadata session/provider | Volume potentiel | Persistent/replayable ? |
|
||||
|----------------------------------------|-------------------------------------|-------------------------------------------------------|-----------------------------------|---------------------------------------------------|-------------------------------------------|----------------------------------------|----------------------------------------|-----------------------|-----------------------------------------|
|
||||
| Solana WS `slotSubscribe` | progression de slot | slot, parent, root | aucune | event répété à chaque slot traité | aucun | aucune | subscription id hors DTO métier | minime | non |
|
||||
| Solana WS `rootSubscribe` | progression de root | root slot | aucune | event répété lors du changement de root | aucun | aucune | subscription id | minime | non |
|
||||
| Solana WS `slotsUpdatesSubscribe` | lifecycle interne slot | slot, type, timestamp | parent/stats/error selon variante | multi-event par slot ; méthode instable | Unix update timestamp en ms | texte seulement pour `dead` | subscription id | faible à modéré | non |
|
||||
| Solana WS `logsSubscribe` | logs transaction realtime | signature, err, logs + context slot | err nullable | flux continu selon filtre/commitment | aucun provider timestamp | opaque RPC transaction error | filtre + commitment + subscription id | logs non bornés wire | non par défaut |
|
||||
| Solana WS `signatureSubscribe` | réception/terminal signature | signature en request ; context slot + result en event | received précoce | one-shot terminal ; reçu optionnel avant terminal | aucun | transaction error au terminal | commitment/request/subscription | minime | non |
|
||||
| Solana HTTP `getSignatureStatuses` | snapshot de status | signatures request ; slot/status/confirmationStatus | nulls/confirmations | requête ponctuelle, pas une transition | aucun | transaction error dans snapshot | search history request policy | faible | queryable côté node, pas event KSP |
|
||||
| Solana WS `voteSubscribe` | vote gossip pré-consensus | votePubkey, slots, hash, signature | timestamp | flux gossip ; aucune garantie ledger | timestamp vote optionnel | aucune erreur transaction canonique | subscription id | faible | non |
|
||||
| Solana WS `accountSubscribe` | changement d'état account | context slot + account payload | selon encoding/dataSlice | flux d'état selon commitment | aucun | payload account, pas error event | commitment/encoding/subscription | potentiellement élevé | peut alimenter `RawAccountState` |
|
||||
| Solana WS `programSubscribe` | changement account d'un programme | context + pubkey + account payload | selon encoding/filters | flux d'état filtré | aucun | payload account | program/filter/commitment/subscription | potentiellement élevé | peut alimenter `RawAccountState` |
|
||||
| Solana WS `blockSubscribe` | bloc/transactions realtime | slot/context + block ou erreur | block nullable | flux de blocs selon config | blockTime dans payload si présent | RPC/block error | filter/config/subscription | très élevé | conteneur d'acquisition |
|
||||
| Yellowstone `Slot` | lifecycle/commitment slot | slot, status | parent/dead_error/created_at | plusieurs statuts possibles par slot | `created_at` = création serveur update | dead diagnostic optionnel | filter echo + server metadata | faible | non |
|
||||
| Yellowstone `TransactionStatus` | update execution/status transaction | slot, signature, is_vote, index | err/created_at | flux transaction status | server `created_at` | erreur transaction encodée | filter echo | faible | non par lui-même |
|
||||
| Yellowstone `Account` | état account + provenance Geyser | account bytes/info + slot + is_startup | txn signature/created_at | flux state/replay startup | server `created_at` | decode/transport error hors payload | filters + write/version metadata | potentiellement élevé | peut alimenter `RawAccountState` |
|
||||
| Yellowstone `Transaction` | transaction complète + meta | slot + transaction info/meta | created_at | flux transaction | server `created_at` | transaction meta error | filters + transaction index | très élevé | peut alimenter `RawTransaction` |
|
||||
| Yellowstone `Block` / `BlockMeta` | bloc / metadata de bloc | slot + block/meta fields | champs block spécifiques | flux block/meta | server `created_at` | payload/meta-specific | filters | très élevé | conteneur d'acquisition |
|
||||
| Yellowstone `Entry` | entry Geyser | slot/index/entry-specific fields | created_at | flux protocol-specific | server `created_at` | protocol-specific | filters | modéré | non retenu |
|
||||
| Helius standard WebSocket | mêmes faits standard Solana | mêmes champs standard | mêmes optionalités | même wire sémantique, runtime provider différent | mêmes semantics Solana | mêmes semantics Solana | Helius session/runtime | selon méthode | suit la famille standard |
|
||||
| Helius Enhanced `transactionSubscribe` | transaction provider-filtered | slot/signature ou transaction selon details | options/detail modes | extension provider continue | provider payload semantics | provider/RPC semantics | filtres Helius + options + session | faible à très élevé | acquisition possible, Transport-owned |
|
||||
| Store notification after commit | wake-up de donnée durable | future référence durable compacte | à définir avec publisher/consumer | après commit ; jamais source de vérité | non requis par le contrat normatif actuel | code safe éventuel, pas payload source | mécanisme de diffusion indépendant | minime | référence une persistence déjà commitée |
|
||||
|
||||
### 6.1 Consumers actuels et imminents
|
||||
|
||||
| Consumer | Besoin actuel / prévu | Dépendance à Interface event | Décision `pre.001` |
|
||||
|-------------------------------------------|-----------------------------------------------------------|------------------------------|---------------------------------------------------------------------------|
|
||||
| `ksp-program-api` | ProgramInstruction / ProgramAccountMeta | non | préserver la surface Program existante ; aucun re-export acquisition |
|
||||
| `0.3.6` premier backfill RAW | range historique -> Transport -> RAW ingestion -> Store | non | ne pas forcer SlotLifecycle dans le backfill |
|
||||
| futur worker RAW live | subscriptions/fetch live multi-transport -> RAW ingestion | oui, candidat concret | consumer proche justifiant une projection slot lifecycle provider-neutral |
|
||||
| futurs processors CORE/DECODE/SPECIALIZED | backlog Store + wake-up post-commit | non pour event réseau | consommer Store/backlog ; ne pas détourner les events réseau |
|
||||
| apps de contrôle/inspection futures | observabilité et commandes de composants | non démontré | aucun type Interface ajouté uniquement pour une UI future |
|
||||
|
||||
## 7. Matrice de convergence sémantique
|
||||
|
||||
| Nature candidate | Sources comparées | Intersection exacte retenue | Différences non représentables sans perte | Projection commune lossless pour le fait ciblé ? | Consumer concret | Owner | Décision |
|
||||
|-----------------------------|---------------------------------------------------------------------------|-------------------------------------------------------------------|------------------------------------------------------------------------------------|--------------------------------------------------|-----------------------------------|-----------------|-----------------|
|
||||
| lifecycle slot | slotSubscribe + slotsUpdates + Yellowstone Slot | Processed, FirstShredReceived, Completed, CreatedBank, Dead | parent/root/timestamps/diagnostics ; Frozen/Optimistic/Root vs Confirmed/Finalized | oui, pour l'occurrence `slot + stage` | futur worker RAW live | Interface | ADMIS |
|
||||
| root/finality | rootSubscribe + slotsUpdates Root + Yellowstone Finalized | aucune | root et finalized ne sont pas déclarés équivalents par une norme commune | non | aucun besoin exact démontré | Transport | REPORTÉ |
|
||||
| logs realtime | logsSubscribe + transaction meta logs + Yellowstone tx | signature/logs seulement au prix de perdre la nature de la source | event logs vs matière d'une transaction complète | non pour un fait unique | hydratation possible, non requise | Transport | REPORTÉ |
|
||||
| transaction status | getSignatureStatuses + signatureSubscribe + Yellowstone TransactionStatus | aucune | snapshot vs transition commitment vs execution update | non | aucun contrat unique démontré | Transport | REPORTÉ |
|
||||
| vote | voteSubscribe + Yellowstone transaction `is_vote` | qualificatif « vote » seulement | gossip pré-consensus vs transaction exécutée | non | aucun besoin commun démontré | Transport | REPORTÉ |
|
||||
| account/program | WS account/program + Yellowstone Account | état account complet possible | persistance/replay déjà possédés par RawAccountState/Observation | non comme event distinct | RAW ingestion | Store/Transport | REJET Interface |
|
||||
| transaction complète | HTTP/WS/Helius/Yellowstone transaction | transaction complète selon source | format/commitment/provider metadata ; RawTransaction déjà canonique Store | non comme second type | RAW ingestion | Store/Transport | REJET Interface |
|
||||
| block | getBlock/blockSubscribe/Yellowstone Block | slot + block container | payloads/options/reconstruction ; pas de consumer passif minimal prouvé | non | extraction RAW transaction | Transport | REJET Interface |
|
||||
| Yellowstone Entry | Yellowstone uniquement | aucune multi-source | mono-producer et protocole-specific | non | aucun | Transport | REJET Interface |
|
||||
| persisted-data available | Store after commit | référence durable compacte conceptuelle | event réseau sans relation ; owner déjà normé par KSP-NOTIFY | oui mais hors owner Interface | processors futurs | Store API | REJET Interface |
|
||||
| Helius Enhanced transaction | Helius uniquement | aucune multi-source indépendante | filtres/options/provider behavior | non | Transport consumer | Transport | REJET Interface |
|
||||
|
||||
### 7.1 Lifecycle de slot — ADMIS sous intersection stricte
|
||||
|
||||
| Fait commun | Solana standard | Yellowstone | Décision Interface | Metadata volontairement non commune |
|
||||
|--------------------------|-----------------------------------------|----------------------|--------------------|--------------------------------------------------------------------------------|
|
||||
| slot traité | `slotSubscribe` | `Processed` | ADMIS | parent/root courant côté WS ; filters/created_at/parent côté Yellowstone |
|
||||
| premier shred reçu | `FirstShredReceived` | `FirstShredReceived` | ADMIS | timestamp WS ; created_at/filters côté Yellowstone |
|
||||
| ingestion slot complétée | `Completed` | `Completed` | ADMIS | timestamp WS ; created_at/filters côté Yellowstone |
|
||||
| bank créé | `CreatedBank` | `CreatedBank` | ADMIS | parent requis WS, optionnel Yellowstone ; il reste dans le DTO Transport riche |
|
||||
| slot mort | `Dead` | `Dead` | ADMIS | diagnostics source-specific et horodatages restent Transport |
|
||||
| frozen | `Frozen` | aucun statut exact | REJETÉ | pas d'intersection |
|
||||
| optimistic confirmation | `OptimisticConfirmation` | `Confirmed` | REJETÉ | aucune équivalence normative exacte retenue |
|
||||
| root | `rootSubscribe` / `slotsUpdates` `Root` | `Finalized` | REJETÉ | aucune équivalence normative exacte retenue |
|
||||
| confirmed | aucun événement exact retenu | `Confirmed` | REJETÉ | pas de producer standard exact |
|
||||
| finalized | aucun événement exact retenu | `Finalized` | REJETÉ | root n'est pas promu artificiellement en finalized |
|
||||
|
||||
Le fait commun est volontairement plus petit que chaque DTO producteur. La conversion **n'efface pas** le DTO Transport : elle ajoute une projection passive `slot + stage` pour les consumers qui n'ont besoin que de l'occurrence de l'étape commune.
|
||||
|
||||
Le timestamp n'entre pas dans le contrat commun : `slotsUpdatesSubscribe.timestamp` décrit l'horodatage Unix de l'update côté validator alors que `YellowstoneUpdateTimestamp` est une metadata de création serveur. Les réunir sous un seul champ produirait une fausse équivalence.
|
||||
|
||||
Le `parent`, le root courant et `dead_error` restent également source-owned ; un consumer qui en a besoin doit conserver le DTO Transport ou définir un contrat supérieur spécifique.
|
||||
|
||||
### 7.2 Logs realtime — REPORTÉ
|
||||
|
||||
Le payload standard `logsSubscribe` est compact et event-only, mais le gate ne démontre pas une deuxième surface sémantiquement indépendante qui produise exactement le même fait :
|
||||
|
||||
- Helius standard réutilise le wire standard Solana et n'ajoute donc pas un nouveau contrat ;
|
||||
- Yellowstone expose des logs dans la transaction/meta complète, pas une notification `logsSubscribe` équivalente ;
|
||||
- la signature + logs peut déclencher une hydratation, mais ce besoin pourra être porté directement par le DTO Transport tant qu'un consumer multi-transport concret n'exige pas une projection commune.
|
||||
|
||||
Aucun `RawLog`, `TransactionLogEvent` ou équivalent public n'est donc créé en `0.3.5` sauf réouverture explicite du gate avec un nouveau producer/consumer.
|
||||
|
||||
### 7.3 Transaction status — REPORTÉ
|
||||
|
||||
Les trois familles restent distinctes :
|
||||
|
||||
```text
|
||||
HTTP getSignatureStatuses
|
||||
= snapshot interrogé, avec confirmations/status/confirmationStatus
|
||||
|
||||
WS signatureSubscribe
|
||||
= transition one-shot vers le commitment demandé, éventuellement précédée de ReceivedSignature
|
||||
|
||||
Yellowstone transaction_status
|
||||
= update execution/status avec signature, slot, is_vote, index et error
|
||||
```
|
||||
|
||||
Une struct avec de nombreux `Option` perdrait les distinctions entre snapshot, observation de réception, transition de commitment et update d'exécution. La décision de `0.3.1` est donc confirmée.
|
||||
|
||||
### 7.4 Vote — REPORTÉ
|
||||
|
||||
`voteSubscribe` est explicitement pré-consensus et ne garantit pas l'entrée du vote dans le ledger. Le booléen `is_vote` de la famille transaction Yellowstone qualifie une transaction et n'est pas une notification gossip équivalente.
|
||||
|
||||
Aucun `VoteEvent` partagé n'est admis.
|
||||
|
||||
### 7.5 Account/program — REJET Interface
|
||||
|
||||
Les updates account/program peuvent contenir l'état complet nécessaire à l'acquisition RAW. `ksp-store-api` possède déjà :
|
||||
|
||||
```text
|
||||
RawAccountState
|
||||
RawAccountObservation
|
||||
```
|
||||
|
||||
Créer un second account event structurel dans Interface serait soit :
|
||||
|
||||
- un doublon persistant déguisé ;
|
||||
- un wrapper des DTOs Transport ;
|
||||
- un type incomplet qui perd les conditions d'admission RAW.
|
||||
|
||||
La conversion Transport -> Store API reste à la composition.
|
||||
|
||||
### 7.6 Transaction/block — REJET Interface
|
||||
|
||||
`RawTransaction` et `RawTransactionObservation` sont déjà Store-owned. Les blocs servent de conteneurs d'acquisition ou de payloads Transport riches. Aucun `RawBlock`, `TransactionEvent` ou `BlockEvent` transversal n'est ajouté.
|
||||
|
||||
### 7.7 Yellowstone Entry — REJET Interface
|
||||
|
||||
`Entry` n'a qu'un producer/protocole démontré et ne possède aucun consumer transversal proche. Il reste strictement Transport.
|
||||
|
||||
### 7.8 Notification after commit — REJET Interface
|
||||
|
||||
Les règles `KSP-NOTIFY-001..006` sont explicites : le format canonique du signal « persisted data available » appartient à `ksp-store-api`, est publié après commit et ne constitue jamais le backlog. `0.3.5` ne crée aucun équivalent Interface.
|
||||
|
||||
## 8. API sketch admise
|
||||
|
||||
La seule API planifiée pour `pre.002` est conceptuellement :
|
||||
|
||||
```rust
|
||||
#[non_exhaustive]
|
||||
pub enum SlotLifecycleStage {
|
||||
Processed,
|
||||
FirstShredReceived,
|
||||
Completed,
|
||||
CreatedBank,
|
||||
Dead,
|
||||
}
|
||||
|
||||
pub struct SlotLifecycleEvent {
|
||||
slot: u64,
|
||||
stage: SlotLifecycleStage,
|
||||
}
|
||||
```
|
||||
|
||||
Surface publique visée :
|
||||
|
||||
```text
|
||||
SlotLifecycleStage
|
||||
SlotLifecycleEvent::new(slot, stage)
|
||||
SlotLifecycleEvent::slot()
|
||||
SlotLifecycleEvent::stage()
|
||||
```
|
||||
|
||||
Décisions de représentation :
|
||||
|
||||
```text
|
||||
SlotLifecycleStage -> #[non_exhaustive] + Clone + Copy + Debug + Eq + PartialEq
|
||||
SlotLifecycleEvent -> champs privés + Clone + Copy + Debug + Eq + PartialEq
|
||||
Hash -> absent tant qu'un consumer réel ne l'exige pas
|
||||
validation -> aucune borne variable ; slot u64 conservé exactement
|
||||
error code -> aucun ; aucune admission faillible n'est nécessaire
|
||||
```
|
||||
|
||||
Contraintes :
|
||||
|
||||
- pas de serde imposé ;
|
||||
- pas de `String`, JSON, bytes, timestamp ou diagnostic ;
|
||||
- pas de network id dupliquant `RawNetworkId` ; la composition est déjà liée à son contexte réseau ;
|
||||
- `Debug` est sûr par construction ;
|
||||
- aucun error code n'est nécessaire si tout `u64` de slot et toute variante publique construite sont valides ;
|
||||
- aucune dépendance nouvelle n'est requise ;
|
||||
- aucun trait universel `Event`, `EventSource`, `Subscriber` ou `Handler` ;
|
||||
- aucune conversion `From<TransportType>` dans Interface, car cela créerait une dépendance interdite ;
|
||||
- les converters appartiennent au futur consumer/composition ou, si un usage concret le justifie plus tard, à une crate de composition dédiée.
|
||||
|
||||
Le nom final peut être ajusté pendant `pre.002` seulement si les canaris montrent une ambiguïté réelle. Le sens `slot + stage commun` ne doit pas être élargi.
|
||||
|
||||
## 9. Consumer proche et usage concret
|
||||
|
||||
L'architecture prévoit un futur worker RAW live :
|
||||
|
||||
```text
|
||||
subscriptions/fetch live
|
||||
-> ksp-onchain-transport-lib
|
||||
-> RAW ingestion
|
||||
-> D1 RAW
|
||||
```
|
||||
|
||||
Ce worker est le consumer proche qui peut recevoir des événements de progression/lifecycle de slot venant soit des WebSockets standard, soit de Yellowstone sans connaître les DTOs des deux protocoles lorsqu'il n'a besoin que de déclencher/ordonner une réaction de composition propre au lifecycle.
|
||||
|
||||
Cette API ne devient pas un prérequis de `0.3.6` : le premier backfill historique reste fondé sur Transport + Store et peut ne jamais consommer `SlotLifecycleEvent`.
|
||||
|
||||
## 10. Anti-duplication Store
|
||||
|
||||
| Contrat Store comparé | Chevauchement avec `SlotLifecycleEvent` | Pourquoi il n'y a pas de seconde vérité |
|
||||
|-----------------------------|-----------------------------------------|-----------------------------------------------------------------------------------------------|
|
||||
| `RawTransaction` | slot possible seulement | aucun payload/signature/format/hash ; l'event ne peut reconstruire une transaction |
|
||||
| `RawTransactionObservation` | slot indirect possible | aucune provenance acquisition, observation key ou timestamp durable |
|
||||
| `RawAccountState` | slot possible seulement | aucune pubkey/state hash/lamports/owner/data ; aucun état account |
|
||||
| `RawAccountObservation` | slot indirect possible | aucune référence account/provenance Geyser |
|
||||
| `RawAcquisitionProvenance` | aucun | pas d'origin/provider code/timestamps ; les metadata source restent Transport/composition |
|
||||
| `RawTimestamp` | aucun | aucun timestamp dans l'event, précisément pour éviter la fusion de clocks différentes |
|
||||
| `RawContentHash` | aucun | aucune identité de contenu durable |
|
||||
| `RawObservationKey` | aucun | aucune identité d'observation persistante |
|
||||
| notification after commit | aucun | SlotLifecycle précède/observe le réseau ; le wake-up Store référence une donnée déjà commitée |
|
||||
|
||||
Le gate doit conserver les canaris conceptuels suivants :
|
||||
|
||||
```text
|
||||
SlotLifecycleEvent -X-> RawTransaction
|
||||
SlotLifecycleEvent -X-> RawAccountState
|
||||
SlotLifecycleEvent -X-> RawAcquisitionProvenance
|
||||
SlotLifecycleEvent -X-> persisted-data notification
|
||||
|
||||
Interface -X-> ksp-store-api
|
||||
Interface -X-> ksp-store-lib
|
||||
Store API -X-> Interface
|
||||
```
|
||||
|
||||
Aucun champ du modèle admis ne doit pouvoir servir de substitut à une référence RAW durable.
|
||||
|
||||
## 11. Graphe cible
|
||||
|
||||
Après implémentation de la release :
|
||||
|
||||
```text
|
||||
ksp-interface-lib
|
||||
└── ksp-core-lib
|
||||
```
|
||||
|
||||
Aucune nouvelle dependency normale ou feature n'est planifiée.
|
||||
|
||||
Les consumers restent :
|
||||
|
||||
```text
|
||||
ksp-program-api
|
||||
-> ksp-interface-lib # ProgramInstruction / ProgramAccountMeta seulement
|
||||
|
||||
future acquisition composition / RAW live worker
|
||||
-> ksp-onchain-transport-lib
|
||||
-> ksp-interface-lib # SlotLifecycleEvent si utile
|
||||
-> ksp-store-lib / ksp-store-api selon ownership
|
||||
```
|
||||
|
||||
## 12. Threat model
|
||||
|
||||
| Risque | Menace | Garde planifiée |
|
||||
|--------------------------------|------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------|
|
||||
| mega enum | Interface devient catalogue de tous les transports | une seule famille étroite ; aucun `Event` générique |
|
||||
| Option soup | sémantiques différentes fusionnées par champs optionnels | `slot + stage` seulement ; status/log/vote non convergents reportés |
|
||||
| persistence creep | event-only devient second Store | aucun RAW/payload/cursor/retention ; `KSP-NOTIFY-*` reste Store API |
|
||||
| transport wrapper | copie des DTOs WS/gRPC/provider | aucune metadata protocol/provider dans le type Interface |
|
||||
| faux timestamp commun | horodatages WS et Yellowstone confondus | aucun timestamp partagé |
|
||||
| root/finality confusion | `root` normalisé artificiellement en `Finalized` | aucun stage Root/Finalized tant qu'une équivalence normative exacte n'est pas démontrée |
|
||||
| optimistic/confirmed confusion | `OptimisticConfirmation` fusionné à `Confirmed` | deux états exclus de l'intersection |
|
||||
| dead diagnostic leak | texte provider/validator traverse une API partagée durable | stage `Dead` sans diagnostic ; détail reste Transport |
|
||||
| cross-network confusion | event sans réseau mélangé entre sessions | conversion autorisée seulement dans une composition déjà liée à un contexte réseau ; pas de network id dupliqué |
|
||||
| unbounded payload | logs/JSON/bytes entrent dans Interface | aucun payload variable dans la famille admise |
|
||||
| public enum breakage | ajout futur casse les matches externes | `SlotLifecycleStage` non-exhaustive |
|
||||
| logging/runtime creep | crate passive acquiert tracing/Tokio/channel | aucune dependency/runtime/logging ajoutée |
|
||||
| Helius semantic promotion | extension provider devient norme KSP | Enhanced `transactionSubscribe` reste Transport |
|
||||
| Yellowstone protocol promotion | `Entry`/filters/created_at deviennent Interface | types Yellowstone restent Transport |
|
||||
|
||||
## 13. Stratégie de tests
|
||||
|
||||
### 13.1 `pre.002` — modèle admis
|
||||
|
||||
Tests unitaires Interface :
|
||||
|
||||
- chaque stage public est distinct ;
|
||||
- `slot` est conservé sans narrowing ;
|
||||
- le constructeur/getters sont passifs et déterministes ;
|
||||
- le type n'emporte aucune metadata de transport.
|
||||
|
||||
Tests d'intégration :
|
||||
|
||||
- crate-root public API ;
|
||||
- external consumer ;
|
||||
- dependency boundary Core-only ;
|
||||
- exact production module/export inventory.
|
||||
|
||||
### 13.2 Convergence sans dépendance Transport
|
||||
|
||||
`ksp-interface-lib` ne doit pas ajouter `ksp-onchain-transport-lib` même en dépendance normale pour « tester » les converters. Les preuves d'équivalence sémantique restent dans le plan/validation de release et les canaris de frontière Interface.
|
||||
|
||||
Si un converter concret est introduit plus tard dans une crate de composition, sa propre crate devra tester les mappings exacts :
|
||||
|
||||
```text
|
||||
SolanaSlotNotification -> Processed
|
||||
SolanaSlotUpdate::FirstShredReceived -> FirstShredReceived
|
||||
SolanaSlotUpdate::Completed -> Completed
|
||||
SolanaSlotUpdate::CreatedBank -> CreatedBank
|
||||
SolanaSlotUpdate::Dead -> Dead
|
||||
YellowstoneSlotStatus équivalents -> mêmes stages
|
||||
```
|
||||
|
||||
Et devra explicitement refuser de convertir les variantes hors intersection en un faux stage commun.
|
||||
|
||||
## 14. Prévision souple des prereleases
|
||||
|
||||
La release est dimensionnée pour rester dans une seule session et ne possède qu'une famille fonctionnelle retenue.
|
||||
|
||||
### `0.3.5-pre.001` — audit + plan
|
||||
|
||||
- lecture des règles/architectures/surfaces ;
|
||||
- audit externe actuel ;
|
||||
- matrice producer/fact et convergence ;
|
||||
- ownership et anti-duplication Store ;
|
||||
- threat model ;
|
||||
- API sketch ;
|
||||
- sizing et plan de release.
|
||||
|
||||
### `0.3.5-pre.002` — `SlotLifecycleEvent`
|
||||
|
||||
- implémenter la famille minimale admise ;
|
||||
- crate-root exports ;
|
||||
- tests unitaires et public API ciblés ;
|
||||
- préserver le graphe Core-only.
|
||||
|
||||
### `0.3.5-pre.003` — canaris externes + complétude API
|
||||
|
||||
- external consumer ;
|
||||
- inventaire exact des modules/exports ;
|
||||
- canaris négatifs contre Transport/Store/runtime/serde/logging ;
|
||||
- non-exhaustive et stabilité de la surface.
|
||||
|
||||
Cette tranche ne crée aucune deuxième famille d'event sauf réouverture documentée du gate avec preuve nouvelle. Le défaut est de conserver logs/status/vote/root reportés.
|
||||
|
||||
### `0.3.5-pre.004` — hardening final
|
||||
|
||||
- adversarial/API hardening ;
|
||||
- absence de payload/source metadata ;
|
||||
- absence de second RAW ;
|
||||
- validation du graphe et des dépendances ;
|
||||
- aucun élargissement fonctionnel opportuniste.
|
||||
|
||||
### `0.3.5-pre.005` — gate technique final
|
||||
|
||||
- gates Rust/workspace complets ;
|
||||
- `cargo tree` Interface normal/features/duplicates ;
|
||||
- aucun smoke live requis : le contrat est passif et ne possède aucun réseau.
|
||||
|
||||
### `0.3.5-pre.006` — réconciliation documentaire finale
|
||||
|
||||
- plan + validation ;
|
||||
- README/USAGE Interface durables et version-neutral ;
|
||||
- architecture durable uniquement si le rôle Interface doit être explicité ;
|
||||
- aucun CHANGELOG/ROADMAP/prompt suivant dans cette tranche.
|
||||
|
||||
### `0.3.5-pre.007` — préparation de publication
|
||||
|
||||
Lane minimale :
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
CHANGELOG.md
|
||||
ROADMAP.md
|
||||
prompts/025-V0_3_6_START_PROMPT.md
|
||||
deltas/0.3.5/pre.007.md
|
||||
```
|
||||
|
||||
Aucun code, README/USAGE, plan ou validation ne doit être rouvert ici.
|
||||
|
||||
### `0.3.5-rel.001` — stable
|
||||
|
||||
- mécanique de publication uniquement ;
|
||||
- version Cargo finale `0.3.5` ;
|
||||
- aucun rattrapage fonctionnel/documentaire.
|
||||
|
||||
## 15. Gates opérateur
|
||||
|
||||
### 15.1 Après chaque overlay fonctionnel
|
||||
|
||||
```text
|
||||
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
|
||||
```
|
||||
|
||||
Ajouter `cargo test -p ksp-program-api` lorsqu'une modification publique Interface pourrait affecter son consumer actuel.
|
||||
|
||||
### 15.2 Gate technique final
|
||||
|
||||
```text
|
||||
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 --workspace
|
||||
cargo tree -p ksp-interface-lib --edges normal
|
||||
cargo tree -p ksp-interface-lib -e features
|
||||
cargo tree --duplicates
|
||||
```
|
||||
|
||||
Aucun live test n'est justifié par `0.3.5` : un type passif ne doit pas acquérir de dépendance réseau pour prouver son existence.
|
||||
|
||||
## 16. Hors périmètre
|
||||
|
||||
```text
|
||||
grand enum Event
|
||||
event bus / channel / broadcaster
|
||||
scheduler / worker / job
|
||||
backfill 0.3.6
|
||||
persistence ou migration Store
|
||||
nouvelle capability Store
|
||||
RawLog / RawBlock
|
||||
TransactionStatusObservation fusionné
|
||||
VoteEvent partagé
|
||||
Root == Finalized
|
||||
OptimisticConfirmation == Confirmed
|
||||
Helius Enhanced DTO dans Interface
|
||||
Yellowstone Entry dans Interface
|
||||
serde/wincode/borsh ajouté sans protocole réel
|
||||
logging/runtime dans Interface
|
||||
conversion Transport -> Interface possédée par Interface
|
||||
```
|
||||
|
||||
## 17. Critère de clôture de `0.3.5`
|
||||
|
||||
La release peut fermer si et seulement si :
|
||||
|
||||
```text
|
||||
une famille minimale SlotLifecycle est publique et bornée
|
||||
intersection = Processed + FirstShredReceived + Completed + CreatedBank + Dead
|
||||
aucune variante hors intersection n'est normalisée artificiellement
|
||||
aucun payload/diagnostic/timestamp/provider metadata n'entre dans Interface
|
||||
Interface reste Core-only
|
||||
Store RAW 10/10 reste inchangé
|
||||
KSP-NOTIFY ownership reste Store API
|
||||
aucun event bus/runtime/persistence n'est ajouté
|
||||
external consumer et crate-root canaries passent
|
||||
README/USAGE finaux restent durables et version-neutral
|
||||
```
|
||||
|
||||
Si l'implémentation montre qu'un de ces invariants ne peut pas être préservé, la famille SlotLifecycle est retirée plutôt qu'élargie artificiellement.
|
||||
234
docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md
Normal file
234
docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md
Normal file
@@ -0,0 +1,234 @@
|
||||
<!-- file: docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Validation `0.3.5` — Interface passive acquisition events
|
||||
|
||||
## 1. Portée
|
||||
|
||||
Ce document est ouvert par `0.3.5-pre.001`. Il enregistre uniquement des constats d'audit et des décisions de gate réellement effectués ; aucun test Cargo de `0.3.5` n'est déclaré PASS dans cette tranche tant qu'il n'a pas été rejoué par l'opérateur.
|
||||
|
||||
Base :
|
||||
|
||||
```text
|
||||
v0.3.4
|
||||
workspace.package.version = 0.3.4
|
||||
```
|
||||
|
||||
Version de travail :
|
||||
|
||||
```text
|
||||
0.3.5-pre.1
|
||||
```
|
||||
|
||||
## 2. Gate d'entrée `v0.3.4`
|
||||
|
||||
Le log opérateur fourni avec l'archive indique un gate stable `v0.3.4` propre : audits Rust/Markdown, `cargo check`, Clippy, tests ciblés des crates, `cargo test --workspace`, `ksp-store-lib --no-default-features` et graphes Store ont été exécutés sans échec visible ; les smokes réseau restent explicitement ignorés/opt-in.
|
||||
|
||||
Cette preuve est l'entrée de `0.3.5`. Elle n'est pas réétiquetée comme validation exécutée dans l'environnement d'assemblage de `pre.001`.
|
||||
|
||||
## 3. Gate de lecture `pre.001`
|
||||
|
||||
| Contrôle | Résultat | Preuve / décision |
|
||||
|---------------------------------------|----------|--------------------------------------------------------------------------------------------------------|
|
||||
| règles globales relues | PASS | familles KSP-API/TRANSPORT/STORE/NOTIFY/PROC/REL et DEP applicables relues |
|
||||
| architecture durable relue | PASS | Interface passif, Transport protocol/runtime, Store persistant, composition owner des conversions |
|
||||
| fondation Interface stable relue | PASS | surface Program petite ; dépendance normale Core-only |
|
||||
| Store API RAW relu | PASS | `RawTransaction*` + `RawAccount*` restent Store-owned |
|
||||
| Store/PostgreSQL `0.3.2`–`0.3.4` relu | PASS | RAW physique 10/10 fermé ; aucune rétention account |
|
||||
| surfaces HTTP/WS/gRPC/Helius relues | PASS | status/log/slot/vote/account/transaction/block/Entry inventoriés |
|
||||
| documentation Solana courante auditée | PASS | `slotSubscribe`, `slotsUpdatesSubscribe`, status/log/vote/account/program, getTransaction/getBlock |
|
||||
| Yellowstone upstream courant audité | PASS | `SlotStatus` et familles SubscribeUpdate courantes |
|
||||
| Helius courant audité | PASS | standard WSS préserve wire Solana ; Enhanced `transactionSubscribe` reste extension provider |
|
||||
| producer/consumer inventory | PASS | une intersection lifecycle slot justifiée ; autres familles non admises |
|
||||
| threat model | PASS | mega enum, Option soup, Store duplication, timestamp/finality confusion et provider promotion couverts |
|
||||
| sizing release | PASS | 7 prereleases prévues avant `rel.001`, une seule famille fonctionnelle |
|
||||
|
||||
## 4. Matrice de décision par famille
|
||||
|
||||
| Famille | Décision | Owner | Motif déterminant |
|
||||
|---------------------------------------|-----------------|-----------------|---------------------------------------------------------------------------------------------|
|
||||
| slot lifecycle intersection | ADMIS | Interface | faits compacts exacts produits par Solana WS et Yellowstone ; pas de persistence |
|
||||
| root/finality | REPORTÉ | Transport | aucune équivalence normative exacte `root` <-> `Finalized` retenue |
|
||||
| optimistic/confirmed | REPORTÉ | Transport | aucune équivalence normative exacte retenue |
|
||||
| logs realtime | REPORTÉ | Transport | pas de seconde surface indépendante équivalente ; Yellowstone logs restent transaction/meta |
|
||||
| transaction status | REPORTÉ | Transport | HTTP snapshot != WS one-shot commitment != Yellowstone execution update |
|
||||
| vote | REPORTÉ | Transport | gossip pré-consensus != transaction qualifiée `is_vote` |
|
||||
| account/program | REJET Interface | Store/Transport | risque de doublon `RawAccountState`/observation ou wrapper Transport |
|
||||
| transaction | REJET Interface | Store/Transport | `RawTransaction`/observation déjà persistants |
|
||||
| block | REJET Interface | Transport | conteneur/payload d'acquisition ; aucun besoin passif transversal démontré |
|
||||
| Yellowstone Entry | REJET Interface | Transport | surface protocolaire mono-producer |
|
||||
| persisted-data available notification | REJET Interface | Store API | ownership normatif `KSP-NOTIFY-001..006` |
|
||||
| Helius Enhanced transaction | REJET Interface | Transport | extension provider-specific |
|
||||
|
||||
## 5. Intersection lifecycle retenue
|
||||
|
||||
| Stage Interface prévu | Producer Solana standard | Producer Yellowstone | Verdict | Détails exclus du contrat commun |
|
||||
|--------------------------|----------------------------------------|----------------------|---------|-------------------------------------------------------------------------|
|
||||
| `Processed` | `slotSubscribe` | `Processed` | PASS | WS parent/root ; Yellowstone filters/created_at/parent |
|
||||
| `FirstShredReceived` | `slotsUpdates::FirstShredReceived` | `FirstShredReceived` | PASS | timestamps/metadata source |
|
||||
| `Completed` | `slotsUpdates::Completed` | `Completed` | PASS | timestamps/metadata source |
|
||||
| `CreatedBank` | `slotsUpdates::CreatedBank` | `CreatedBank` | PASS | parent reste dans le DTO Transport riche |
|
||||
| `Dead` | `slotsUpdates::Dead` | `Dead` | PASS | diagnostic `err`/`dead_error` et timestamp restent Transport |
|
||||
| `Frozen` | `slotsUpdates::Frozen` | — | FAIL | pas d'intersection |
|
||||
| `OptimisticConfirmation` | `slotsUpdates::OptimisticConfirmation` | `Confirmed` | FAIL | noms/semantiques proches insuffisants sans équivalence normative exacte |
|
||||
| `Root` | `rootSubscribe` / `slotsUpdates::Root` | `Finalized` | FAIL | aucune normalisation root/finalized inventée |
|
||||
| `Confirmed` | — | `Confirmed` | FAIL | producer standard exact absent |
|
||||
| `Finalized` | — | `Finalized` | FAIL | producer standard exact absent |
|
||||
|
||||
## 6. Validation anti-Option-soup
|
||||
|
||||
Les modèles suivants sont explicitement **non admis** par le gate :
|
||||
|
||||
```text
|
||||
TransactionStatusObservation {
|
||||
confirmations?: ...,
|
||||
confirmation_status?: ...,
|
||||
received?: ...,
|
||||
is_vote?: ...,
|
||||
transaction_index?: ...,
|
||||
...
|
||||
}
|
||||
|
||||
SlotLifecycleEvent {
|
||||
parent?: ...,
|
||||
root?: ...,
|
||||
timestamp?: ...,
|
||||
dead_error?: ...,
|
||||
provider?: ...,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
La surface visée reste conceptuellement :
|
||||
|
||||
```text
|
||||
SlotLifecycleEvent { slot, stage }
|
||||
```
|
||||
|
||||
## 7. Validation anti-duplication Store
|
||||
|
||||
| Modèle Store stable | Action `0.3.5` | Justification |
|
||||
|---------------------------------|---------------------|------------------------------------------------|
|
||||
| `RawTransaction` | inchangé | payload durable/replayable |
|
||||
| `RawTransactionObservation` | inchangé | provenance persistante |
|
||||
| `RawAccountState` | inchangé | état account durable |
|
||||
| `RawAccountObservation` | inchangé | observation persistante |
|
||||
| pagination/cursors RAW | inchangés | contrats de navigation Store |
|
||||
| retention/tombstone transaction | inchangés | lifecycle de persistence Store |
|
||||
| notification after commit | non implémentée ici | ownership Store API réservé par `KSP-NOTIFY-*` |
|
||||
|
||||
Canari conceptuel : aucun futur fichier source Interface de `0.3.5` ne doit importer `ksp_store_api`, `ksp_store_lib` ou copier leurs modèles.
|
||||
|
||||
## 8. Validation dependency/ownership
|
||||
|
||||
État de l'archive stable inspecté :
|
||||
|
||||
```text
|
||||
crates/ksp-interface-lib/Cargo.toml
|
||||
runtime dependency = ksp-core-lib seulement
|
||||
```
|
||||
|
||||
Cible `0.3.5` :
|
||||
|
||||
```text
|
||||
ksp-interface-lib -> ksp-core-lib
|
||||
ksp-interface-lib -X-> ksp-onchain-transport-lib
|
||||
ksp-interface-lib -X-> ksp-store-api
|
||||
ksp-interface-lib -X-> ksp-store-lib
|
||||
ksp-interface-lib -X-> ksp-program-api
|
||||
ksp-interface-lib -X-> serde/tracing/tokio/channel runtime additions
|
||||
```
|
||||
|
||||
Le `cargo tree` ne peut pas être exécuté dans l'environnement d'assemblage actuel, où `cargo` est absent. Le gate opérateur est donc obligatoire sur l'overlay.
|
||||
|
||||
## 9. Consumer concret retenu
|
||||
|
||||
Consumer proche documenté par l'architecture : futur worker RAW live / composition d'acquisition.
|
||||
|
||||
Usage possible sans dépendance protocol-specific :
|
||||
|
||||
```text
|
||||
Solana standard WS -----------+
|
||||
+-> converter composition -> SlotLifecycleEvent -> réaction lifecycle du consumer
|
||||
Yellowstone gRPC -------------+
|
||||
```
|
||||
|
||||
`0.3.6` backfill n'est pas forcé d'utiliser ce type ; il reste une composition historique Transport + Store.
|
||||
|
||||
## 10. Threat gates
|
||||
|
||||
| Gate | Attendu `0.3.5` | Statut `pre.001` |
|
||||
|----------------------------------|-----------------------------------------------|------------------|
|
||||
| mega enum | absent | PLAN PASS |
|
||||
| protocol/provider enum leakage | absent | PLAN PASS |
|
||||
| timestamp semantics conflated | absent | PLAN PASS |
|
||||
| root/finalized conflated | absent | PLAN PASS |
|
||||
| optimistic/confirmed conflated | absent | PLAN PASS |
|
||||
| dead diagnostic in shared API | absent | PLAN PASS |
|
||||
| RAW Store duplication | absent | PLAN PASS |
|
||||
| event persistence | absent | PLAN PASS |
|
||||
| event bus/runtime | absent | PLAN PASS |
|
||||
| network id duplicated from Store | absent | PLAN PASS |
|
||||
| cross-network use | composition doit conserver son scope réseau | À CANARIER |
|
||||
| public enum evolution | `SlotLifecycleStage` doit être non-exhaustive | À IMPLÉMENTER |
|
||||
| Core-only graph | aucune dependency nouvelle | À REJOUER |
|
||||
| external consumer | type consommable depuis crate externe | À IMPLÉMENTER |
|
||||
|
||||
## 11. Fichiers de `pre.001`
|
||||
|
||||
Ajoutés :
|
||||
|
||||
```text
|
||||
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.001.md
|
||||
```
|
||||
|
||||
Modifié :
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
```
|
||||
|
||||
Aucun autre fichier ne doit changer dans cet overlay.
|
||||
|
||||
## 12. Validations exécutées dans l'environnement d'assemblage
|
||||
|
||||
Exécutables sans Cargo :
|
||||
|
||||
```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.5
|
||||
```
|
||||
|
||||
Le résultat réel est enregistré dans `deltas/0.3.5/pre.001.md` après exécution.
|
||||
|
||||
## 13. Validations opérateur requises
|
||||
|
||||
À appliquer sur le repository `v0.3.4` après extraction de l'overlay :
|
||||
|
||||
```text
|
||||
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
|
||||
```
|
||||
|
||||
Aucun `cargo test -p ksp-program-api` n'est requis par le contenu de `pre.001`, car aucun contrat public Interface n'est encore modifié. Il devient requis à partir de la première tranche qui change réellement la surface publique concernée.
|
||||
|
||||
## 14. Exit gate `pre.001`
|
||||
|
||||
`pre.001` est prêt à livrer lorsque :
|
||||
|
||||
```text
|
||||
plan + validation + delta existent
|
||||
workspace.package.version = 0.3.5-pre.1
|
||||
une seule famille est admise : SlotLifecycle
|
||||
stages admis = Processed / FirstShredReceived / Completed / CreatedBank / Dead
|
||||
logs/status/vote/root/account/transaction/block/Entry/post-commit sont classés explicitement
|
||||
aucun fichier Rust/Transport/Store n'est modifié
|
||||
les audits statiques disponibles sont propres
|
||||
les gates Cargo non exécutables sont explicitement laissés à l'opérateur
|
||||
```
|
||||
Reference in New Issue
Block a user