v0.3.5-pre.001

This commit is contained in:
2026-08-31 09:45:27 +02:00
parent c7cfb9557d
commit c24e4c48f8
4 changed files with 1027 additions and 2 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 382 # version: 383
[workspace] [workspace]
resolver = "3" 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"] 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] [workspace.package]
version = "0.3.4" version = "0.3.5-pre.1"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

119
deltas/0.3.5/pre.001.md Normal file
View 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
```

View 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.

View 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
```