v0.3.5-pre.008

This commit is contained in:
2026-08-31 14:01:23 +02:00
parent 80be36bfdd
commit 1b9104d64b
5 changed files with 566 additions and 9 deletions

View File

@@ -1,8 +1,20 @@
<!-- file: CHANGELOG.md --> <!-- file: CHANGELOG.md -->
<!-- version: 23 --> <!-- version: 24 -->
# Changelog KSP # Changelog KSP
## 0.3.5 — Interface acquisition events partagés — 2026-08-31
`0.3.5` étend `ksp-interface-lib` avec deux familles passives d'acquisition réellement partagées, sans transformer Interface en runtime, en event bus ou en seconde couche RAW. `SlotLifecycleEvent` expose un `slot` et un `SlotLifecycleStage` non exhaustif limité à `Processed`, `FirstShredReceived`, `Completed`, `CreatedBank`, `Dead`, `OptimisticallyConfirmed` et `Rooted`. La normalisation conserve la sémantique commune : les notifications Solana `optimisticConfirmation` et Yellowstone `Confirmed` convergent vers `OptimisticallyConfirmed`, tandis que Solana `root` et Yellowstone `Finalized` convergent vers `Rooted`; les différences d'ordre, de complétude, de replay et de transport restent la responsabilité du producteur/Transport.
La seconde famille matérialise le fait minimal d'exécution transactionnelle partagé par plusieurs sources. `TransactionSignature` possède exactement 64 octets et un `Debug` redacted, `TransactionExecutionOutcome` distingue seulement `Succeeded` et `Failed`, et `TransactionExecutionEvent` transporte uniquement `slot + signature + outcome`. Les logs, erreurs provider détaillées, commitments, indexes, timestamps, filtres et payloads complets restent Transport-owned. Les snapshots HTTP `getSignatureStatuses`, les transitions one-shot `signatureSubscribe`, un éventuel `TransactionLogEvent`, les votes et les entrées Yellowstone ne sont pas fusionnés artificiellement dans ce contrat.
La frontière d'ownership reste stricte : les DTOs wire/provider demeurent dans `ksp-onchain-transport-lib`, les événements passifs provider-neutral sont Interface-owned, et les modèles persistants/replayables `RawTransaction` / `RawAccountState` restent `ksp-store-api`. `ksp-interface-lib` conserve exactement `ksp-core-lib` comme seule dépendance normale, sans feature propre, dev/build dependency, serde, codec, logging ou runtime. Les canaris publics, external consumer, inventaires exacts et hardening vérifient également qu'aucun second RAW, metadata source ou payload hostile n'entre dans la surface Interface.
Les gates de clôture passent audits Rust/Markdown, `cargo check --workspace`, Clippy all-targets, tests ciblés Interface/Program API, `cargo test --workspace` et graphes Cargo. `cargo tree -p ksp-interface-lib --edges normal` confirme le chemin `ksp-interface-lib -> ksp-core-lib -> solana-pubkey -> solana-address`; le graphe features ne montre aucune feature propre Interface et les doublons éventuels restent ceux du workspace global. La documentation durable a été réconciliée et `TransactionLogEvent` est conservé comme idée différée soumise à un nouveau gate consumer/bornes.
`prompts/025-V0_3_6_START_PROMPT.md` ouvre `0.3.6` sur `ksp-job-api` et un premier backfill historique RAW concret. Le job doit consommer `ksp-store-lib`, conserver policy/batch-size/progression/checkpoint hors de Store et auditer en `pre.001` le premier parcours `RawTransaction` historique, avec `getSignaturesForAddress` + `getTransaction` comme candidat prioritaire plutôt que comme décision irrévocable.
## 0.3.4 — Store/PostgreSQL RawAccountState + complétude RAW — 2026-08-31 ## 0.3.4 — Store/PostgreSQL RawAccountState + complétude RAW — 2026-08-31
`0.3.4` complète la seconde vertical slice RAW physique sur le couple `ksp-store-lib` / `ksp-store-postgres-lib` et ferme la conformance PostgreSQL des **10 capabilities** backend-agnostic de `ksp-store-api` : les six capabilities `RawTransaction*` acquises en `0.3.3` restent intactes et les quatre capabilities `RawAccountStateRead`, `RawAccountStateWrite`, `RawAccountObservationRead` et `RawAccountObservationWrite` sont désormais implémentées par `PostgresBackend` puis dispatchées par la façade `Store`. La séparation reste stricte : les consommateurs ordinaires passent par `ksp-store-lib`, le backend PostgreSQL conserve SQL/driver/pool/TLS/migrations privés, et la façade reste compilable/testable sans backend via `--no-default-features`. `0.3.4` complète la seconde vertical slice RAW physique sur le couple `ksp-store-lib` / `ksp-store-postgres-lib` et ferme la conformance PostgreSQL des **10 capabilities** backend-agnostic de `ksp-store-api` : les six capabilities `RawTransaction*` acquises en `0.3.3` restent intactes et les quatre capabilities `RawAccountStateRead`, `RawAccountStateWrite`, `RawAccountObservationRead` et `RawAccountObservationWrite` sont désormais implémentées par `PostgresBackend` puis dispatchées par la façade `Store`. La séparation reste stricte : les consommateurs ordinaires passent par `ksp-store-lib`, le backend PostgreSQL conserve SQL/driver/pool/TLS/migrations privés, et la façade reste compilable/testable sans backend via `--no-default-features`.

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 390 # version: 391
[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.5-pre.7" version = "0.3.5-pre.8"
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"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md --> <!-- file: ROADMAP.md -->
<!-- version: 98 --> <!-- version: 99 -->
# Roadmap KSP # Roadmap KSP
@@ -97,8 +97,8 @@ RAW -> STRUCTURAL -> DECODED -> DOMAIN
- [X] `0.3.2``ksp-store-lib` + `ksp-store-postgres-lib` stables comme fondation runtime/backend PostgreSQL : feature `postgres` par défaut, `Store` lié à un unique `RawNetworkId`, Config `std.store` avec targets/bases `devnet`/`mainnet`/`testnet`, pool Deadpool borné, `tokio-postgres`, TLS Rustls `Disabled`/`VerifyFull`, moteur de migrations privé `V000` + SHA-256/advisory lock, health/readiness portable et close borné. Gate complet + PostgreSQL réel major 17 verts ; aucune table/capability `RawTransaction`/`RawAccountState` métier n'est encore ajoutée. - [X] `0.3.2``ksp-store-lib` + `ksp-store-postgres-lib` stables comme fondation runtime/backend PostgreSQL : feature `postgres` par défaut, `Store` lié à un unique `RawNetworkId`, Config `std.store` avec targets/bases `devnet`/`mainnet`/`testnet`, pool Deadpool borné, `tokio-postgres`, TLS Rustls `Disabled`/`VerifyFull`, moteur de migrations privé `V000` + SHA-256/advisory lock, health/readiness portable et close borné. Gate complet + PostgreSQL réel major 17 verts ; aucune table/capability `RawTransaction`/`RawAccountState` métier n'est encore ajoutée.
- [X] `0.3.3` — Vertical slice PostgreSQL `RawTransaction` complète sur `ksp-store-lib` + `ksp-store-postgres-lib` : six capabilities transaction/observation/rétention, V001 physique liée à un réseau, acquisition canonical+observation atomique, idempotence/conflit, get/list keyset cursorisé, archive/purge/tombstone/ForceRehydrate, hardening des erreurs et du schéma, concurrence et rollback validés sur PostgreSQL 17. - [X] `0.3.3` — Vertical slice PostgreSQL `RawTransaction` complète sur `ksp-store-lib` + `ksp-store-postgres-lib` : six capabilities transaction/observation/rétention, V001 physique liée à un réseau, acquisition canonical+observation atomique, idempotence/conflit, get/list keyset cursorisé, archive/purge/tombstone/ForceRehydrate, hardening des erreurs et du schéma, concurrence et rollback validés sur PostgreSQL 17.
- [X] `0.3.4` — Vertical slice PostgreSQL `RawAccountState` complète sur `ksp-store-lib` + `ksp-store-postgres-lib` : quatre capabilities account ajoutées aux six transaction pour une conformance RAW 10/10, V002 additive de 32 ressources au-dessus de V000/V001 immuables, state+observation atomiques, idempotence/conflit exacts, metadata Yellowstone observation-only, get/list keyset `(slot,pubkey,state_hash)` avec cursor KSPA anti-replay, hardening cross-family et live validé sur PostgreSQL 17 sans rétention destructive account. - [X] `0.3.4` — Vertical slice PostgreSQL `RawAccountState` complète sur `ksp-store-lib` + `ksp-store-postgres-lib` : quatre capabilities account ajoutées aux six transaction pour une conformance RAW 10/10, V002 additive de 32 ressources au-dessus de V000/V001 immuables, state+observation atomiques, idempotence/conflit exacts, metadata Yellowstone observation-only, get/list keyset `(slot,pubkey,state_hash)` avec cursor KSPA anti-replay, hardening cross-family et live validé sur PostgreSQL 17 sans rétention destructive account.
- [ ] `0.3.5` Étendre `ksp-interface-lib` uniquement avec les modèles passifs/event-only dont une matrice des surfaces HTTP/WS/Yellowstone/Helius démontre la sémantique réellement partagée et le besoin consumer ; auditer notamment logs, slot/root/slotsUpdates, transaction status et vote, sans dupliquer `RawTransaction`/`RawAccountState`, sans event bus et sans dépendance Interface vers Transport/Store. - [X] `0.3.5``ksp-interface-lib` étendu avec deux familles passives réellement partagées : `SlotLifecycleEvent` (`Processed`, `FirstShredReceived`, `Completed`, `CreatedBank`, `Dead`, `OptimisticallyConfirmed`, `Rooted`) et `TransactionExecutionEvent` (`slot + TransactionSignature[64] + Succeeded/Failed`). Interface reste Core-only, provider-neutral, sans serde/codec/runtime/event bus et sans duplication de `RawTransaction`/`RawAccountState`; les DTOs riches restent Transport-owned et les candidats non convergents restent différés.
- [ ] `0.3.6` — Introduire `ksp-job-api` et un premier job de backfill historique concret consommant `ksp-store-lib`, avec policy/batch-size/progression possédés par le job et non par Store. - [ ] `0.3.6` — Introduire `ksp-job-api` et un premier job de backfill historique RAW concret consommant `ksp-store-lib`; auditer en priorité un backfill `RawTransaction` par adresse via pagination Transport, avec policy/batch-size/progression/checkpoint/cancellation possédés par le job et jamais par Store.
- [ ] `0.3.7` — Introduire une application spécialisée de backfill/inspection RAW. - [ ] `0.3.7` — Introduire une application spécialisée de backfill/inspection RAW.
- [ ] Compléter ensuite la couche RAW avec le worker/service live, son contrôle et les outils dexploitation réellement nécessaires avant de passer à la couche de normalisation générique suivante. - [ ] Compléter ensuite la couche RAW avec le worker/service live, son contrôle et les outils dexploitation réellement nécessaires avant de passer à la couche de normalisation générique suivante.
@@ -106,9 +106,10 @@ RAW -> STRUCTURAL -> DECODED -> DOMAIN
- [ ] **TODO** — maintenir la matrice dadmission HTTP/WS/gRPC/provider lors de toute nouvelle famille N1 : plusieurs sources ne convergent vers un même struct que si elles satisfont la même sémantique sans perte. - [ ] **TODO** — maintenir la matrice dadmission HTTP/WS/gRPC/provider lors de toute nouvelle famille N1 : plusieurs sources ne convergent vers un même struct que si elles satisfont la même sémantique sans perte.
- [X] `RawAccountState` + observation — contrat commun stabilisé en `0.3.1` avec bytes complets + slot, provenance séparée et enrichissements source-specific optionnels ; la persistence PostgreSQL physique est complétée en `0.3.4` avec les quatre capabilities account et la conformance RAW 10/10. - [X] `RawAccountState` + observation — contrat commun stabilisé en `0.3.1` avec bytes complets + slot, provenance séparée et enrichissements source-specific optionnels ; la persistence PostgreSQL physique est complétée en `0.3.4` avec les quatre capabilities account et la conformance RAW 10/10.
- [ ] **TODO**`TransactionStatusObservation` : réauditer `signatureSubscribe`, `getSignatureStatuses`, Yellowstone TransactionStatus et extensions provider lorsquun consumer réel apparaît ; ne pas fusionner snapshot, transition et update dans un modèle Option-soup. - [ ] **TODO**statut/commitment transactionnel restant : `0.3.5` couvre uniquement le fait passif dexécution `slot + signature + outcome`; réauditer séparément `signatureSubscribe` et `getSignatureStatuses` lorsquun consumer de commitment/snapshot réel apparaît, sans fusionner snapshot, transition et execution update dans un modèle Option-soup.
- [ ] **TODO** — logs realtime : conserver `logMessages` dans `RawTransaction` jusquà la décomposition STRUCTURAL ; traiter `logsSubscribe` comme event-only candidat et décider son contrat passif dans `ksp-interface-lib`, sans table Store par défaut. Le format canonique dun wake-up « donnée persistée disponible » reste distinct et appartient à `ksp-store-api` conformément à `KSP-NOTIFY-*`, mais ne sera matérialisé quavec un publisher/consumer réel. - [ ] **IDEA** — logs realtime enrichis : `logsSubscribe` alimente déjà la projection minimale `TransactionExecutionEvent`, mais un éventuel `TransactionLogEvent` portant les lignes de log reste différé dans `docs/IDEAS.md` jusquà démonstration dun consumer et de bornes explicites. `logMessages` reste dans `RawTransaction` jusquà STRUCTURAL ; le wake-up post-commit reste distinct et Store API-owned conformément à `KSP-NOTIFY-*`.
- [ ] **TODO** slot/root/slotsUpdates et vote : ne créer un modèle passif commun que si un consumer realtime réel et une sémantique cross-ledger/provider justifient le contrat ; aucune persistence Store par défaut. - [X] slot/root/slotsUpdates `0.3.5` stabilise `SlotLifecycleEvent` pour lintersection réellement partagée, sans persistence Store par défaut et sans promettre lordre/complétude du flux.
- [ ] **TODO** — vote realtime : reste hors Interface tant quaucun consumer transversal et aucune sémantique provider-neutral suffisamment précise ne justifient un contrat partagé.
- [ ] **IDEA**`RawBlock` : ne rouvrir que si une information block-level non reconstructible devient nécessaire ; `getBlock` doit dabord être traité comme source de `RawTransaction`, pas comme invitation à recopier le ledger en blocs. - [ ] **IDEA**`RawBlock` : ne rouvrir que si une information block-level non reconstructible devient nécessaire ; `getBlock` doit dabord être traité comme source de `RawTransaction`, pas comme invitation à recopier le ledger en blocs.
- [ ] **REJET ACTUEL** — Yellowstone `Entry` : trop bas niveau et aucune destination replay/decomposition/event métier justifiant un modèle KSP nest identifiée. - [ ] **REJET ACTUEL** — Yellowstone `Entry` : trop bas niveau et aucune destination replay/decomposition/event métier justifiant un modèle KSP nest identifiée.
- [ ] **TODO** — processing ledger : reprendre lidée kbot2/kbot3 `stage + processor identity/version + input identity/hash + terminal status`, sans faire dun `processed: bool` la preuve durable unique ; prévoir force replay/version upgrades lorsque les processors seront ouverts. - [ ] **TODO** — processing ledger : reprendre lidée kbot2/kbot3 `stage + processor identity/version + input identity/hash + terminal status`, sans faire dun `processed: bool` la preuve durable unique ; prévoir force replay/version upgrades lorsque les processors seront ouverts.

112
deltas/0.3.5/pre.008.md Normal file
View File

@@ -0,0 +1,112 @@
# Delta `0.3.5-pre.008`
## Objet
Préparer la publication de `0.3.5` après le gate technique final et la réconciliation documentaire propres, sans rouvrir le code ni les documents de conception de la release.
## Base
```text
0.3.5-pre.007
workspace.package.version = 0.3.5-pre.7
```
Le gate opérateur de `pre.007` est propre :
```text
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (240 table(s), 146 file(s))
cargo check --workspace: PASS
cargo clippy --workspace --all-targets: PASS
cargo test -p ksp-interface-lib: PASS
cargo test -p ksp-program-api: PASS
```
Le gate technique final `pre.006` avait déjà confirmé `cargo test --workspace` et les graphes Cargo Interface Core-only.
## Modifications
### Version workspace
```text
0.3.5-pre.8
```
Le numéro d'en-tête de `Cargo.toml` est incrémenté avec cette modification réelle.
### `CHANGELOG.md`
Ajout de l'entrée de release `0.3.5` décrivant :
- `SlotLifecycleEvent` et ses sept stages admis ;
- `TransactionSignature`, `TransactionExecutionOutcome` et `TransactionExecutionEvent` ;
- les frontières Transport / Interface / Store ;
- le graphe Interface Core-only ;
- les gates finaux propres ;
- l'ouverture de `0.3.6` sur Job API + premier backfill RAW.
### `ROADMAP.md`
- `0.3.5` passe à terminé ;
- `0.3.6` est précisé comme premier backfill RAW avec ownership Job de la policy/progression/checkpoint ;
- les TODO historiques sont réconciliés avec les deux familles Interface réellement acquises ;
- `TransactionLogEvent` reste une idée différée et `vote` reste hors Interface.
### Prompt suivant
Ajout de :
```text
prompts/025-V0_3_6_START_PROMPT.md
```
Le prompt ouvre `0.3.6` sur :
```text
ksp-job-api
+ premier backfill historique RAW concret
+ audit prioritaire RawTransaction par adresse
+ getSignaturesForAddress -> getTransaction comme candidat
+ policy/batch/progression/checkpoint/cancellation Job-owned
```
L'archive historique kbot3 n'est pas requise pour cette release.
## Fichiers de la tranche
Exactement :
```text
Cargo.toml
CHANGELOG.md
ROADMAP.md
prompts/025-V0_3_6_START_PROMPT.md
deltas/0.3.5/pre.008.md
```
Explicitement inchangés :
```text
crates/**
docs/architecture/**
docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md
docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md
crates/ksp-interface-lib/README.md
crates/ksp-interface-lib/USAGE.md
```
## Gate demandé
```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 -p ksp-program-api
```
Si ce gate reste propre, la tranche suivante est `0.3.5-rel.001` et doit être strictement mécanique : version stable `0.3.5`, delta de release et aucune correction fonctionnelle/documentaire.

View File

@@ -0,0 +1,432 @@
<!-- file: prompts/025-V0_3_6_START_PROMPT.md -->
<!-- version: 1 -->
# Prompt de démarrage `0.3.6` — Job API + premier backfill historique RAW
## 1. Contexte de reprise
La base attendue est la release stable :
```text
v0.3.5
```
La surface acquise doit notamment être :
```text
ksp-store-api
-> RAW backend-agnostic
-> RawTransaction + RawAccountState + observations
-> 10 capabilities object-safe
ksp-store-lib
-> façade runtime backend-neutral
-> backend postgres activé par feature par défaut
ksp-store-postgres-lib
-> PostgreSQL 17 validé
-> RAW 10/10 physique
ksp-interface-lib
-> ProgramAccountMeta / ProgramInstruction
-> SlotLifecycleEvent / SlotLifecycleStage
-> TransactionSignature / TransactionExecutionEvent / TransactionExecutionOutcome
-> dépendance normale Core-only
ksp-onchain-transport-lib
-> HTTP Solana typed complet
-> WS standard + Helius
-> Yellowstone engine actuel
```
`0.3.5` a confirmé la séparation suivante :
```text
DTO riche / provider-specific -> Transport
fait passif provider-neutral -> Interface
modèle persistant / replayable -> Store API
backlog durable -> Store
policy / batch-size / progression -> Job/Worker
```
La release à ouvrir est :
```text
0.3.6 — ksp-job-api + premier backfill historique RAW
```
La première tranche est `0.3.6-pre.001` et commence par **audit de la base réelle + brainstorming + sizing + plan**, sans implémentation fonctionnelle lourde.
## 2. Mission
Cette release doit introduire :
1. `ksp-job-api`, comme API passive et backend-neutral de lifecycle/progression pour traitements bornés ;
2. un premier job historique RAW concret ;
3. une composition explicite Transport -> conversion RAW -> `ksp-store-lib` ;
4. une ownership claire de la policy, de la pagination réseau, du batch-size, du checkpoint et de la cancellation.
Le premier candidat prioritaire est un backfill `RawTransaction` historique **scopé par adresse**, fondé sur les primitives HTTP Solana existantes :
```text
getSignaturesForAddress
|
v
signatures ordonnées newest -> oldest
|
v
getTransaction
|
v
conversion vers RawTransaction + observation
|
v
ksp-store-lib
```
Ce candidat n'est pas encore une décision irrévocable : `pre.001` doit vérifier la sémantique officielle actuelle, la surface Transport réelle, les bornes provider/RPC, les lacunes éventuelles et la faisabilité d'une clôture complète de la release dans une session.
## 3. Principes d'architecture non négociables
### 3.1 Store reste une primitive de persistence/navigation
Ne pas déplacer dans Store :
```text
batch-size métier
priorité de job
retry policy métier
range historique décidé par le job
checkpoint métier
cadence
scheduler
progression
cancellation
```
Store peut exposer ses primitives de lecture/écriture/cursorisation existantes ; il ne devient pas orchestrateur.
### 3.2 `ksp-job-api` reste passif
L'API Job ne doit pas devenir :
```text
scheduler global
thread pool
runtime Tokio propriétaire
event bus
queue distribuée
registry de tous les jobs KSP
backend de persistence implicite
```
`pre.001` doit déterminer la surface minimale réellement nécessaire au premier consumer. Les concepts à auditer, sans les figer d'avance, sont notamment :
```text
JobId
JobState
JobDescriptor
JobProgress
JobOutcome
JobCheckpoint
cancellation / stop reason
```
Éviter les structs Option-soup et les états dont la sémantique n'est pas observable par le premier job.
### 3.3 Implémentation du backfill séparée de l'API
`ksp-job-api` ne doit pas dépendre de Transport ou d'un backend Store physique.
Le job concret peut dépendre de :
```text
ksp-job-api
ksp-onchain-transport-lib
ksp-store-lib
ksp-core-lib si réellement nécessaire
ksp-logging-lib pour le comportement runtime
```
Aucune dépendance directe vers `ksp-store-postgres-lib` n'est autorisée au consumer ordinaire.
Le nom et la forme de la crate d'implémentation du premier job doivent être décidés en `pre.001` après audit des conventions workspace. Ne pas créer plusieurs crates auxiliaires spéculatives.
### 3.4 Conversion RAW
Le job doit produire les modèles RAW backend-neutral existants et écrire via `ksp-store-lib`.
Il ne doit pas :
```text
écrire du SQL
connaître tokio-postgres/deadpool
inventer un RawTransaction concurrent
faire du decode Program
produire STRUCTURAL/DECODED/DOMAIN
persister des DTOs Transport tels quels
```
Auditer si la conversion Transport -> RAW mérite déjà une petite pipeline réutilisable. Par défaut, ne pas introduire `ksp-pipeline-raw-ingestion-lib` tant que la réutilisation job + futur worker ne justifie pas clairement une crate séparée.
## 4. Audit obligatoire de `pre.001`
Avant toute implémentation, relire au minimum :
```text
RULES.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/PROMPT_STRUCTURE.md
docs/VERSION_WORKFLOW.md
docs/FILE_CONTRACTS.md
docs/architecture/002-LAYERS_AND_DEPENDENCIES.md
docs/architecture/003-COMPONENT_CONTRACTS.md
docs/architecture/004-COMPONENT_INVENTORY.md
docs/architecture/005-DEPENDENCY_GRAPH.md
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
crates/ksp-store-api/**
crates/ksp-store-lib/**
crates/ksp-onchain-transport-lib/**
```
Puis auditer explicitement :
### 4.1 Transport historique
Vérifier dans le code KSP et dans la documentation officielle actuelle :
```text
getSignaturesForAddress
getTransaction
```
Pour `getSignaturesForAddress`, confirmer notamment :
```text
ordre newest -> oldest
before
until
limit
commitment
minContextSlot
sémantique de fin de pagination
cardinalité/limites réellement supportées
```
Pour `getTransaction`, confirmer notamment :
```text
commitment supporté
encoding retenu
maxSupportedTransactionVersion
null / transaction unavailable
slot
blockTime
meta / transaction completeness
```
Ne pas inventer une capacité de scan global de toutes les transactions si le RPC standard ne l'offre pas.
### 4.2 Store
Inventorier les capacités `RawTransaction*` réellement disponibles et vérifier comment le job doit :
```text
écrire canonical + observation
traiter l'idempotence
traiter un conflit réel
éviter une réhydratation implicite d'un tombstone
respecter le RawNetworkId du Store
```
Le job consomme `ksp-store-lib`; il ne bypass pas la façade pour parler à `ksp-store-api` ou au backend PostgreSQL directement sauf preuve architecturale contraire explicite.
### 4.3 Checkpoint et reprise
Définir ce qui constitue un checkpoint fiable pour une pagination newest -> oldest par adresse.
Le checkpoint doit être distingué de :
```text
cursor Store
signature candidate courante
signature réellement persistée
frontière contiguë complétée
simple compteur de progression
```
La cancellation et une reprise doivent éviter de sauter silencieusement une transaction non terminée.
Ne pas créer une table Job dans Store par réflexe. Si une persistence de checkpoint devient nécessaire, l'ownership et le besoin doivent être démontrés avant toute migration.
### 4.4 Retry et erreurs
Séparer :
```text
retry Transport déjà possédé par Transport
retry métier du job
provider rate limit / Retry-After
transaction null/indisponible
conflit Store
cancellation
échec terminal
```
Éviter les doubles boucles de retry Transport + Job qui amplifient involontairement les appels réseau.
### 4.5 Logging
Le job concret étant comportemental, utiliser `ksp-logging-lib` si logging runtime nécessaire et respecter les conventions KSP de `TRACING_TARGET` / `constants.rs`.
Ne jamais logguer :
```text
URL/secret provider
payload transaction complet
credentials
SQL
bytes sensibles inutiles
```
Les signatures peuvent apparaître uniquement si les règles de logging KSP et le besoin opérationnel l'autorisent explicitement ; ne pas les rendre automatiquement via `Debug`.
## 5. Livrables obligatoires de `pre.001`
Créer :
```text
docs/plans/027-V0_3_6_JOB_API_RAW_BACKFILL_PLAN.md
docs/validation/023-V0_3_6_JOB_API_RAW_BACKFILL.md
deltas/0.3.6/pre.001.md
```
Le plan doit contenir au minimum :
```text
inventaire des contrats existants
matrice ownership API Job / job concret / Transport / Store
choix ou rejet du backfill RawTransaction par adresse
modèle de pagination/checkpoint/reprise
modèle cancellation/progression/outcome
risques de double retry et de gaps historiques
choix de crate(s) minimal
forecast des prereleases
critères de clôture
```
`pre.001` peut faire évoluer `Cargo.toml` vers `0.3.6-pre.1`, mais ne doit pas créer de code fonctionnel lourd simplement pour remplir la tranche.
## 6. Direction préférée pour le premier backfill
Si l'audit confirme le candidat, viser une verticale minimale :
```text
adresse explicite
+ réseau explicite via Store/Transport configurés
+ commitment explicite
+ plage/bornes explicites si supportables sans fausse précision
+ pagination getSignaturesForAddress
+ hydratation getTransaction
+ conversion RAW
+ write via ksp-store-lib
+ progression observable
+ cancellation propre
+ checkpoint/reprise déterministes
```
Le premier job n'a pas à devenir un crawler global multi-address/provider ou un scheduler de production.
## 7. Tests attendus à terme
Prévoir selon l'implémentation :
```text
unit tests Job API
public API canaries
external implementation/consumer
pagination newest -> oldest
checkpoint contigu / reprise
cancellation avant/pendant fetch et avant/pendant persistence
idempotence Store
conflit Store terminal et sûr
null getTransaction
rate-limit / retry ownership
no secret/payload debug leak
manifest/dependency firewall
```
Un smoke Devnet opt-in peut être ajouté seulement s'il apporte une preuve que les fixtures ne peuvent pas apporter. Aucun test live payant n'est requis.
## 8. Hors périmètre `0.3.6`
```text
application desktop de backfill/inspection (0.3.7)
worker RAW live continu
scheduler global
queue distribuée
cron engine
STRUCTURAL/DECODED/DOMAIN
Program decoding
materialization
nouveau backend Store
nouvelle persistence RawAccountState
réouverture des migrations RAW PostgreSQL sans nécessité démontrée
event bus Interface
persistence Job ajoutée par réflexe
support provider-specific payant requis pour fermer la release
```
## 9. Archive historique kbot3
L'archive kbot3 **n'est pas requise** pour démarrer ou fermer `0.3.6`.
La source de vérité est :
```text
base KSP stable v0.3.5
règles/architecture KSP actuelles
surfaces Transport/Store réelles
contrats RPC officiels actuels
```
Si une comparaison avec un ancien mécanisme de backfill kbot3 devient utile pendant le brainstorming, elle peut être fournie comme référence historique uniquement ; elle ne doit pas être copiée comme architecture normative.
## 10. Cadence provisoire
Ne pas figer le nombre exact de prereleases avant le sizing de `pre.001`. Une trajectoire raisonnable à confirmer est :
```text
pre.001 audit + brainstorming + sizing + plan
pre.002 ksp-job-api minimal
pre.003 première verticale backfill RawTransaction
pre.004 checkpoint/reprise/cancellation + canaris externes
pre.005 hardening + intégration Store/Transport
pre.006 gate technique final
pre.007 réconciliation documentaire
pre.008 préparation de publication
rel.001 stable
```
La release doit rester dimensionnée pour **une session maximum**. Si le premier job réel exige nettement plus, réduire le scope plutôt que d'introduire une architecture partielle non fermable.
## 11. Gate opérateur de base
Après les tranches Rust significatives :
```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.6
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-job-api
```
Ajouter les tests ciblés des crates concrètement modifiées. Le gate technique final doit inclure `cargo test --workspace` et les graphes Cargo pertinents.
## 12. Règle de décision
Si le brainstorming de `pre.001` montre que `getSignaturesForAddress + getTransaction` ne permet pas un premier backfill suffisamment exact, reprenable et testable sans élargissement excessif, **ne pas forcer cette verticale**. Documenter le blocage, choisir le plus petit backfill RAW réellement démontrable, et préserver les frontières Job / Transport / Store.