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.
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_DEPENDENCIES.md -->
|
||||
<!-- version: 18 -->
|
||||
<!-- version: 19 -->
|
||||
|
||||
# Règles des dépendances KSP
|
||||
|
||||
@@ -81,7 +81,7 @@ Elles complètent les règles Rust générales et le graphe de `docs/architectur
|
||||
- **DEP-STORE-001** — `ksp-store-api` ne dépend pas de Program, Materializer ou Transport.
|
||||
- **DEP-STORE-002** — `ksp-store-lib` dépend de `ksp-store-api`, porte la façade/runtime Store commune et peut dépendre optionnellement de crates backend compilées par feature ; il ne dépend pas des implémentations Program/Materializer/Transport.
|
||||
- **DEP-STORE-003** — Les workers/jobs spécialisés sont propriétaires des conversions entre modèles runtime et DTO persistants.
|
||||
- **DEP-STORE-004** — Les niveaux durables sont D1 Raw, D2 Core canonique, D3 journal de matérialisation générique et D4 projections spécialisées.
|
||||
- **DEP-STORE-004** — Les niveaux durables canoniques sont D1 `RAW`, D2 `STRUCTURAL`, D3 `DECODED` et D4 `DOMAIN` ; le journal générique de matérialisation décodée appartient à D3 et les projections/faits de domaine queryables à D4.
|
||||
- **DEP-STORE-005** — Les replays D1 -> D2, D2 -> D3 et D3 -> D4 doivent pouvoir être exécutés indépendamment.
|
||||
- **DEP-STORE-006** — Une notification de donnée persistée ne constitue jamais la source de vérité du backlog ; les queries Store et marqueurs durables d'idempotence/version de processor font autorité.
|
||||
- **DEP-STORE-007** — Une notification de donnée est publiée seulement après persistence/commit réussis.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_KSP.md -->
|
||||
<!-- version: 40 -->
|
||||
<!-- version: 41 -->
|
||||
|
||||
# Règles spécifiques à KSP
|
||||
|
||||
@@ -97,11 +97,11 @@
|
||||
## Niveaux durables et Store
|
||||
|
||||
- **KSP-DURABLE-001** — Les niveaux persistants utilisent la nomenclature D1 à D4, distincte des couches architecturales N1 à N4.
|
||||
- **KSP-DURABLE-002** — D1 est Raw, D2 Core canonique, D3 le journal générique de matérialisation et D4 les projections spécialisées/queryables.
|
||||
- **KSP-DURABLE-002** — Les niveaux durables canoniques sont D1 `RAW`, D2 `STRUCTURAL`, D3 `DECODED` et D4 `DOMAIN`. D3 conserve la matérialisation générique décodée/journal durable requis ; D4 porte les faits et projections de domaine queryables lorsque leur normalisation est pertinente.
|
||||
- **KSP-DURABLE-003** — D1/D2/D3 sont destinés à devenir fortement stables après stabilisation de la première série Store ; D4 reste plus évolutif.
|
||||
- **KSP-DURABLE-004** — Le journal D3 est durable et obligatoire ; il ne peut pas être supprimé au profit de projections D4 directes.
|
||||
- **KSP-DURABLE-005** — Les replays D1 -> D2, D2 -> D3 et D3 -> D4 sont indépendants.
|
||||
- **KSP-DURABLE-006** — Les instructions top-level et CPI restent des faits Core distincts lorsque leurs invariants/requêtes diffèrent.
|
||||
- **KSP-DURABLE-006** — Les instructions top-level et CPI restent des faits STRUCTURAL distincts lorsque leurs invariants/requêtes diffèrent.
|
||||
- **KSP-DURABLE-007** — D4 modélise des faits canoniques plutôt que des familles de tables par protocole lorsque les invariants sont normalisables.
|
||||
- **KSP-DURABLE-008** — Les temporalités blockchain et locales restent distinctes ; un `block_time` absent n'est jamais remplacé par une date locale inventée.
|
||||
|
||||
@@ -138,12 +138,12 @@
|
||||
- **KSP-WORKER-002** — Les contrats communs des workers appartiennent à `ksp-worker-api` et ne contiennent aucun contrat propre aux jobs.
|
||||
- **KSP-WORKER-003** — `ksp-worker-api` est principalement une lifecycle API de services continus : identité, état, health, démarrage/arrêt et événements communs ; les capacités optionnelles ne deviennent universelles que si plusieurs workers les partagent réellement.
|
||||
- **KSP-WORKER-004** — `ksp-worker-control-lib` est une implémentation commune de gouvernance/contrôle réutilisable d'abord par les apps manager spécialisées, puis éventuellement par un futur orchestrateur/application globale ; les apps ne réimplémentent pas cette gouvernance.
|
||||
- **KSP-WORKER-005** — `ksp-worker-raw-retriever` est le worker d'acquisition raw live/quasi-live. Il ne décode pas, ne matérialise pas et ne réalise pas de replay/backfill historique.
|
||||
- **KSP-WORKER-006** — `ksp-worker-raw-retriever` persiste les données raw puis notifie leur disponibilité selon les contrats de données normalisés.
|
||||
- **KSP-WORKER-007** — `ksp-worker-raw-retriever` doit pouvoir faire évoluer à chaud les listeners et la sélection des données qu'il rapatrie/stocke.
|
||||
- **KSP-WORKER-005** — `ksp-worker-raw-transaction-ingest-lib` est le worker d'acquisition raw live/quasi-live. Il ne décode pas, ne matérialise pas et ne réalise pas de replay/backfill historique.
|
||||
- **KSP-WORKER-006** — `ksp-worker-raw-transaction-ingest-lib` persiste les données raw puis notifie leur disponibilité selon les contrats de données normalisés.
|
||||
- **KSP-WORKER-007** — `ksp-worker-raw-transaction-ingest-lib` doit pouvoir faire évoluer à chaud les listeners et la sélection des données qu'il rapatrie/stocke.
|
||||
- **KSP-WORKER-008** — Les workers de processing ne sont pas figés à l'avance sous une chaîne globale `structural -> generic materializer -> domain projector`. RAW et STRUCTURAL peuvent disposer de workers horizontaux propres à leur couche ; à partir de DECODED, les workers/processors sont introduits au besoin avec chaque groupe fonctionnel vertical afin que décodage, matérialisation, projection spécialisée et validation d'exécution évoluent ensemble.
|
||||
- **KSP-WORKER-009** — Les workers de processing utilisent notification comme wake-up mais reconstruisent leur backlog depuis le Store.
|
||||
- **KSP-WORKER-010** — `ksp-worker-raw-retriever` distingue une configuration desired et une configuration effective lors des reconfigurations à chaud.
|
||||
- **KSP-WORKER-010** — `ksp-worker-raw-transaction-ingest-lib` distingue une configuration desired et une configuration effective lors des reconfigurations à chaud.
|
||||
- **KSP-WORKER-011** — Un cursor de scan est une optimisation ; les processing outcomes durables constituent la preuve qu'un input a été traité pour un processor/version/capability.
|
||||
- **KSP-WORKER-012** — La concurrence de processing utilise une sémantique de claim/lease récupérable après expiration/crash.
|
||||
- **KSP-WORKER-013** — Chaque worker doit pouvoir fonctionner comme service/processus indépendant afin d'être arrêté/redémarré/mis à jour sans imposer l'arrêt volontaire des autres workers.
|
||||
|
||||
@@ -0,0 +1,444 @@
|
||||
<!-- file: docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Validation v0.3.11 — fondation runtime du Worker RawTransaction ingest
|
||||
|
||||
## 1. Rôle du document
|
||||
|
||||
Ce document suit les preuves de `0.3.11` pour `ksp-worker-raw-transaction-ingest-lib`.
|
||||
|
||||
Il distingue explicitement :
|
||||
|
||||
```text
|
||||
preuve exécutée dans l'environnement d'assemblage
|
||||
preuve opérateur fournie sur la stable de base
|
||||
preuve planifiée pour une tranche future
|
||||
preuve non applicable au scope 0.3.11
|
||||
```
|
||||
|
||||
Aucune commande Cargo non exécutée localement n'est déclarée PASS.
|
||||
|
||||
## 2. Gate `pre.001` — audit/sizing/plan
|
||||
|
||||
État : **fermé pour la planification**. Le gate statique/Markdown final du delta complet est PASS dans l’environnement d’assemblage ; les gates Cargo restent non exécutables localement.
|
||||
|
||||
### 2.1 Archive stable contrôlée
|
||||
|
||||
```text
|
||||
archive : khadhroony-solana-project-v0.3.10.zip
|
||||
SHA-256 : befafea61304aaea15c94db7c8b3525c58b7c1622bf880a9110373bcc0ae6ac0
|
||||
bytes : 7993096
|
||||
entries : 1901
|
||||
unzip -t : PASS
|
||||
racine unique : khadhroony-solana-project
|
||||
workspace.package.version : 0.3.10
|
||||
workspace members : 20
|
||||
stable delta : deltas/0.3.10/rel.001.md
|
||||
```
|
||||
|
||||
Sécurité/forme :
|
||||
|
||||
```text
|
||||
absolute entries : 0
|
||||
path traversal entries : 0
|
||||
symlinks : 0
|
||||
.git/ : 0
|
||||
target/ : 0
|
||||
node_modules/ : 0
|
||||
Cargo.lock : 0
|
||||
.env : 0
|
||||
workspace member manifest missing : 0
|
||||
```
|
||||
|
||||
Préconditions fonctionnelles :
|
||||
|
||||
```text
|
||||
ksp-raw-transaction-lib : présent + README/USAGE/src/tests/unit_tests
|
||||
ksp-worker-api : présent
|
||||
ksp-job-backfill-lib : présent
|
||||
Backfill -> ksp-raw-transaction-lib : présent
|
||||
ksp-worker-raw-transaction-ingest-lib : absent
|
||||
```
|
||||
|
||||
### 2.2 Baseline statique exécutée avant modification
|
||||
|
||||
```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
|
||||
Markdown table audit: clean (340 table(s), 772 file(s))
|
||||
```
|
||||
|
||||
Les audits automatiques sont verts mais ne détectent pas toutes les contradictions sémantiques entre règles ; la lecture humaine reste obligatoire.
|
||||
|
||||
### 2.3 Cargo local
|
||||
|
||||
```text
|
||||
cargo : indisponible dans l'environnement d'assemblage
|
||||
```
|
||||
|
||||
Donc, pour `pre.001` local :
|
||||
|
||||
```text
|
||||
cargo fmt : NON EXÉCUTÉ
|
||||
cargo check : NON EXÉCUTÉ
|
||||
cargo clippy: NON EXÉCUTÉ
|
||||
cargo test : NON EXÉCUTÉ
|
||||
cargo tree : NON EXÉCUTÉ
|
||||
```
|
||||
|
||||
### 2.4 Preuve opérateur de la stable `0.3.10`
|
||||
|
||||
Le journal opérateur fourni le 8 septembre 2026 montre sur la base stable `0.3.10` :
|
||||
|
||||
```text
|
||||
cargo fmt --all -- --check : terminé sans erreur
|
||||
Rust rule audit : clean
|
||||
Markdown audit : clean dans l'environnement opérateur
|
||||
cargo check --workspace : terminé sans erreur
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings : terminé sans erreur
|
||||
```
|
||||
|
||||
Suites ciblées communiquées :
|
||||
|
||||
```text
|
||||
ksp-raw-transaction-lib : 26 tests verts au total
|
||||
ksp-job-backfill-lib : 77 tests verts au total
|
||||
```
|
||||
|
||||
Les arbres normaux des deux crates ont également été fournis. Cette preuve confirme la qualité de la stable opérateur ; elle ne remplace pas les futurs gates Cargo de `0.3.11-pre.*`.
|
||||
|
||||
## 3. Audit humain des règles
|
||||
|
||||
### 3.1 Divergence D2
|
||||
|
||||
Défaut trouvé dans la stable :
|
||||
|
||||
```text
|
||||
RULES_KSP / KSP-DURABLE-002 : D2 encore nommé Core canonique
|
||||
RULES_KSP / KSP-DURABLE-006 : instructions encore appelées faits Core
|
||||
RULES_DEPENDENCIES / DEP-STORE-004 : D2 encore nommé Core canonique
|
||||
```
|
||||
|
||||
Ces formulations contredisent les règles actives plus récentes et `docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md` :
|
||||
|
||||
```text
|
||||
RAW -> STRUCTURAL -> DECODED -> DOMAIN
|
||||
```
|
||||
|
||||
Correction `pre.001` : règles actives normalisées vers D1 `RAW`, D2 `STRUCTURAL`, D3 `DECODED`, D4 `DOMAIN`. Les traces historiques ne sont pas réécrites.
|
||||
|
||||
### 3.2 Ancien nom Worker
|
||||
|
||||
Défaut trouvé dans :
|
||||
|
||||
```text
|
||||
KSP-WORKER-005
|
||||
KSP-WORKER-006
|
||||
KSP-WORKER-007
|
||||
KSP-WORKER-010
|
||||
```
|
||||
|
||||
Ancien nom :
|
||||
|
||||
```text
|
||||
ksp-worker-raw-retriever
|
||||
```
|
||||
|
||||
Nom durable confirmé par architecture/ROADMAP/CHANGELOG/handoff/prompt :
|
||||
|
||||
```text
|
||||
ksp-worker-raw-transaction-ingest-lib
|
||||
```
|
||||
|
||||
Correction `pre.001` : normalisation du nom uniquement, sans changement de responsabilité des règles.
|
||||
|
||||
### 3.3 Tension Store API/façade Worker auditée
|
||||
|
||||
`DEP-WORKER-003` privilégie l'injection d'APIs pour la logique réutilisable ; `DEP-STORE-010`, l'architecture `011` et le prompt `030` autorisent/ordonnent la façade `ksp-store-lib` pour le producer runtime concret.
|
||||
|
||||
Décision : pas de nouvelle règle nécessaire. La crate concrète dépend de `ksp-store-lib default-features=false`, tandis que la logique de persistence reste derrière un port privé testable. Aucun backend physique n'entre dans la crate.
|
||||
|
||||
## 4. Inventaire des surfaces de référence
|
||||
|
||||
### 4.1 Worker API
|
||||
|
||||
Surface crate-root constatée :
|
||||
|
||||
```text
|
||||
WorkerId
|
||||
WorkerKindCode
|
||||
WorkerState
|
||||
WorkerHealth
|
||||
WorkerActivity
|
||||
WorkerLifecycle
|
||||
WorkerStopToken
|
||||
WorkerSnapshotSequence
|
||||
WorkerSnapshot
|
||||
WorkerSnapshotFuture
|
||||
WorkerSnapshotSource
|
||||
```
|
||||
|
||||
Aucun runtime Tokio, Store, Transport, Config ou type Solana n'est présent.
|
||||
|
||||
### 4.2 Common RAW
|
||||
|
||||
Surface pertinente constatée :
|
||||
|
||||
```text
|
||||
RawTransactionMaterial
|
||||
RawTransactionWireField
|
||||
RawTransactionVersion
|
||||
canonicalize_raw_transaction
|
||||
RawTransactionAcquisition
|
||||
assemble_raw_transaction_acquisition
|
||||
signature/wire helpers
|
||||
```
|
||||
|
||||
La crate dépend de `ksp-store-api` pour les modèles persistables mais reste sans runtime/Transport/Worker/Job/backend.
|
||||
|
||||
### 4.3 Store
|
||||
|
||||
Contrat atomique pertinent :
|
||||
|
||||
```text
|
||||
RawTransactionWrite::persist_raw_transaction_acquisition
|
||||
RawTransactionAcquisitionMode::Normal
|
||||
RawAcquisitionWriteOutcome
|
||||
RawEntityWriteOutcome
|
||||
RawObservationWriteOutcome
|
||||
ERROR_CODE_RAW_CONFLICT
|
||||
```
|
||||
|
||||
`Store` est non-Clone et possède son propre close ; le Worker recevra donc `Arc<Store>` et ne prendra pas la responsabilité de le fermer.
|
||||
|
||||
### 4.4 Backfill
|
||||
|
||||
Patterns vérifiés :
|
||||
|
||||
```text
|
||||
RawTransactionPersistencePort privé
|
||||
Store network check avant write
|
||||
mapping explicite conflict vs idempotence
|
||||
watch/latest-value runtime
|
||||
cancellation et terminal
|
||||
security hardening tests
|
||||
```
|
||||
|
||||
Aucun scope/checkpoint Job n'est transféré au Worker.
|
||||
|
||||
## 5. Fraîcheur des dépendances
|
||||
|
||||
Vérifié le 8 septembre 2026 sur les documentations courantes :
|
||||
|
||||
```text
|
||||
tokio 1.53.1
|
||||
futures-util 0.3.34
|
||||
sha2 0.11.0
|
||||
```
|
||||
|
||||
Constats :
|
||||
|
||||
```text
|
||||
Tokio spawn/JoinHandle -> feature rt
|
||||
Tokio mpsc/watch -> feature sync
|
||||
Tokio select! -> feature macros
|
||||
Tokio timeout/time -> feature time
|
||||
bounded mpsc applique du backpressure
|
||||
watch ne retient que la dernière valeur
|
||||
JoinHandle droppé détache la tâche -> handles privés doivent rester possédés/joints
|
||||
```
|
||||
|
||||
Décision : aucun bump workspace. Le futur manifest Worker prévoit Tokio direct avec `macros,rt,sync,time`, `sha2` pour la key domain-separated, et aucun `futures-util` ni Transport tant qu'un usage réel n'est pas matérialisé.
|
||||
|
||||
## 6. Questions `pre.001` fermées
|
||||
|
||||
### 6.1 Settings
|
||||
|
||||
Surface minimale retenue :
|
||||
|
||||
```text
|
||||
network
|
||||
worker_id
|
||||
admission_queue_capacity
|
||||
persistence_concurrency
|
||||
shutdown_drain_timeout
|
||||
```
|
||||
|
||||
Bornes retenues :
|
||||
|
||||
```text
|
||||
queue : 1..=65_536, default 256
|
||||
persistence concurrency : 1..=64, default 8
|
||||
drain : 100 ms..=30 s, default 5 s
|
||||
```
|
||||
|
||||
### 6.2 Source types
|
||||
|
||||
Décision : `SourceId`, capability, role, continuity et settings provider restent privés/absents en `0.3.11`. Ils ne seront publics qu'avec une première source productive en `0.3.12+`.
|
||||
|
||||
### 6.3 Start/handle
|
||||
|
||||
Décision :
|
||||
|
||||
```text
|
||||
RawTransactionIngestWorker::start(settings, Arc<Store>) -> Result<Handle>
|
||||
request_stop idempotent
|
||||
snapshot_source concret
|
||||
projection WorkerSnapshot commune
|
||||
wait_terminal async boxed sans JoinHandle public
|
||||
```
|
||||
|
||||
### 6.4 Supervisor/tasks
|
||||
|
||||
Décision : supervisor unique privé, `JoinSet`/JoinHandle privés, ownership intégral jusqu'au terminal.
|
||||
|
||||
### 6.5 Channels
|
||||
|
||||
Décision :
|
||||
|
||||
```text
|
||||
1 mpsc borné pour admission
|
||||
1 watch latest-value pour snapshot concret
|
||||
1 watch privé pour réveil stop
|
||||
aucun unbounded channel
|
||||
```
|
||||
|
||||
### 6.6 Timestamps/frontiers
|
||||
|
||||
Décision : aucun frontier/timestamp runtime public dans la fondation. `received_at` reste propriété de l'entrée/provenance source ; run frontier/continuity attendent une source réelle.
|
||||
|
||||
### 6.7 Persistence/conflict
|
||||
|
||||
Décision : Store mode `Normal`, vérité de correction dans Store, aucune cache-based correctness, conflict terminal sans overwrite ni source gagnante.
|
||||
|
||||
### 6.8 Fault
|
||||
|
||||
Décision : erreurs statiques Worker pour settings/runtime/source/store/conflict/drain/counter. Le texte d'erreur distant ou le matériau de transaction n'entre jamais dans snapshot/Debug public.
|
||||
|
||||
## 7. Harness déterministe prévu
|
||||
|
||||
Le harness privé doit pouvoir injecter des matériaux RAW complets et metadata sûre sans réseau et contrôler les ordres de terminaison.
|
||||
|
||||
Preuves minimales :
|
||||
|
||||
```text
|
||||
start/stop normal
|
||||
stop idempotent
|
||||
queue pleine/backpressure
|
||||
concurrency Store bornée
|
||||
new/idempotent/new observation
|
||||
content conflict
|
||||
Store error
|
||||
source failure
|
||||
stop pendant admission/persistence
|
||||
drain timeout
|
||||
no orphan task
|
||||
slow/no snapshot listener
|
||||
latest-value concrete/common
|
||||
redaction
|
||||
```
|
||||
|
||||
Le harness ne devient pas une API publique d'injection.
|
||||
|
||||
## 8. Questions reportées sans blocage
|
||||
|
||||
```text
|
||||
source IDs/capabilities/roles publics
|
||||
required/optional source policy
|
||||
retry/reconnect policy
|
||||
Yellowstone/WS/Helius/HTTP productive adapters
|
||||
run frontier
|
||||
continuity/gap repair
|
||||
hydration live
|
||||
multi-source coalescence optimization
|
||||
hot reconfiguration desired/effective
|
||||
provider smokes
|
||||
```
|
||||
|
||||
Ces sujets appartiennent aux releases `0.3.12+` ou à une tranche ultérieure explicitement ouverte si la base réelle l'impose.
|
||||
|
||||
## 9. Sizing et décision release
|
||||
|
||||
Le forecast initial du prompt est scindé afin de ne pas concentrer crate/settings/runtime/supervision/persistence/snapshots dans les mêmes tranches.
|
||||
|
||||
Prévision retenue :
|
||||
|
||||
```text
|
||||
pre.001 audit/rules/plan
|
||||
pre.002 crate + dependency firewall
|
||||
pre.003 identity/settings
|
||||
pre.004 lifecycle/start/handle/terminal
|
||||
pre.005 supervisor/task ownership + harness
|
||||
pre.006 bounded admission + common RAW
|
||||
pre.007 Store persistence/idempotence/conflict
|
||||
pre.008 snapshots + Worker API projection
|
||||
pre.009 shutdown/backpressure/fault hardening
|
||||
pre.010 public/release/security hardening
|
||||
pre.011 technical final gate
|
||||
pre.012 documentation reconciliation
|
||||
pre.013 publication preparation
|
||||
rel.001
|
||||
```
|
||||
|
||||
Décision `pre.001` : **0.3.11 reste clôturable dans une seule session** si aucune source live, modification Transport/Config, migration Store ou continuity/gap-repair n'entre dans le scope.
|
||||
|
||||
## 10. Gates futurs
|
||||
|
||||
À partir de `pre.002`, chaque tranche Rust rejoue au minimum :
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Les suites et graphes s'ajoutent selon la responsabilité de la tranche. `pre.011` exécute le gate workspace final, y compris :
|
||||
|
||||
```bash
|
||||
cargo test --workspace --all-targets --all-features
|
||||
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
|
||||
```
|
||||
|
||||
## 11. Non-claims `0.3.11`
|
||||
|
||||
Même après fermeture de cette release, ne pas revendiquer :
|
||||
|
||||
```text
|
||||
Yellowstone support
|
||||
WS standard support
|
||||
Helius support
|
||||
HTTP live ingestion
|
||||
lossless provider continuity
|
||||
replay/gap repair
|
||||
multi-provider live convergence
|
||||
hot source reconfiguration
|
||||
Desk ingestion
|
||||
```
|
||||
|
||||
`0.3.11` prouve uniquement que le host runtime Worker est sûr, borné, déterministe et prêt à recevoir ces sources dans les releases suivantes.
|
||||
|
||||
## 12. Gate final `pre.001` dans l’environnement d’assemblage
|
||||
|
||||
Après matérialisation du delta complet :
|
||||
|
||||
```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
|
||||
Markdown table audit: clean (340 table(s), 775 file(s))
|
||||
|
||||
scan sémantique des règles actives : 0 formulation obsolète ciblée restante
|
||||
comparaison byte-à-byte avec la stable : 3 fichiers ajoutés, 3 modifiés, 0 supprimé
|
||||
```
|
||||
Reference in New Issue
Block a user