v0.3.11-pre.007

This commit is contained in:
2026-09-08 11:32:41 +02:00
parent 355c5d1e9a
commit ed6c0ac10c
12 changed files with 1239 additions and 58 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md -->
<!-- version: 6 -->
<!-- version: 7 -->
# Plan v0.3.11 — fondation runtime du Worker RawTransaction ingest
@@ -726,12 +726,14 @@ Budget cible : **1520 min**. Introduire le supervisor, les JoinSet/joins priv
Budget cible : **1520 min**. `mpsc` borné, backpressure, ingress privé, common `RawTransactionMaterial -> RawTransaction`, observation-key domain/golden et assembly. Pas de source réseau.
État après matérialisation : **implémenté, gate opérateur requis**. Le supervisor possède un channel central `tokio::sync::mpsc` borné par `admission_queue_capacity`. Le seam source reçoit directement un clone du sender borné ainsi que le `watch<bool>` de stop ; le harness prouve `send().await` sous saturation et un `select! biased` stop-before-send, sans helper de production mort avant les vraies sources. L'ingress reste crate-private et transporte material source-neutral, network attendu, provenance sûre et une source key opaque de 32 bytes. Le Worker canonicalise exclusivement via `ksp-raw-transaction-lib`, vérifie le réseau avant/après canonicalisation, dérive l'observation key sous `ksp.raw_transaction_ingest.observation.v1` à partir de `(network, signature, source_key)`, puis assemble un `RawTransactionAcquisition` via le common RAW. Au stop, le receiver ferme les nouvelles admissions puis canonicalise les entrées déjà admises avant le join final. Aucune persistence Store, source live, Transport, snapshot concret ou policy provider n'est introduite.
État après matérialisation : **implémenté et gate opérateur validé après `pre.006-fix.001`**. Le supervisor possède un channel central `tokio::sync::mpsc` borné par `admission_queue_capacity`. Le seam source reçoit directement un clone du sender borné ainsi que le `watch<bool>` de stop ; le harness prouve `send().await` sous saturation et un `select! biased` stop-before-send, sans helper de production mort avant les vraies sources. L'ingress reste crate-private et transporte material source-neutral, network attendu, provenance sûre et une source key opaque de 32 bytes. Le Worker canonicalise exclusivement via `ksp-raw-transaction-lib`, vérifie le réseau avant/après canonicalisation, dérive l'observation key sous `ksp.raw_transaction_ingest.observation.v1` à partir de `(network, signature, source_key)`, puis assemble un `RawTransactionAcquisition` via le common RAW. `pre.006-fix.001` corrige uniquement les séparateurs de branches du `tokio::select!` de test ; le gate communiqué le 8 septembre 2026 est ensuite vert sur `fmt`, audits, `check`, Clippy strict, 22 tests de crate et doc-tests. Aucun arbre Cargo n'a été rejoué après ce fix strictement sans changement de dépendance. Aucune persistence Store, source live, Transport, snapshot concret ou policy provider n'est introduite.
### `pre.007` — persistence Store + idempotence/conflict
Budget cible : **1520 min**. Port privé Store, mode Normal, concurrency bornée, outcomes new/idempotent/purged, observation distincte, Store error et content conflict terminal.
État après matérialisation : **implémenté, gate opérateur requis**. La crate possède désormais un port de persistence Store crate-private, implémenté par la façade `ksp-store-lib::Store`, et appelle exclusivement l'opération atomique transaction + observation en `RawTransactionAcquisitionMode::Normal`. Le supervisor possède un `JoinSet` privé de persistences ; il ne lit une nouvelle acquisition que si `in_flight < persistence_concurrency`, ce qui borne les écritures sans sémaphore ni file secondaire. Les succès distinguent `Inserted`, `AlreadyPresent`, `SkippedPurged` et les observations `Inserted`, `AlreadyPresent`, `NotRecorded`; `Rehydrated` ou toute combinaison impossible en mode Normal deviennent `runtime_invalid`. `store_api.raw_conflict` est réduit à `worker_raw_transaction_ingest.content_conflict`; toute autre erreur Store devient `worker_raw_transaction_ingest.store_failed` en ne conservant que le `ErrorCode` inférieur sûr. Le premier fault de cette tranche signale le stop privé, ferme ensuite les nouvelles admissions, draine les acquisitions déjà admises, rejoint persistences et sources, puis publie le terminal. Les races terminales fortes et le timeout/abort restent réservés à `pre.009`; les compteurs/snapshots restent réservés à `pre.008`.
### `pre.008` — snapshots concrets + projection Worker API
Budget cible : **1520 min**. `watch` latest-value, compteurs checked, common projection, slow/no listener et terminal retained.