v0.3.11-pre.006
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Plan v0.3.11 — fondation runtime du Worker RawTransaction ingest
|
||||
|
||||
@@ -344,7 +344,7 @@ Les `JoinHandle`/`JoinSet` restent strictement privés. Dropper le handle public
|
||||
Un seul channel central :
|
||||
|
||||
```text
|
||||
tokio::sync::mpsc::channel<PrivateRawTransactionIngress>(admission_queue_capacity)
|
||||
tokio::sync::mpsc::channel<RawTransactionIngress>(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.
|
||||
@@ -361,13 +361,14 @@ Un `watch<RawTransactionIngestSnapshot>` privé conserve uniquement la dernière
|
||||
|
||||
## 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.
|
||||
Le runtime de fondation est prouvé par un harness privé qui produit des `RawTransactionIngress` crate-private contrôlés.
|
||||
|
||||
Une entrée de harness contient conceptuellement :
|
||||
|
||||
```text
|
||||
RawTransactionMaterial
|
||||
RawObservationKey déterministe Worker-owned
|
||||
RawNetworkId attendu
|
||||
source key privée déterministe [u8; 32]
|
||||
RawAcquisitionProvenance sûre
|
||||
```
|
||||
|
||||
@@ -413,9 +414,9 @@ La Worker observation key est un SHA-256 KSP-owned versionné et domain-separate
|
||||
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 bytes exacts/golden sont figés en `pre.006` à partir de l'identité `(network, signature)` et d'une source key privée opaque de 32 bytes. Le SHA-256 est domain-separated puis encode chaque composant avec une longueur `u64` big-endian. Aucun timestamp local aléatoire, run id ni ordre d'admission 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.
|
||||
Les éléments provider/source utilisés pour produire cette source key 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 sans ouvrir une API source prématurée.
|
||||
|
||||
### 10.3 Outcomes
|
||||
|
||||
@@ -719,12 +720,14 @@ Les méthodes `snapshot_source()` et `worker_snapshot_source()` prévues par la
|
||||
|
||||
Budget cible : **15–20 min**. Introduire le supervisor, les JoinSet/joins privés, intégrer le wake-up de stop déjà matérialisé à l'ownership des tâches enfants, ajouter le test source seam et prouver qu'aucune tâche enfant ne survit au terminal. Pas encore de persistence réelle.
|
||||
|
||||
État après matérialisation : **implémenté, gate opérateur requis**. Le task racine est désormais le supervisor privé et possède un `tokio::task::JoinSet<()>`. Un seam privé de spawn de sources reçoit le `JoinSet` et un clone du `watch<bool>` de stop ; la production utilise un seam vide tandis que les unit tests injectent des tâches coopératives déterministes. Le supervisor récole les enfants terminés pendant l'exécution puis, au stop ou à la fermeture du channel de contrôle, attend la fin de tous les enfants avant de publier `Stopped`. Un `JoinError` observé marque la supervision comme non clean ; si la fermeture de supervision est ensuite engagée, le terminal est projeté vers `Faulted(worker_raw_transaction_ingest.runtime_invalid)`. Le traitement immédiat/prioritaire des faults reste différé à `pre.009`. Aucun timeout/abort forcé n'est encore introduit : ce hardening reste réservé à `pre.009`.
|
||||
État après matérialisation : **implémenté et gate opérateur validé**. Le task racine est désormais le supervisor privé et possède un `tokio::task::JoinSet<()>`. Un seam privé de spawn de sources reçoit le `JoinSet` et un clone du `watch<bool>` de stop ; la production utilise un seam vide tandis que les unit tests injectent des tâches coopératives déterministes. Le supervisor récole les enfants terminés pendant l'exécution puis, au stop ou à la fermeture du channel de contrôle, attend la fin de tous les enfants avant de publier `Stopped`. Un `JoinError` observé marque la supervision comme non clean ; si la fermeture de supervision est ensuite engagée, le terminal est projeté vers `Faulted(worker_raw_transaction_ingest.runtime_invalid)`. Le traitement immédiat/prioritaire des faults reste différé à `pre.009`. Aucun timeout/abort forcé n'est encore introduit : ce hardening reste réservé à `pre.009`. Le gate communiqué le 8 septembre 2026 est vert sur `fmt`, audits, `check`, Clippy strict, 18 tests de crate, doc-tests et les deux arbres Cargo.
|
||||
|
||||
### `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.
|
||||
|
||||
É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.
|
||||
|
||||
### `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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Validation v0.3.11 — fondation runtime du Worker RawTransaction ingest
|
||||
|
||||
@@ -852,3 +852,165 @@ cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features
|
||||
|
||||
Critère de passage : le supervisor/JoinSet privé, le seam source déterministe et le join complet avant terminal sont verts ; aucun `mpsc`, common RAW assembly, Store write, snapshot concret, source live ou Transport n'apparaît.
|
||||
|
||||
## 17. Fermeture opérateur `pre.005` et matérialisation `pre.006`
|
||||
|
||||
### 17.1 Fermeture opérateur de `pre.005`
|
||||
|
||||
Le journal opérateur communiqué le 8 septembre 2026 ferme `0.3.11-pre.005` (`workspace.package.version = 0.3.11-pre.5`) :
|
||||
|
||||
```text
|
||||
cargo fmt --all : terminé sans erreur
|
||||
python3 scripts/audit_rust_workspace_rules.py : clean, export completeness 0
|
||||
python3 scripts/audit_markdown_tables.py ... : clean (340 tables, 780 files)
|
||||
cargo check --workspace : terminé sans erreur
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings : terminé sans erreur
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib : 11 unit + 3 dependency-boundary + 4 public API PASS, 0 échec
|
||||
doc-tests : PASS
|
||||
cargo tree normal : conforme au firewall attendu
|
||||
cargo tree features : Tokio limité à macros/rt/sync/time côté Worker et Store sans backend Worker direct
|
||||
```
|
||||
|
||||
`pre.006` peut donc être ouverte.
|
||||
|
||||
### 17.2 Admission centrale bornée
|
||||
|
||||
Le supervisor crée exactement un channel central :
|
||||
|
||||
```text
|
||||
tokio::sync::mpsc::channel<RawTransactionIngress>(admission_queue_capacity)
|
||||
```
|
||||
|
||||
`RawTransactionIngress` reste crate-private et n'appartient pas à l'API publique. Le receiver owner `RawTransactionAdmission` est également crate-private ; le seam source reçoit directement un clone du `tokio::sync::mpsc::Sender<RawTransactionIngress>` avec son `watch<bool>` de stop.
|
||||
|
||||
Le contrat d'admission est :
|
||||
|
||||
```text
|
||||
mpsc::Sender::send(...).await pour le backpressure
|
||||
source harness : select! biased avec stop avant send
|
||||
receiver close au shutdown
|
||||
aucun unbounded_channel
|
||||
aucun drop silencieux sous saturation normale
|
||||
```
|
||||
|
||||
Le supervisor continue à observer le stop en priorité. Lors de la fermeture, le receiver appelle `close()`, refuse toute nouvelle admission, puis canonicalise les entrées déjà présentes dans le buffer avant le join final des tâches enfants.
|
||||
|
||||
### 17.3 Ingress privé et common RAW
|
||||
|
||||
L'ingress de fondation porte uniquement :
|
||||
|
||||
```text
|
||||
RawTransactionMaterial
|
||||
RawNetworkId attendu
|
||||
RawAcquisitionProvenance sûre
|
||||
source key opaque [u8; 32]
|
||||
```
|
||||
|
||||
Le pipeline `pre.006` est :
|
||||
|
||||
```text
|
||||
vérifier ingress.network == settings.network
|
||||
canonicalize_raw_transaction(material)
|
||||
vérifier transaction.reference.network == settings.network
|
||||
dériver RawObservationKey Worker-owned
|
||||
assemble_raw_transaction_acquisition(transaction, observation_key, provenance)
|
||||
```
|
||||
|
||||
Aucune logique de canonicalisation RAW v1 n'est recodée dans le Worker. Une erreur common RAW est réduite à un contexte runtime statique et n'échoe aucun payload, réseau ou signature.
|
||||
|
||||
### 17.4 Observation key privée V1
|
||||
|
||||
Le domaine exact est :
|
||||
|
||||
```text
|
||||
ksp.raw_transaction_ingest.observation.v1\0
|
||||
```
|
||||
|
||||
L'entrée SHA-256 est domain-separated puis encode avec longueur `u64` big-endian :
|
||||
|
||||
```text
|
||||
network UTF-8
|
||||
signature 64 bytes
|
||||
source key 32 bytes
|
||||
```
|
||||
|
||||
Aucun timestamp local, run id ou ordre d'admission n'entre dans la clé. Une rediffusion du même triplet produit donc la même `RawObservationKey`; le contrat provider/source public reste reporté à `0.3.12`.
|
||||
|
||||
Golden harness figé :
|
||||
|
||||
```text
|
||||
network : mainnet
|
||||
signature : 64 x 0x07
|
||||
source key : 32 x 0x09
|
||||
SHA-256 : f8d161dca8a8a72a0da110fc87882ee7136848461c6aa32b09e30a6188b95dcc
|
||||
```
|
||||
|
||||
### 17.5 Preuves ajoutées
|
||||
|
||||
Les tests unitaires `pre.006` couvrent :
|
||||
|
||||
```text
|
||||
capacity = 1 : second send reste bloqué tant que le premier slot n'est pas consommé
|
||||
stop : un sender bloqué retourne false sans admission post-stop
|
||||
common RAW : payload canonique exact + format/version exacts
|
||||
observation key : golden exact
|
||||
assembly : transaction/provenance/reference alignés
|
||||
network guard : mismatch ingress et mismatch material rejetés sans fuite de valeurs
|
||||
```
|
||||
|
||||
Le test de dependency boundary exige désormais `mpsc`, common canonicalization, common assembly et le domaine observation, tout en interdisant toujours persistence, mode Store, Transport, snapshots et `unbounded_channel`.
|
||||
|
||||
### 17.6 Frontière volontaire de `pre.006`
|
||||
|
||||
La tranche n'introduit encore aucun :
|
||||
|
||||
```text
|
||||
RawTransactionWrite::persist_raw_transaction_acquisition
|
||||
RawTransactionAcquisitionMode::Normal
|
||||
persistence concurrency
|
||||
Store outcome mapping
|
||||
content conflict terminal
|
||||
store failure terminal
|
||||
snapshot concret / compteurs publics
|
||||
source live / Transport
|
||||
Config
|
||||
retry/reconnect/gap repair
|
||||
```
|
||||
|
||||
`pre.007` reste propriétaire de la persistence et des outcomes. `pre.008` reste propriétaire des snapshots. `pre.009` reste propriétaire du fault ordering immédiat et du drain timeout/abort.
|
||||
|
||||
### 17.7 Preuves locales d'assemblage `pre.006`
|
||||
|
||||
Exécuté dans l'environnement d'assemblage :
|
||||
|
||||
```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), 781 file(s))
|
||||
|
||||
scan statique production : aucun ?, unwrap, expect, panic, unbounded_channel
|
||||
scan statique scope : aucune persistence Store, aucun Transport, aucun snapshot concret
|
||||
scan statique pipeline : exactement un mpsc::channel, un appel common canonicalize et un appel common assembly
|
||||
golden SHA-256 indépendant : f8d161dca8a8a72a0da110fc87882ee7136848461c6aa32b09e30a6188b95dcc
|
||||
```
|
||||
|
||||
L'environnement d'assemblage ne fournit ni `cargo`, ni `rustc`, ni `rustfmt`. Aucun gate Cargo `pre.006` n'est déclaré PASS localement.
|
||||
|
||||
### 17.8 Gate opérateur demandé pour `pre.006`
|
||||
|
||||
```bash
|
||||
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
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
cargo test -p ksp-worker-raw-transaction-ingest-lib
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib --edges normal
|
||||
cargo tree -p ksp-worker-raw-transaction-ingest-lib -e features
|
||||
```
|
||||
|
||||
Critère de passage : admission bornée/backpressure, stop-preemption, canonicalisation common, golden observation et assembly sont verts ; aucune persistence Store, source live, Transport ou snapshot concret n'apparaît.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user