v0.3.11-pre.001
This commit is contained in:
@@ -0,0 +1,765 @@
|
||||
<!-- file: docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Plan v0.3.11 — fondation runtime du Worker RawTransaction ingest
|
||||
|
||||
## 1. But de la version
|
||||
|
||||
`0.3.11` introduit `ksp-worker-raw-transaction-ingest-lib` comme premier Worker concret KSP, mais ferme uniquement sa fondation runtime source-neutral et déterministe.
|
||||
|
||||
La release doit prouver :
|
||||
|
||||
```text
|
||||
crate + dependency firewall
|
||||
settings techniques bornés
|
||||
identité Worker concrète
|
||||
start/stop et terminal
|
||||
supervisor et tâches privés
|
||||
admission bornée
|
||||
canonicalisation via ksp-raw-transaction-lib
|
||||
persistence via ksp-store-lib
|
||||
idempotence/conflit déterministes
|
||||
snapshots latest-value concrets
|
||||
projection vers ksp-worker-api
|
||||
shutdown/fault/backpressure bornés
|
||||
```
|
||||
|
||||
Aucune source Yellowstone, WS, Helius ou HTTP live n'est nécessaire pour fermer `0.3.11`. Les sources réelles commencent en `0.3.12`.
|
||||
|
||||
## 2. Base autoritaire auditée en `pre.001`
|
||||
|
||||
Base opérateur :
|
||||
|
||||
```text
|
||||
archive : khadhroony-solana-project-v0.3.10.zip
|
||||
SHA-256 : befafea61304aaea15c94db7c8b3525c58b7c1622bf880a9110373bcc0ae6ac0
|
||||
ZIP bytes : 7993096
|
||||
ZIP entries : 1901
|
||||
unzip -t : PASS
|
||||
workspace.package.version : 0.3.10
|
||||
workspace members : 20
|
||||
deltas/0.3.10/rel.001.md : présent
|
||||
ksp-raw-transaction-lib : présent
|
||||
ksp-worker-api : présent
|
||||
ksp-job-backfill-lib : présent et consommateur de ksp-raw-transaction-lib
|
||||
ksp-worker-raw-transaction-ingest-lib : absent
|
||||
```
|
||||
|
||||
Sécurité/forme du ZIP :
|
||||
|
||||
```text
|
||||
une seule racine : khadhroony-solana-project
|
||||
entrée absolue : 0
|
||||
path traversal : 0
|
||||
symlink : 0
|
||||
.git/ : 0
|
||||
target/ : 0
|
||||
node_modules/ : 0
|
||||
Cargo.lock : 0
|
||||
.env : 0
|
||||
```
|
||||
|
||||
La base satisfait donc les préconditions du prompt `030`.
|
||||
|
||||
## 3. Réconciliation normative obligatoire ouverte par l'audit
|
||||
|
||||
Deux divergences existent dans les règles actives de la stable `0.3.10`.
|
||||
|
||||
### 3.1 Vocabulaire D1–D4
|
||||
|
||||
`RULES_KSP.md` et `RULES_DEPENDENCIES.md` contenaient encore une ancienne formulation où D2 était nommé `Core canonique`, alors que les règles plus récentes et l'architecture `008` imposent :
|
||||
|
||||
```text
|
||||
D1 RAW
|
||||
D2 STRUCTURAL
|
||||
D3 DECODED
|
||||
D4 DOMAIN
|
||||
```
|
||||
|
||||
`pre.001` corrige uniquement les règles actives concernées. Les deltas/plans historiques restent des traces historiques et ne sont pas réécrits.
|
||||
|
||||
### 3.2 Nom du Worker RAW
|
||||
|
||||
Les règles `KSP-WORKER-005`, `006`, `007` et `010` utilisaient encore `ksp-worker-raw-retriever`. Le nom durable retenu par l'architecture, le ROADMAP, le CHANGELOG, le handoff `0.3.10` et le prompt `030` est :
|
||||
|
||||
```text
|
||||
ksp-worker-raw-transaction-ingest-lib
|
||||
```
|
||||
|
||||
`pre.001` normalise ces quatre règles sans modifier leur responsabilité fonctionnelle.
|
||||
|
||||
## 4. Frontières existantes à préserver
|
||||
|
||||
### 4.1 `ksp-worker-api`
|
||||
|
||||
Surface générique conservée sans modification :
|
||||
|
||||
```text
|
||||
WorkerId
|
||||
WorkerKindCode
|
||||
WorkerState
|
||||
WorkerHealth
|
||||
WorkerActivity
|
||||
WorkerLifecycle
|
||||
WorkerStopToken
|
||||
WorkerSnapshotSequence
|
||||
WorkerSnapshot
|
||||
WorkerSnapshotFuture
|
||||
WorkerSnapshotSource
|
||||
```
|
||||
|
||||
La crate reste runtime-neutral et dépend uniquement de `ksp-core-lib`. Aucun `start()`/`stop()` universel ni type Solana-specific n'y est ajouté pour `0.3.11`.
|
||||
|
||||
### 4.2 `ksp-raw-transaction-lib`
|
||||
|
||||
La common RAW reste propriétaire de :
|
||||
|
||||
```text
|
||||
RawTransactionMaterial
|
||||
canonicalize_raw_transaction
|
||||
parse/extract signature
|
||||
RAW v1 wire/canonical bytes/hash
|
||||
RawTransactionAcquisition
|
||||
assemble_raw_transaction_acquisition
|
||||
```
|
||||
|
||||
Elle ne reçoit aucun edge runtime/Worker/Job/Transport/Config/backend.
|
||||
|
||||
### 4.3 `ksp-store-lib`
|
||||
|
||||
Le Worker concret persiste via la façade `Store` et le contrat atomique :
|
||||
|
||||
```text
|
||||
RawTransactionWrite::persist_raw_transaction_acquisition
|
||||
```
|
||||
|
||||
Le Store reste l'autorité de convergence pour `(network, signature)` et retourne les outcomes entity/observation. Le Worker ne dépend pas de `ksp-store-postgres-lib` et n'ouvre/ferme pas le Store qui lui est fourni.
|
||||
|
||||
### 4.4 Backfill
|
||||
|
||||
Les patterns réutilisables conceptuellement sont :
|
||||
|
||||
```text
|
||||
port privé de persistence pour tests déterministes
|
||||
persistence atomique entity + observation
|
||||
mapping explicite du content conflict
|
||||
latest-value coalescent
|
||||
cancellation coopérative
|
||||
redaction des surfaces publiques
|
||||
```
|
||||
|
||||
Ne sont pas réutilisés :
|
||||
|
||||
```text
|
||||
BackfillRequest
|
||||
scope historique
|
||||
before/after
|
||||
checkpoint
|
||||
JobId
|
||||
campagne/limit historique
|
||||
```
|
||||
|
||||
## 5. Dépendances externes et graphe cible
|
||||
|
||||
Fraîcheur vérifiée le 8 septembre 2026 :
|
||||
|
||||
```text
|
||||
tokio latest stable : 1.53.1
|
||||
workspace KSP : ^1.53
|
||||
futures-util latest stable : 0.3.34
|
||||
workspace KSP : ^0.3
|
||||
sha2 latest stable : 0.11.0
|
||||
workspace KSP : ^0.11
|
||||
```
|
||||
|
||||
Aucun bump de contrainte workspace n'est requis.
|
||||
|
||||
Graphe de production prévu pour la fondation :
|
||||
|
||||
```text
|
||||
ksp-worker-raw-transaction-ingest-lib
|
||||
-> ksp-core-lib
|
||||
-> ksp-worker-api
|
||||
-> ksp-raw-transaction-lib
|
||||
-> ksp-store-lib default-features=false
|
||||
-> ksp-logging-lib
|
||||
-> sha2
|
||||
-> tokio
|
||||
```
|
||||
|
||||
Tokio est direct parce que la crate concrète possède ses tâches runtime. Features de production retenues lorsque le runtime est matérialisé :
|
||||
|
||||
```text
|
||||
macros
|
||||
rt
|
||||
sync
|
||||
time
|
||||
```
|
||||
|
||||
Raisons :
|
||||
|
||||
```text
|
||||
rt -> spawn / JoinHandle / JoinSet privés
|
||||
sync -> mpsc borné + watch latest-value
|
||||
macros -> select! avec ordre biaisé explicite pour stop/fault
|
||||
time -> deadline de drain bornée
|
||||
```
|
||||
|
||||
`rt-multi-thread` reste test-only si les tests en ont besoin ; le Worker ne crée aucun runtime.
|
||||
|
||||
`futures-util` n'est pas ajouté en fondation : `JoinSet`, `mpsc`, `watch`, les futures boxed standard et `select!` couvrent le modèle retenu. `ksp-onchain-transport-lib` n'est pas ajouté à `0.3.11` : aucune source live n'existe encore et un edge inutilisé violerait le principe de dépendance minimale. Il sera réaudité avec Yellowstone en `0.3.12`.
|
||||
|
||||
Edges interdits :
|
||||
|
||||
```text
|
||||
Worker -> ksp-config-lib
|
||||
Worker -> ksp-job-backfill-lib
|
||||
Worker -> ksp-job-api
|
||||
Worker -> ksp-store-api direct sans nécessité démontrée
|
||||
Worker -> ksp-store-postgres-lib
|
||||
Worker -> SDK provider
|
||||
common RAW -> Worker/runtime/Transport/Config
|
||||
```
|
||||
|
||||
## 6. Surface publique minimale retenue
|
||||
|
||||
### 6.1 Constante d'identité
|
||||
|
||||
```text
|
||||
RAW_TRANSACTION_INGEST_WORKER_KIND_CODE = "raw_transaction_ingest"
|
||||
```
|
||||
|
||||
La construction de `WorkerKindCode` reste validée par `ksp-worker-api`.
|
||||
|
||||
### 6.2 `RawTransactionIngestSettings`
|
||||
|
||||
La fondation expose seulement les réglages runtime techniques dont le Worker est propriétaire :
|
||||
|
||||
```text
|
||||
network: RawNetworkId
|
||||
worker_id: WorkerId
|
||||
admission_queue_capacity: usize
|
||||
persistence_concurrency: usize
|
||||
shutdown_drain_timeout: Duration
|
||||
```
|
||||
|
||||
Bornes V1 :
|
||||
|
||||
```text
|
||||
admission queue default : 256
|
||||
admission queue min : 1
|
||||
admission queue max : 65_536
|
||||
|
||||
persistence concurrency default : 8
|
||||
persistence concurrency min : 1
|
||||
persistence concurrency max : 64
|
||||
|
||||
shutdown drain default : 5 s
|
||||
shutdown drain min : 100 ms
|
||||
shutdown drain max : 30 s
|
||||
```
|
||||
|
||||
Ces bornes reprennent des enveloppes déjà utilisées dans KSP : queue live conservatrice à 256, plafond de channel Transport à 65 536, concurrence Store usuelle 8 et plafond 64, timeout de shutdown Store 5 s avec enveloppe 100 ms–30 s.
|
||||
|
||||
Aucun champ métier historique ni provider-specific n'entre dans cette structure.
|
||||
|
||||
### 6.3 Types différés
|
||||
|
||||
Ne sont pas figés publiquement en `0.3.11` :
|
||||
|
||||
```text
|
||||
RawTransactionSourceId
|
||||
RawTransactionSourceSettings
|
||||
RawTransactionSourceCapability
|
||||
RawTransactionSourceRole
|
||||
RawTransactionContinuityState
|
||||
source frontier/run frontier
|
||||
provider enum
|
||||
Yellowstone/WS/Helius fields
|
||||
retry/replay/gap-repair settings
|
||||
```
|
||||
|
||||
Le harness déterministe utilise des types privés. Les types source publics seront ouverts lorsque `0.3.12` disposera d'une première source réelle permettant de prouver leur contrat.
|
||||
|
||||
## 7. Forme du start, ownership et handle
|
||||
|
||||
### 7.1 Start
|
||||
|
||||
Forme cible :
|
||||
|
||||
```text
|
||||
RawTransactionIngestWorker::start(
|
||||
settings: RawTransactionIngestSettings,
|
||||
store: Arc<ksp_store_lib::Store>,
|
||||
) -> Result<RawTransactionIngestHandle>
|
||||
```
|
||||
|
||||
`start` est synchrone et exige un runtime Tokio actif fourni par le caller. Il vérifie avant spawn :
|
||||
|
||||
```text
|
||||
settings valides
|
||||
runtime Tokio courant disponible
|
||||
network settings == network Store
|
||||
état initial cohérent
|
||||
```
|
||||
|
||||
Le Worker ne ferme jamais le Store ; le caller conserve son lifecycle. `Arc<Store>` permet aux tâches privées de partager la même façade sans exposer un backend.
|
||||
|
||||
### 7.2 Handle
|
||||
|
||||
Surface minimale :
|
||||
|
||||
```text
|
||||
request_stop() -> bool
|
||||
snapshot_source()
|
||||
worker_snapshot_source()
|
||||
wait_terminal()
|
||||
```
|
||||
|
||||
`request_stop()` est idempotent et retourne `true` seulement pour le premier appel effectif.
|
||||
|
||||
`wait_terminal()` retourne une future runtime-neutral boxed appartenant à la crate concrète ; aucun `tokio::task::JoinHandle` n'apparaît dans l'API publique.
|
||||
|
||||
## 8. Supervisor, tâches et channels
|
||||
|
||||
### 8.1 Ownership privé
|
||||
|
||||
Le modèle retenu est :
|
||||
|
||||
```text
|
||||
start
|
||||
-> crée stop token + signal stop privé
|
||||
-> crée watch snapshot
|
||||
-> crée mpsc admission borné
|
||||
-> spawn supervisor privé
|
||||
-> garde l'ownership des source tasks présentes/futures
|
||||
-> garde l'ownership des persistence tasks
|
||||
-> ferme et joint toutes les tâches avant terminal
|
||||
```
|
||||
|
||||
Les `JoinHandle`/`JoinSet` restent strictement privés. Dropper le handle public ne détache pas le supervisor ; l'ownership interne du run reste suffisant pour atteindre un terminal ou répondre à stop par les clones encore présents.
|
||||
|
||||
### 8.2 Admission
|
||||
|
||||
Un seul channel central :
|
||||
|
||||
```text
|
||||
tokio::sync::mpsc::channel<PrivateRawTransactionIngress>(admission_queue_capacity)
|
||||
```
|
||||
|
||||
Le channel est borné. `send().await` applique le backpressure ; aucun `unbounded_channel`, aucun drop silencieux et aucune event queue publique ne sont admis.
|
||||
|
||||
Les futures sources posséderont des clones du sender. En `0.3.11`, seuls les tests/harness privés injectent des entrées.
|
||||
|
||||
### 8.3 Stop signal
|
||||
|
||||
`WorkerStopToken` porte l'intention commune. Un `watch<bool>` privé réveille immédiatement le supervisor/source harness sans polling. Le stop branch est placé en premier dans les `select!` biaisés afin qu'aucune nouvelle admission ne soit acceptée après observation du stop.
|
||||
|
||||
### 8.4 Snapshot
|
||||
|
||||
Un `watch<RawTransactionIngestSnapshot>` privé conserve uniquement la dernière valeur. La projection commune `WorkerSnapshotSource` et la source concrète lisent ce même état ; aucune seconde event queue n'est nécessaire.
|
||||
|
||||
## 9. Seam/harness déterministe sans réseau
|
||||
|
||||
Le runtime de fondation est prouvé par un harness privé qui produit des `PrivateRawTransactionIngress` contrôlés.
|
||||
|
||||
Une entrée de harness contient conceptuellement :
|
||||
|
||||
```text
|
||||
RawTransactionMaterial
|
||||
RawObservationKey déterministe Worker-owned
|
||||
RawAcquisitionProvenance sûre
|
||||
```
|
||||
|
||||
Le harness permet :
|
||||
|
||||
```text
|
||||
N acquisitions séquentielles
|
||||
acquisitions concurrentes
|
||||
même transaction/même observation
|
||||
même transaction/nouvelle observation
|
||||
contenu canonique divergent
|
||||
source qui fault
|
||||
source qui reste bloquée
|
||||
stop pendant admission
|
||||
stop pendant persistence
|
||||
saturation d'admission
|
||||
lecteur snapshot lent ou absent
|
||||
```
|
||||
|
||||
Le seam n'est pas public et ne constitue pas une API d'injection de données pour les applications. `0.3.12` branchera une source productive sur le même sender privé.
|
||||
|
||||
## 10. Canonicalisation, observation key et persistence
|
||||
|
||||
### 10.1 Pipeline central
|
||||
|
||||
```text
|
||||
private ingress
|
||||
-> vérifier network
|
||||
-> canonicalize_raw_transaction(material)
|
||||
-> assemble_raw_transaction_acquisition(...)
|
||||
-> persist_raw_transaction_acquisition(..., Normal)
|
||||
-> classifier outcome
|
||||
-> publier counters/snapshot
|
||||
```
|
||||
|
||||
Aucune canonicalisation RAW v1 n'est recodée dans le Worker.
|
||||
|
||||
### 10.2 Observation key Worker
|
||||
|
||||
La Worker observation key est un SHA-256 KSP-owned versionné et domain-separated. La fondation réserve le domaine :
|
||||
|
||||
```text
|
||||
ksp.raw_transaction_ingest.observation.v1
|
||||
```
|
||||
|
||||
Les bytes exacts/golden seront figés avec le premier code de persistence, à partir d'éléments stables fournis par la source technique et de l'identité `(network, signature)`. Aucun timestamp local aléatoire ni run id ne peut rendre une rediffusion identique non idempotente.
|
||||
|
||||
Les éléments source exacts ne sont pas figés publiquement avant `0.3.12`; le harness utilise une source key privée déterministe afin de prouver l'idempotence du domaine Worker.
|
||||
|
||||
### 10.3 Outcomes
|
||||
|
||||
Le Worker distingue au minimum :
|
||||
|
||||
```text
|
||||
entity Inserted
|
||||
entity AlreadyPresent
|
||||
entity SkippedPurged
|
||||
observation Inserted
|
||||
observation AlreadyPresent
|
||||
observation NotRecorded
|
||||
content conflict
|
||||
Store error
|
||||
```
|
||||
|
||||
`Rehydrated` n'est pas produit en mode `Normal`; s'il apparaît malgré le contrat, le Worker le traite comme invariant runtime invalide plutôt que comme succès silencieux.
|
||||
|
||||
Le Store reste la source de vérité ; aucun cache de déduplication mémoire n'est requis en `0.3.11`.
|
||||
|
||||
## 11. Snapshots et projection Worker API
|
||||
|
||||
### 11.1 Snapshot concret
|
||||
|
||||
`RawTransactionIngestSnapshot` contient uniquement des données sûres :
|
||||
|
||||
```text
|
||||
WorkerSnapshot commun ou champs de projection équivalents
|
||||
admission_queue_capacity
|
||||
admission_queue_depth
|
||||
persistence_concurrency
|
||||
in_flight_persistence
|
||||
admitted_total
|
||||
canonicalized_total
|
||||
persisted_total
|
||||
entity_inserted_total
|
||||
entity_already_present_total
|
||||
entity_skipped_purged_total
|
||||
observation_inserted_total
|
||||
observation_already_present_total
|
||||
content_conflict_total
|
||||
store_failure_total
|
||||
source_failure_total
|
||||
backpressure_wait_total
|
||||
```
|
||||
|
||||
Compteurs : `u64` monotones avec incrément checked. L'épuisement est un fault statique, jamais un wrap silencieux.
|
||||
|
||||
Aucun timestamp/frontier public n'est nécessaire en fondation. `received_at` appartient à la provenance de l'entrée source ; le run frontier et la continuité sont différés jusqu'à la première source réelle.
|
||||
|
||||
### 11.2 Projection commune
|
||||
|
||||
La même séquence `WorkerSnapshotSequence` pilote le snapshot concret et la projection commune. Mapping :
|
||||
|
||||
```text
|
||||
Created/Starting -> health Unknown
|
||||
Running -> health Healthy tant qu'aucun fault n'est décidé
|
||||
Stopping -> conserve le dernier health non terminal
|
||||
Faulted -> health Unhealthy
|
||||
|
||||
queue ou persistence > 0 -> activity Active
|
||||
sinon Running/Stopping -> activity Idle
|
||||
```
|
||||
|
||||
La state machine reste celle de `WorkerLifecycle`.
|
||||
|
||||
## 12. Fault, shutdown et backpressure
|
||||
|
||||
### 12.1 Error codes publics prévus
|
||||
|
||||
```text
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_SETTINGS_INVALID
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_RUNTIME_INVALID
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_SOURCE_FAILED
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_STORE_FAILED
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_CONTENT_CONFLICT
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_DRAIN_TIMEOUT
|
||||
ERROR_CODE_RAW_TRANSACTION_INGEST_COUNTER_EXHAUSTED
|
||||
```
|
||||
|
||||
Domain ErrorCode :
|
||||
|
||||
```text
|
||||
worker_raw_transaction_ingest
|
||||
```
|
||||
|
||||
Les messages/contextes restent statiques et sûrs ; aucune signature, hash de conflit, payload, URL, token ou erreur distante arbitraire n'est copiée.
|
||||
|
||||
### 12.2 Content conflict
|
||||
|
||||
Policy :
|
||||
|
||||
```text
|
||||
fermer l'admission
|
||||
request stop interne
|
||||
ne pas overwrite
|
||||
ne pas choisir de source gagnante
|
||||
continuer seulement le drain déjà admis tant que sûr
|
||||
publier Faulted(content_conflict)
|
||||
```
|
||||
|
||||
Le premier terminal décidé reste terminal ; une demande de stop tardive ne remplace pas le fault.
|
||||
|
||||
### 12.3 Store error
|
||||
|
||||
Une erreur Store non-conflict pendant une acquisition admise devient `Faulted(store_failed)`. Le code Store original peut être tracé uniquement s'il est déjà un `ErrorCode` sûr ; le texte d'erreur arbitraire n'est jamais propagé dans snapshot/Debug.
|
||||
|
||||
### 12.4 Source harness failure
|
||||
|
||||
Une panne de source privée devient `Faulted(source_failed)` en `0.3.11`. Les futures politiques required/optional/degraded sont reportées à la release qui possède de vraies sources.
|
||||
|
||||
### 12.5 Drain
|
||||
|
||||
Après stop/fault :
|
||||
|
||||
```text
|
||||
fermer nouvelles admissions
|
||||
signaler les tâches source
|
||||
fermer les senders Worker-owned
|
||||
continuer les acquisitions déjà reçues/admisses
|
||||
attendre les persistence tasks jusqu'à shutdown_drain_timeout
|
||||
si deadline dépassée -> abort privé des tâches restantes, join, Faulted(drain_timeout)
|
||||
publier terminal seulement après absence de tâche privée survivante
|
||||
```
|
||||
|
||||
Le timeout Tokio nécessite un runtime caller avec time driver actif ; cette précondition est documentée et testée dans les harness runtime de la crate.
|
||||
|
||||
## 13. Menaces et gardes de fondation
|
||||
|
||||
```text
|
||||
payload hostile/oversized
|
||||
-> common RAW/Store bounds ; aucun payload dans snapshot/log
|
||||
|
||||
duplicate storm
|
||||
-> bounded mpsc + bounded persistence concurrency + Store idempotence
|
||||
|
||||
queue saturation
|
||||
-> send await/backpressure observable ; aucun drop silencieux
|
||||
|
||||
Store lent
|
||||
-> queue/concurrency bornées ; stop drain deadline
|
||||
|
||||
content conflict
|
||||
-> fault terminal ; aucune overwrite/first-provider-wins
|
||||
|
||||
Store failure
|
||||
-> fault statique ; aucune retry queue infinie en fondation
|
||||
|
||||
source task failure
|
||||
-> détectée/joined ; fault sûr
|
||||
|
||||
task orphan
|
||||
-> ownership supervisor/JoinSet ; terminal après join/abort complet
|
||||
|
||||
stop/fault race
|
||||
-> première décision terminale cohérente ; fault d'intégrité prioritaire
|
||||
|
||||
slow/no snapshot reader
|
||||
-> watch latest-value ; aucun impact lifecycle
|
||||
|
||||
secret/URL/signature leak
|
||||
-> aucun champ public correspondant ; Debug redacted ; tests statiques
|
||||
|
||||
Job semantics leak
|
||||
-> dependency/public-surface tests interdisant request/scope/checkpoint/JobId
|
||||
|
||||
Config leak
|
||||
-> manifest/source scans ; aucun std::env/.env/ksp-config-lib
|
||||
```
|
||||
|
||||
## 14. Preuves et suites de tests prévues
|
||||
|
||||
Tests unitaires :
|
||||
|
||||
```text
|
||||
settings defaults/bounds/invalid
|
||||
kind/identity
|
||||
checked counters
|
||||
snapshot mapping
|
||||
observation-key golden privé
|
||||
outcome mapping
|
||||
fault precedence
|
||||
```
|
||||
|
||||
Tests runtime déterministes :
|
||||
|
||||
```text
|
||||
start sur runtime valide
|
||||
start sans runtime -> erreur sûre
|
||||
network Store mismatch -> erreur avant spawn
|
||||
stop idempotent
|
||||
terminal normal
|
||||
no orphan task after terminal
|
||||
bounded admission saturation/backpressure
|
||||
bounded persistence concurrency
|
||||
same entity/same observation idempotent
|
||||
same entity/new observation conservée
|
||||
content conflict terminal
|
||||
Store failure terminal
|
||||
source harness failure terminal
|
||||
stop pendant queue/persistence
|
||||
drain timeout -> abort/join -> terminal fault
|
||||
slow/no listeners
|
||||
common/concrete snapshot latest-value
|
||||
```
|
||||
|
||||
Tests externes :
|
||||
|
||||
```text
|
||||
dependency boundary
|
||||
public API crate-root
|
||||
release completeness
|
||||
security hardening/redaction
|
||||
source visibility crate::Item
|
||||
forbidden historical request surface
|
||||
manifest exactness
|
||||
```
|
||||
|
||||
Aucun test provider live n'est requis en `0.3.11`.
|
||||
|
||||
## 15. Gates techniques cibles
|
||||
|
||||
À partir de la création de la crate :
|
||||
|
||||
```bash
|
||||
cargo fmt --all -- --check
|
||||
python3 scripts/audit_rust_workspace_rules.py
|
||||
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib
|
||||
cargo test -p ksp-worker-api
|
||||
cargo test -p ksp-raw-transaction-lib
|
||||
cargo test -p ksp-store-lib
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib --edges normal
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features
|
||||
cargo tree --duplicates
|
||||
```
|
||||
|
||||
Gate technique final :
|
||||
|
||||
```bash
|
||||
cargo test --workspace --all-targets --all-features
|
||||
```
|
||||
|
||||
Une commande non exécutée n'est jamais déclarée PASS.
|
||||
|
||||
## 16. Hors périmètre et questions reportées
|
||||
|
||||
Reportés explicitement :
|
||||
|
||||
```text
|
||||
Yellowstone live
|
||||
WS standard live
|
||||
Helius live
|
||||
HTTP block polling live
|
||||
Transport dependency productive
|
||||
source capability/role publics
|
||||
source required/optional policy
|
||||
retry/reconnect policy provider
|
||||
run frontier
|
||||
continuity/gap repair
|
||||
hydration productive
|
||||
multi-source convergence live
|
||||
hot reconfiguration desired/effective
|
||||
Desk d'ingestion
|
||||
Backfill multi-source
|
||||
D2 STRUCTURAL
|
||||
migration Store
|
||||
```
|
||||
|
||||
Ces éléments ne bloquent pas le gate de fondation.
|
||||
|
||||
## 17. Prévision souple recalibrée
|
||||
|
||||
### `pre.001` — audit, règles, brainstorming, sizing, plan
|
||||
|
||||
Budget cible : **10–15 min**. Vérifier la stable, corriger les deux divergences normatives actives, fermer le modèle runtime/dependencies/public-private/harness et créer plan + validation. Aucun Rust Worker.
|
||||
|
||||
### `pre.002` — crate skeleton + dependency firewall
|
||||
|
||||
Budget cible : **10–15 min**. Créer la crate minimale, l'ajouter au workspace, installer uniquement les edges décidés et les tests de manifest/dependency boundary. Pas de runtime comportemental.
|
||||
|
||||
### `pre.003` — identity + settings foundation
|
||||
|
||||
Budget cible : **10–15 min**. Kind code, settings, defaults/bounds, validation network/worker identity et erreurs correspondantes. Aucun spawn.
|
||||
|
||||
### `pre.004` — start/handle/lifecycle/terminal
|
||||
|
||||
Budget cible : **15–20 min**. Start sur runtime caller-owned, handle public, stop idempotent, lifecycle générique, terminal future sans JoinHandle public. Harness runtime minimal.
|
||||
|
||||
### `pre.005` — supervisor privé + ownership des tâches
|
||||
|
||||
Budget cible : **15–20 min**. Supervisor, JoinSet/joins privés, stop wake-up, test source seam et preuve qu'aucune tâche ne survit au terminal. Pas encore de persistence réelle.
|
||||
|
||||
### `pre.006` — admission bornée + canonicalisation common
|
||||
|
||||
Budget cible : **15–20 min**. `mpsc` borné, backpressure, ingress privé, common `RawTransactionMaterial -> RawTransaction`, observation-key domain/golden et assembly. Pas de source réseau.
|
||||
|
||||
### `pre.007` — persistence Store + idempotence/conflict
|
||||
|
||||
Budget cible : **15–20 min**. Port privé Store, mode Normal, concurrency bornée, outcomes new/idempotent/purged, observation distincte, Store error et content conflict terminal.
|
||||
|
||||
### `pre.008` — snapshots concrets + projection Worker API
|
||||
|
||||
Budget cible : **15–20 min**. `watch` latest-value, compteurs checked, common projection, slow/no listener et terminal retained.
|
||||
|
||||
### `pre.009` — hardening shutdown/backpressure/fault races
|
||||
|
||||
Budget cible : **15–20 min**. Drain deadline, stop/fault ordering, saturation, source failure, Store slow/failure, abort+join au timeout, no orphan tasks. Scinder immédiatement si le gate réel dépasse le budget.
|
||||
|
||||
### `pre.010` — hardening public/release/security
|
||||
|
||||
Budget cible : **10–15 min**. Tests externes exacts : API root, dependencies, historical-surface absence, redaction, error codes, module inventory et scans Config/secret/backend.
|
||||
|
||||
### `pre.011` — gate technique final
|
||||
|
||||
Budget cible : **10–15 min**. Workspace tests/all-features, Clippy strict, suites ciblées, arbres normal/features, duplicate tree. Aucun nouveau scope fonctionnel.
|
||||
|
||||
### `pre.012` — réconciliation documentaire
|
||||
|
||||
Budget cible : **10–15 min**. README/USAGE Worker, plan, validation et architecture/références réellement affectées. Aucun CHANGELOG/ROADMAP/prompt suivant.
|
||||
|
||||
### `pre.013` — préparation publication
|
||||
|
||||
Budget cible : **5–10 min**. Prompt `0.3.12`, CHANGELOG, ROADMAP, Cargo/delta mécaniques uniquement.
|
||||
|
||||
### `rel.001` — stable
|
||||
|
||||
Publication mécanique sans rattrapage.
|
||||
|
||||
## 18. Décision de sizing `pre.001`
|
||||
|
||||
Décision : **maintenir `0.3.11`**.
|
||||
|
||||
Le périmètre reste clôturable dans une seule session à condition de préserver strictement :
|
||||
|
||||
```text
|
||||
aucune source live
|
||||
aucun edge Transport productif
|
||||
aucune modification Config
|
||||
aucune migration Store
|
||||
aucun gap repair/continuity live
|
||||
aucune API source provider prématurée
|
||||
```
|
||||
|
||||
Le découpage initial `pre.002`–`pre.007` du prompt a été volontairement affiné afin que chaque tranche ne mélange pas plusieurs responsabilités runtime. Si `pre.007` ou `pre.009` révèle un volume supérieur au budget, la tranche est scindée avant exécution ; si cette scission révèle qu'un sous-système live est nécessaire, la release est rescindée avant d'introduire ce nouveau scope.
|
||||
Reference in New Issue
Block a user