Files
khadhroony-solana-project/docs/validation/029-V0_3_12_YELLOWSTONE_HYDRATION_CONTINUITY.md

51 KiB
Raw Blame History

Validation v0.3.12 — Yellowstone + hydration HTTP + continuité de run du Worker RawTransaction

1. Rôle du document

Ce document enregistre les preuves réellement exécutées, les non-claims et les gates progressifs de 0.3.12. Une commande non exécutée n'est jamais déclarée PASS.

pre.001 est un gate de lecture/audit/sizing. Il ne contient aucun code Worker réseau productif.

2. Gate pre.001 — base stable

2.1 Archive contrôlée

archive : khadhroony-solana-project-v0.3.11.zip
SHA-256 : a6bb59935650a7f48630d12ef80fbd1a44a84819dd129b085ff7f467369535fc
bytes : 8125100
entries : 1950
unzip -t : PASS
root unique : PASS
absolute entries : 0
path traversal : 0
symlinks : 0
.git/ : 0
target/ : 0
node_modules/ : 0
Cargo.lock : 0
.env : 0
workspace members : 21
workspace.package.version : 0.3.11

deltas/0.3.11/rel.001.md est présent.

2.2 Préconditions fonctionnelles

Contrôlé dans la stable :

ksp-worker-raw-transaction-ingest-lib présent
README/USAGE présents
aucun edge Worker -> Transport
aucune source réseau productive dans src/
ksp-raw-transaction-lib présent
ksp-onchain-transport-lib présent avec Yellowstone gRPC générique
ksp-store-lib présent
ksp-job-backfill-lib ne dépend pas du Worker

Résultat : PASS.

3. Baseline statique locale avant modification

Exécuté dans l'archive extraite :

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

Résultat : PASS.

Exécuté :

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), 798 file(s))

Résultat : PASS.

4. Cargo local dans l'environnement d'assemblage

cargo n'est pas installé dans l'environnement d'assemblage utilisé pour pre.001.

Non exécuté localement :

cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-targets --all-features
cargo tree --duplicates

Ces commandes ne sont pas déclarées PASS localement.

5. Preuve opérateur de la stable 0.3.11

Le journal fourni avec la demande d'ouverture montre sur la stable :

cargo clean : exécuté
cargo fmt --all -- --check : sans erreur visible
audit Rust : clean
audit Markdown : clean (340 tables, 798 fichiers)
cargo check --workspace : terminé sans erreur
cargo clippy --workspace --all-targets --all-features -- -D warnings : terminé sans erreur
cargo test --workspace : suites affichées vertes ; tests live opt-in ignorés conformément à leur contrat
cargo tree Worker normal/features : demandé dans le journal opérateur

Cette preuve opérateur concerne l'état stable d'entrée. Elle n'est pas réétiquetée comme exécution locale de 0.3.12-pre.001.

6. Audit humain des règles

Sources lues pour le gate :

RULES.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/rules/RULES_GENERAL.md
docs/rules/RULES_KSP.md
docs/rules/RULES_RUST.md
docs/rules/RULES_DEPENDENCIES.md
docs/rules/RULES_DOCUMENTATION.md
docs/rules/FILE_CONTRACTS.md
docs/rules/VERSION_WORKFLOW.md
docs/rules/PROMPT_STRUCTURE.md

Résultat : aucune divergence normative active nécessitant une correction de règle en pre.001.

Vérifications clés :

D2 reste STRUCTURAL
nom Worker canonique = ksp-worker-raw-transaction-ingest-lib
Worker/Job restent séparés
Config reste propriétaire de l'environnement et des secrets
Store backend direct reste interdit au Worker
VER-ID-009 impose 0.3.12-pre.1 pour cette prerelease non-fix

7. Sources internes de handoff auditées

Lecture/inventaire réalisés sur :

docs/plans/032-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION_PLAN.md
docs/validation/028-V0_3_11_RAW_TRANSACTION_INGEST_WORKER_FOUNDATION.md
crates/ksp-worker-raw-transaction-ingest-lib/Cargo.toml
crates/ksp-worker-raw-transaction-ingest-lib/README.md
crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md
crates/ksp-worker-raw-transaction-ingest-lib/src/
crates/ksp-worker-raw-transaction-ingest-lib/tests/
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/

docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md
docs/plans/031-V0_3_10_RAW_TRANSACTION_INGEST_PLAN.md
docs/validation/027-V0_3_10_RAW_TRANSACTION_INGEST.md
crates/ksp-raw-transaction-lib/README.md
crates/ksp-raw-transaction-lib/USAGE.md
crates/ksp-raw-transaction-lib/src/
crates/ksp-raw-transaction-lib/tests/

crates/ksp-onchain-transport-lib/Cargo.toml
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-onchain-transport-lib/src/grpc_*.rs
crates/ksp-onchain-transport-lib/src/rpc_transactions.rs
crates/ksp-onchain-transport-lib/src/rpc_blocks.rs
crates/ksp-onchain-transport-lib/tests/

crates/ksp-store-lib/README.md
crates/ksp-store-lib/USAGE.md
crates/ksp-store-lib/src/
crates/ksp-worker-api/README.md
crates/ksp-worker-api/USAGE.md
crates/ksp-worker-api/src/
crates/ksp-config-lib/README.md
crates/ksp-config-lib/USAGE.md
crates/ksp-config-lib/src/

Le résultat d'inventaire est détaillé dans le plan 033.

8. Preuve Worker stable

Le Worker stable possède exactement huit fichiers de production sous src/ :

admission.rs
error.rs
identity.rs
lib.rs
persistence.rs
runtime.rs
settings.rs
snapshot.rs

Le manifest normal ne contient pas ksp-onchain-transport-lib, ksp-config-lib, ksp-job-backfill-lib, backend physique, Tonic, Reqwest ni Yellowstone proto.

Un scan source grpc|yellowstone|http|ws|transport ne révèle qu'une documentation signalant l'absence de source live ; aucun adapter réseau productif n'est présent.

Résultat : PASS pour la précondition 0.3.11.

9. Preuve Transport actuelle

Contrats existants confirmés :

YellowstoneGrpcChannel::open_standard_subscribe
SolanaYellowstoneGrpcSubscribeSession::next_update
SolanaYellowstoneGrpcSubscribeSession::snapshot
YellowstoneSubscribeRequest::set_from_slot
YellowstoneReplayInfo::first_available
HttpTransportPool::get_transaction_observed
HttpTransportPool::get_block_observed
HttpObservedValue::{value, endpoint_name, provider}

Le snapshot Yellowstone indique explicitement :

continuity_gap_count : seulement gap prouvé par borne ReplayInfo
replay_attempt_count : tentative, pas preuve de couverture
duplicate_update_count : observabilité, duplicates toujours livrés
last_requested_from_slot
last_observed_slot

Résultat : PASS pour la réutilisation du moteur existant.

10. Audit externe de fraîcheur

10.1 Yellowstone versions

Source docs.rs courante :

yellowstone-grpc-proto latest : 12.7.0
publication : 2026-08-29
workspace KSP : ^12.7

Résultat : aucune mise à jour de dépendance nécessaire en pre.001.

10.2 Replay upstream

Le changelog upstream du 22 juillet 2026 documente la correction yellowstone-grpc-geyser 14.2.1 pour un cas où from_slot + blocks était accepté mais aucun Block replay n'était livré avant reprise live.

Impact de validation :

subscribe accepted != replay proven
from_slot sent != replay proven
first_available compatible != replay proven

Cette menace doit posséder un canari KSP et, si un provider live est disponible, un smoke dédié.

10.3 Solana HTTP

La documentation officielle courante confirme que getTransaction à confirmed/finalized, en Base64, fournit les champs nécessaires à la conversion Common RAW déjà qualifiée : blockTime, meta, slot, transaction, version.

Résultat : hydration getTransaction maintenue comme référence P0.

10.4 Providers

OrbitFlare documente encore Devnet gRPC et un free tier Devnet-only. Helius LaserStream documente Yellowstone wire compatibility et un replay provider-specific d'environ 216 000 slots / 24 heures. Ces valeurs ne sont pas transposées dans les constantes KSP.

PublicNode reste operator-only dans KSP ; aucune nouvelle assertion provider n'est ajoutée faute de source primaire indexée suffisamment précise pendant ce gate.

11. Gate de matrice Yellowstone fermé

11.1 Transaction

Preuve interne : YellowstoneTransactionUpdate contient slot, filter names, created_at et YellowstoneTransactionInfo; ce dernier contient signature, transaction, meta, index.

Conclusion : candidat hydration ; RAW-direct non prouvé.

11.2 TransactionStatus

Preuve interne : slot, signature, index, is_vote, error optionnelle.

Conclusion : discovery/hydration seulement.

11.3 Block

Preuve interne : slot, block_time, transactions avec transaction/meta/signature/index, compteurs et metadata block.

Conclusion : chaque transaction peut devenir candidat hydration ; aucun pipeline block RAW parallèle.

11.4 BlockMeta

Conclusion : continuity/health only ; aucune signature donc aucune hydration transaction autonome.

11.5 Slot

Conclusion : continuity/health only ; aucune admission RAW.

11.6 from_slot

Conclusion : mécanisme Transport de replay au reconnect, pas checkpoint historique Worker.

11.7 ReplayInfo

Conclusion : first_available prouve seulement une limite de rétention. Un gap est prouvé quand la demande est antérieure à cette borne ; le cas inverse ne prouve pas que toutes les updates filtrées ont été livrées.

12. Gate architecture d'injection fermé

Décision :

nouvel edge autorisé : Worker -> ksp-onchain-transport-lib
Worker -> Config : interdit
Worker -> Job : interdit
Worker -> backend : interdit
Worker -> Tonic/Reqwest/yellowstone-grpc-proto direct : non retenu

La composition supérieure construit YellowstoneGrpcChannel, YellowstoneSubscribeRequest, HttpTransportPool et HttpRoleName. pre.002 matérialise exactement :

RawTransactionIngestYellowstoneSource::new(...)
RawTransactionIngestRuntimeResources::new(yellowstone_source)
RawTransactionIngestWorker::start_with_runtime_resources(settings, Arc<Store>, resources)

Les champs restent privés. RawTransactionIngestWorker::start(settings, Arc<Store>) reste disponible comme foundation source-neutral. Aucune API publique enqueue n'est ouverte.

13. Gate hydration/provenance fermé

Hydration P0 :

get_transaction_observed
Base64
confirmed/finalized uniquement
maxSupportedTransactionVersion = 0

Provenance : route composite encodée dans les champs RawAcquisitionProvenance existants, avec provider/endpoint réels du winner HTTP et identité sûre Yellowstone, sous MAX_RAW_CODE_BYTES. Aucune migration Store.

Un code composite impossible à représenter est rejeté ; aucune troncature silencieuse.

14. Gate continuité fermé

Décisions :

Transport high-watermark != Worker processing frontier
processing frontier != blockchain completeness
reconnect != replay
replay != repair
continuity gap prouvé => fault Worker sûr
aucun Backfill automatique
aucun checkpoint persistant inter-process
pending hydration peut survivre au reconnect source dans le même run

Le split pre.007/pre.008 évite de coder frontier et replay semantics dans une seule tranche.

15. Threat model à transformer en tests

Canaris obligatoires :

secret/URL/header redaction
remote status/error text not copied
bounded signal/hydration queues
bounded coalescence
no duplicate HTTP in-flight for same key
no double retry storm
stop during connect/reconnect/hydration/replay
no admission after stop frontier
no orphan task after terminal
counter checked arithmetic
stale frontier never labelled complete
continuity gap terminal and safe

16. Smokes live

16.1 Disponibilité démontrée par le dépôt

Présents et ignored :

yellowstone_orbitflare_smoke
yellowstone_publicnode_smoke

Ils exigent des tokens fournis de manière operator-only.

16.2 Disponibilité opérateur pour pre.001

Aucun secret live n'est fourni dans l'archive. Le journal stable montre ces tests comme ignorés par défaut.

Résultat :

Worker live smoke : NON EXÉCUTÉ en pre.001
raison : pipeline productif pas encore implémenté + secret/provider live non fourni au gate

Aucun faux PASS live n'est enregistré.

17. Graphe Cargo cible vérifiable à partir de pre.002

Attendu :

Worker -> core
Worker -> logging
Worker -> onchain-transport
Worker -> raw-transaction
Worker -> store facade default-features=false
Worker -> worker-api
Worker -> sha2
Worker -> tokio

Toujours absent :

Config
Job Backfill
Store backend
Tauri
provider SDK
Tonic direct
Reqwest direct
Yellowstone proto direct

18. Sizing et décision release

Forecast retenu :

pre.001 audit/sizing/plan
pre.002 Transport resource/source contract
pre.003 Transaction + TransactionStatus signal adapters
pre.004 HTTP hydration + provenance composite
pre.005 Block + BlockMeta + Slot adapters
pre.006 productive source task + supervisor/coalescence
pre.007 processing frontier
pre.008 reconnect/from_slot/ReplayInfo
pre.009 races/retry/backpressure hardening
pre.010 cross-layer completeness/security
pre.011 technical/live gate
pre.012 documentation reconciliation
pre.013 publication preparation
rel.001

Décision : 0.3.12 reste ouverte et n'est pas rescindée. Toute tranche dépassant réellement 1520 minutes est scindée avant exécution.

19. Validation après modification de pre.001

Exécuté sur le delta complet :

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), 801 file(s))

Résultat : PASS pour les audits statiques locaux.

Cargo reste NON EXÉCUTÉ localement car l'outil n'est pas installé.

Le gate opérateur demandé après application du delta est :

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

pre.001 n'ajoutant aucun Rust, les tests ciblés Worker restent une preuve de non-régression facultative mais recommandée :

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

20. Non-claims pre.001

pre.001 ne prétend pas avoir :

ajouté l'edge Worker -> Transport dans Cargo
ouvert une session Yellowstone dans le Worker
hydraté une transaction live
persisté un RAW live Yellowstone
prouvé un RAW-direct Yellowstone
prouvé un replay provider complet
implémenté une frontier
implémenté un repair
enrichi les snapshots runtime
exécuté un smoke live Worker
exécuté Cargo dans l'environnement d'assemblage

21. Critère de sortie pre.001

Le gate est fermé si :

base stable prouvée
règles auditées
surfaces internes inventoriées
fraîcheur externe auditée
matrice Yellowstone fermée
injection runtime décidée
hydration/provenance décidées
frontier/replay/repair distingués
threat model défini
smokes classifiés
Cargo graph cible défini
forecast <20 min par tranche
maintien/split décidé
plan + validation + delta créés
audits statiques post-modification verts

22. Gate opérateur reçu pour pre.001

L'opérateur a exécuté après application de pre.001 :

cargo fmt --all : sans erreur visible
audit Rust : clean
Rust export completeness : 0 candidate
KSP workspace Rust rule audit : clean
audit Markdown : clean (340 tables, 801 fichiers)
cargo check --workspace : PASS visible
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS visible

Aucun cargo test ou cargo tree n'est présent dans ce journal ; ils ne sont donc pas revendiqués pour ce gate.

Résultat : pre.001 est accepté comme base technique de pre.002.

23. Gate pre.002 — edge Transport + contrats runtime/source

La tranche matérialise exactement :

workspace.package.version = 0.3.12-pre.2
Worker -> ksp-onchain-transport-lib
RawTransactionIngestYellowstoneSource
RawTransactionIngestRuntimeResources
RawTransactionIngestWorker::start_with_runtime_resources(...)

Le constructeur RawTransactionIngestYellowstoneSource::new effectue uniquement des validations déterministes sans I/O :

YellowstoneSubscribeRequest::validate
au moins une famille transactions / transactions_status / blocks
commitment explicite confirmed ou finalized
rôle HTTP configuré compatible avec le request kind get_transaction
cluster identique entre Yellowstone et toutes les routes HTTP compatibles

RawTransactionIngestRuntimeResources conserve un seul source Yellowstone à champs privés et vérifie la cohérence avec RawTransactionIngestSettings.network avant le démarrage.

start_with_runtime_resources préserve également le gate Store/settings existant. En pre.002, il ne démarre volontairement encore aucun source live : les ressources sont validées mais ne sont pas activées, puis le démarrage délègue au runtime source-neutral existant. L'activation du stream reste réservée à pre.006 conformément au plan.

24. Canaris déterministes ajoutés en pre.002

Les preuves statiques/unitaires ajoutées couvrent :

manifest Worker exact avec un seul nouvel edge Transport
aucun Config / Job / backend Store / tonic / reqwest / yellowstone-grpc-proto direct
source confirmed + transaction + getTransaction route accepté
processed et commitment implicite rejetés
absence de famille d'ingestion rejetée
rôle HTTP sans get_transaction rejeté
mismatch cluster Yellowstone/HTTP rejeté
mismatch réseau Worker/source rejeté
Debug sans URL, token, filter name ou client inner
API publique des deux resource types disponible depuis crate root
start_with_runtime_resources disponible depuis crate root
aucun enqueue/send/inner/client getter public
aucun open_standard_subscribe / next_update / get_transaction_observed dans la tranche
Transport confiné à runtime_resources.rs dans les sources Worker

Aucun nouveau code Config, Store backend, Backfill ou provider n'est introduit.

25. Validation locale après modification de pre.002

Exécuté dans l'environnement d'assemblage :

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

L'audit Markdown est rejoué après création du delta final afin d'inclure le nouveau fichier deltas/0.3.12/pre.002.md.

cargo, rustc et rustfmt ne sont pas installés dans cet environnement ; aucun gate Cargo local n'est revendiqué.

Gate opérateur demandé après application du delta :

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
cargo tree --duplicates

26. Non-claims pre.002

pre.002 ne prétend pas avoir :

ouvert une session Yellowstone
lu une update Transaction/TransactionStatus/Block
émis un signal Worker privé
appelé getTransaction pour hydration
assemblé une provenance composite
persisté une transaction issue du réseau
coalescé des hydrations
modifié la processing frontier
branché from_slot/replay info
exécuté un smoke live Worker
réconcilié README/USAGE/architecture pour la surface finale 0.3.12

La tranche suivante reste pre.003 : adaptation déterministe Transaction + TransactionStatus vers le signal Worker privé, sans HTTP ni persistence réseau.

27. Gate opérateur reçu pour pre.002

L'opérateur a exécuté après application de pre.002 :

cargo fmt --all : sans erreur visible
audit Rust : clean
Rust export completeness : 0 candidate
KSP workspace Rust rule audit : clean
audit Markdown : clean (340 tables, 802 fichiers)
cargo check --workspace : PASS visible
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS visible
cargo test -p ksp-worker-raw-transaction-ingest-lib : 41 PASS, 0 fail
cargo tree Worker normal : exécuté et inspecté
cargo tree Worker features : exécuté et inspecté
cargo tree --duplicates : exécuté ; inventaire informatif des versions dupliquées, sans gate d'unicité artificiel

Le graphe confirme que le Worker possède directement uniquement l'edge ksp-onchain-transport-lib; reqwest, tonic, tonic-prost et yellowstone-grpc-proto restent transitifs sous Transport.

Résultat : pre.002 est accepté comme base technique de pre.003.

28. Gate pre.003 — signal privé Transaction + TransactionStatus

La tranche matérialise :

workspace.package.version = 0.3.12-pre.3
projection Yellowstone Transaction -> signal Worker privé
projection Yellowstone TransactionStatus -> même signal Worker privé
aucune ouverture de stream
aucune hydration HTTP
aucune persistence réseau

Le signal reste strictement interne à runtime_resources.rs et n'est ni pub, ni pub(crate), ni réexporté au crate-root.

Sa forme source-neutral actuelle est :

network
signature RawTransactionSignature
slot
transaction_index optionnel
source family Transaction | TransactionStatus
safe Yellowstone source route provider + endpoint_id
matched_filter_count
matched_filter_fingerprint SHA-256 déterministe
created_at source-neutral optionnel seconds+nanos

Aucun transaction body, meta Yellowstone, is_vote, remote error ou payload provider n'est conservé dans ce signal.

29. Projection déterministe des filtres et de la route

Les filter names Yellowstone sont consommés uniquement pour produire un fingerprint Worker-owned. Le calcul :

domain = ksp.raw_transaction_ingest.yellowstone.filters.v1\0
tri lexical des noms
suppression des doublons
nombre de noms uniques encodé u64 big-endian
pour chaque nom : longueur u64 big-endian + bytes UTF-8
SHA-256 final

Le signal conserve séparément le nombre de matches reçu afin de ne pas confondre le fingerprint canonique de l'ensemble et la cardinalité de l'enveloppe reçue.

La source valide aussi dès sa construction que :

cluster Yellowstone -> RawNetworkId représentable
provider Yellowstone -> RawProvenanceCode représentable
endpoint logical name Yellowstone -> RawProvenanceCode représentable

Une identité non représentable est rejetée par une condition Worker stable plutôt que tronquée. Cette fermeture prépare la provenance composite de pre.004 sans modifier Store.

30. Canaris déterministes pre.003

Les nouvelles preuves couvrent :

fixture Transaction : signature/slot/index/network/route/timestamp exacts
fixture TransactionStatus : même forme sans payload ni remote error
fingerprint golden exact
fingerprint indépendant de l'ordre et des doublons de filter names
Debug du signal sans filter name, signature brute, payload ou remote error
provider/endpoint Yellowstone non représentables rejetés
adapters réels typés YellowstoneTransactionUpdate / YellowstoneTransactionStatusUpdate présents
TransactionStatus.error non consulté par l'adapter
signal absent de la façade publique
aucun open_standard_subscribe / next_update / get_transaction_observed
aucun backend Store / reqwest / tonic / proto direct ajouté

La tranche ne modifie pas le graphe Cargo du Worker au-delà de celui déjà accepté en pre.002.

31. Validation locale et non-claims pre.003

Exécuté dans l'environnement d'assemblage après les modifications Rust :

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

L'audit Markdown est rejoué après création du delta final.

cargo, rustc et rustfmt ne sont pas disponibles dans l'environnement d'assemblage ; aucun gate Cargo local n'est inventé.

pre.003 ne prétend pas avoir :

ouvert une session Yellowstone
consommé une update depuis un réseau live
appelé getTransaction
créé une RawTransactionMaterial depuis le réseau
assemblé la provenance composite Yellowstone + HTTP
persisté une transaction issue de Yellowstone
coalescé les hydrations
traité Block / BlockMeta / Slot
modifié la processing frontier
branché from_slot / ReplayInfo
exécuté un smoke live Worker

La tranche suivante reste pre.004 : fermeture déterministe signal -> get_transaction_observed -> Common RAW -> ingress avec missing/mismatch et provenance composite, sans Block ni continuité/replay.

32. Correctif pre.003-fix.001 — helpers préparatoires sans dead code

Le gate opérateur de pre.003 a confirmé que cargo check --workspace et les 45 tests Worker passaient, mais cargo clippy --workspace --all-targets --all-features -- -D warnings échouait sur huit warnings dead_code dans runtime_resources.rs.

Les éléments concernés étaient exclusivement les adapters privés préparatoires de pre.003 et leur fingerprint, encore sans consommateur productif avant pre.004 :

RAW_TRANSACTION_INGEST_YELLOWSTONE_FILTER_FINGERPRINT_DOMAIN
RawTransactionIngestSourceFamily
RawTransactionIngestSourceTimestamp
RawTransactionIngestSourceSignal
RawTransactionIngestYellowstoneSignalView
matched_filter_fingerprint
project_yellowstone_signal
impls Transaction / TransactionStatus associés

Le correctif applique directement RUST-API-008 : ces helpers strictement privés restent présents et couverts par les unit tests de pre.003, mais sont compilés sous #[cfg(test)] jusqu'à leur première consommation de production réelle en pre.004. Aucun #[allow(dead_code)] ni #[expect(dead_code)] n'est ajouté.

Le champ privé route de RawTransactionIngestYellowstoneSource reste, lui, productif : sa validation appartient déjà au contrat de construction pre.003. Il est désormais lu par le Debug sûr de la source, qui n'expose que les RawProvenanceCode déjà bornés et validés.

Le correctif ne change ni la surface publique, ni le graphe Cargo, ni le scope fonctionnel de pre.003, et n'active toujours aucun stream Yellowstone, HTTP ou Store réseau.

33. Correctif pre.003-fix.002 — canari de forme compatible avec #[cfg(test)]

Le gate opérateur de pre.003-fix.001 confirme que rustfmt, les audits, cargo check --workspace, Clippy strict et les 45 unit tests Worker passent. Le seul échec restant est le test externe v0_3_12_pre_003_private_signal_debug_and_shape_do_not_expose_signature_filters_or_payload.

Le signal privé lui-même est correct. L'échec vient du scanner source du canari : il bornait la structure avec la séquence littérale }\n\nimpl std::fmt::Debug ..., alors que pre.003-fix.001 a placé légitimement #[cfg(test)] entre la fermeture de la structure et son impl Debug afin de respecter RUST-API-008. Le scanner obtenait donc une chaîne vide et signalait created_at: comme absent.

Le correctif ne touche pas au contrat de production. Le canari recherche désormais directement le début de impl std::fmt::Debug for RawTransactionIngestSourceSignal après la déclaration de la structure. Il reste ainsi valide avec les helpers sous #[cfg(test)] et restera valide lorsque pre.004 remettra ces adapters dans le build productif.

Aucun lint n'est neutralisé, aucun helper n'est remis prématurément en production et aucune fonctionnalité de pre.004 n'est avancée.

34. Gate opérateur reçu pour pre.003-fix.002

L'opérateur a exécuté après application de pre.003-fix.002 :

cargo fmt --all : PASS visible
audit Rust : clean
Rust export completeness : 0 candidate
KSP workspace Rust rule audit : clean
audit Markdown : clean (340 tables, 805 fichiers)
cargo check --workspace : PASS visible
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS visible
cargo test -p ksp-worker-raw-transaction-ingest-lib : PASS
unit tests Worker : 45 PASS, 0 fail
dependency_boundary : 4 PASS
hardening : 10 PASS
public_api : 8 PASS
release_completeness : 3 PASS
doc-tests : 0 fail

Résultat : les deux correctifs pre.003 sont clos et 0.3.12-pre.3.fix.2 devient la base autoritaire de pre.004.

35. Gate pre.004 — hydration HTTP qualifiée et provenance composite

La tranche porte workspace.package.version = 0.3.12-pre.4 et ferme la qualification déterministe suivante :

signal Transaction / TransactionStatus
    -> signature canonique 64 bytes -> Base58 commun
    -> get_transaction_observed
       encoding = base64
       commitment = confirmed | finalized
       maxSupportedTransactionVersion = 0
    -> contrôle slot/index/signature embarquée
    -> RawTransactionMaterial source-neutral
    -> RawTransactionIngress existant

getTransaction -> null produit explicitement un résultat Missing(RawTransactionReference) et ne fabrique ni matériau RAW, ni provenance, ni ingress. Aucun retry Worker n'est ajouté autour du Transport dans cette tranche.

La common RAW reçoit format_raw_transaction_signature, encodeur Base58 borné de RawTransactionSignature 64 bytes. Le round-trip avec parse_raw_transaction_signature est qualifié sur plusieurs signatures canoniques, y compris la signature nulle représentée par 64 caractères 1. Le Worker n'embarque donc pas un second codec Base58.

Avant toute admission, la hydration vérifie :

network signal == network Worker == network source
route signal == route source
slot HTTP == slot signal
transaction_index HTTP == signal lorsqu'il est présent des deux côtés
signature extraite du wire Base64 HTTP == signature signal
transaction HTTP réellement encodée en Base64

Un mismatch devient un fault Worker sûr runtime_invalid avec condition stable hydration.*; il n'est pas délégué au Store sous forme de content conflict.

36. Provenance composite pre.004

La provenance réutilise strictement RawAcquisitionProvenance et RawProvenanceCode; aucune migration Store n'est créée.

Forme qualifiée :

protocol = yellowstone_http
provider = ys.<grpc_provider>:http.<http_provider_observé>
endpoint_id = ys.<grpc_endpoint>:http.<http_endpoint_observé>
acquisition_method = transaction_get_transaction | status_get_transaction
origin = Live
commitment = confirmed | finalized
capture_session_id = WorkerId sûr
filter_id = nom unique représentable | sha256.<fingerprint>
observed_at = created_at Yellowstone seulement s'il est représentable et <= received_at

Les identités HTTP proviennent de HttpObservedValue, donc de l'endpoint réellement gagnant après routage/retry Transport. URL, headers, token, body HTTP brut et remote error ne sont jamais copiés dans la provenance ou les diagnostics Worker.

Le constructeur de RawTransactionIngestYellowstoneSource valide désormais que chaque route HTTP compatible peut former les codes composites provider/endpoint sans dépasser les bornes Store. Une route non représentable est rejetée ; aucune troncature n'est autorisée.

37. Application de RUST-API-008 pendant pre.004

pre.004 ne crée toujours pas le source task productif : son ouverture reste réservée à pre.006. La chaîne signal/hydration n'a donc pas encore de consumer productif dans le build normal.

Conformément à RUST-API-008, les adapters privés Transaction/TransactionStatus et le helper de hydration restent sous #[cfg(test)] pendant cette tranche. Ils sont exécutés par des fixtures déterministes réelles contre le HttpTransportPool, mais aucune fonction privée morte n'est laissée dans le build normal et aucun #[allow(dead_code)]/#[expect(dead_code)] n'est utilisé.

Cela précise l'anticipation écrite dans pre.003-fix.002 selon laquelle pre.004 remettrait nécessairement ces helpers en production : la première consommation productive est en réalité celle du source task pre.006. La frontière fonctionnelle ne change pas ; seule la date d'activation de compilation productive est alignée avec la règle Rust du workspace.

pre.004 possède néanmoins deux effets productifs immédiatement valides :

API common RAW de formatage Base58
validation de représentabilité de la future provenance composite dans le constructeur de source

38. Canaris déterministes pre.004

Les nouvelles preuves couvrent :

round-trip Base58 64 bytes <-> texte canonique
requête getTransaction avec confirmed/base64/max version 0
winner HTTP observé dans provider/endpoint composites
Legacy + meta valeur + block_time valeur + index présent
V0 + meta null + block_time null + index omis
filter unique direct et multi-filter fingerprint borné
Transaction et TransactionStatus vers méthodes de provenance distinctes
created_at futur ignoré pour observed_at
getTransaction null -> Missing sans ingress et sans retry Worker
slot mismatch
index mismatch
signature wire mismatch
network mismatch avant I/O
absence de Block/getBlock/stream Yellowstone/source spawn
absence de Config/Backfill/backend/reqwest/tonic/proto direct dans le Worker

39. Validation locale et non-claims pre.004

L'environnement d'assemblage exécute les audits Python et l'audit Markdown après finalisation du delta. cargo, rustc et rustfmt n'y sont pas disponibles ; aucun résultat Cargo local n'est inventé.

pre.004 ne prétend pas avoir :

ouvert open_standard_subscribe
consommé une update réseau live
spawn un source task Yellowstone
branché Block / BlockMeta / Slot
coalescé des hydrations productives
modifié la processing frontier
branché from_slot / ReplayInfo
persisté une transaction issue d'un stream Yellowstone réel
exécuté un smoke live Worker

La tranche suivante reste pre.005 : adapters Block transactionnels et signaux continuity-only BlockMeta/Slot, toujours sans politique reconnect Worker.

40. Fix pre.004-fix.001 — gate Clippy strict

Le gate opérateur de pre.004 confirme que cargo check --workspace, les audits et les suites de tests ksp-raw-transaction-lib / ksp-worker-raw-transaction-ingest-lib passent. En revanche, cargo clippy --workspace --all-targets --all-features -- -D warnings échoue sur trois diagnostics dans la chaîne de hydration test-only :

clippy::large_enum_variant sur RawTransactionIngestHydrationOutcome
clippy::collapsible_if sur le contrôle optionnel transaction_index
clippy::collapsible_if sur le même contrôle imbriqué

Le correctif ne neutralise aucun lint. Available stocke désormais RawTransactionIngress derrière Box, ce qui réduit la taille de l'enum de résultat test-only sans modifier le contrat fonctionnel. Les deux canaris qui transfèrent ensuite l'ingress vers RawTransactionAdmission déplacent explicitement la valeur hors de la box.

Le contrôle d'index est réécrit avec une chaîne if let Rust 2024 unique : le mismatch n'est signalé que lorsque le signal possède un index, que la réponse HTTP fournit un index concret et que les deux valeurs diffèrent. La sémantique de Omitted/Null reste inchangée.

Version du workspace après correctif :

0.3.12-pre.4.fix.1

Aucune API publique, dépendance, provenance, politique retry, surface Block/continuity ou source task productive n'est modifiée.

41. Gate opérateur reçu pour pre.004-fix.001

Après application de pre.004-fix.001, l'opérateur a exécuté :

cargo fmt --all : PASS visible
audit Rust : clean
Rust export completeness : 0 candidate
KSP workspace Rust rule audit : clean
audit Markdown : clean (340 tables, 807 fichiers)
cargo check --workspace : PASS visible
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS visible
cargo test -p ksp-raw-transaction-lib : PASS
unit tests Common RAW : 17 PASS, 0 fail
integration Common RAW dependency_boundary : 2 PASS
integration Common RAW public_api : 5 PASS
integration Common RAW release_completeness : 2 PASS
integration Common RAW security_hardening : 2 PASS
cargo test -p ksp-worker-raw-transaction-ingest-lib : PASS
unit tests Worker : 52 PASS, 0 fail
dependency_boundary Worker : 5 PASS
hardening Worker : 11 PASS
public_api Worker : 8 PASS
release_completeness Worker : 3 PASS
doc-tests : 0 fail

Résultat : 0.3.12-pre.4.fix.1 devient la base autoritaire de pre.005.

42. Gate pre.005 — Block transactionnel et continuité BlockMeta/Slot

La tranche porte workspace.package.version = 0.3.12-pre.5. Elle reste sans source task productive et ferme trois adapters privés contre la façade Transport existante.

YellowstoneBlockUpdate est adapté vers zéro ou plusieurs RawTransactionIngestSourceSignal :

un signal par transaction réellement incluse dans transactions[]
ordre des signaux == ordre source
slot == slot du Block
transaction_index == index Yellowstone de la transaction
signature == signature Yellowstone 64 bytes
family = Block
filters/created_at/network/route réutilisent les mêmes règles que Transaction/Status

Aucun body/meta Yellowstone du Block n'est admis directement. Ces signaux suivent la même hydration getTransaction que les autres familles et utilisent la méthode de provenance block_get_transaction. Aucun get_block_observed n'est introduit.

YellowstoneBlockMetaUpdate et YellowstoneSlotUpdate convergent séparément vers RawTransactionIngestContinuitySignal, strictement continuity-only :

created_at
family = BlockMeta | Slot
matched_filter_count
matched_filter_fingerprint
matched_filter_id optionnel
network
parent_slot optionnel
route
slot
status optionnel

Le signal de continuité ne contient ni signature transactionnelle, ni transaction/meta/payload, ni remote error. Pour Slot, les sept états Yellowstone sont mappés vers un enum Worker privé. Le texte dead_error n'est jamais lu ni recopié. Pour BlockMeta, aucun compteur n'est interprété comme preuve de complétude transactionnelle.

43. RUST-API-008 et frontière productive pre.005

Comme pre.006 reste la première tranche qui ouvre réellement une session Yellowstone et consomme ces adapters dans le runtime normal, les nouveaux helpers Block/BlockMeta/Slot demeurent sous #[cfg(test)].

Cette décision évite simultanément :

code privé mort dans le build normal
surface publique artificielle
#[allow(dead_code)] / #[expect(dead_code)]
activation prématurée du source task

Les impls contre les DTOs Transport réels sont néanmoins compilés dans les tests. Les fixtures génériques qualifient l'ordre, les identités et la séparation RAW/continuité sans nécessiter de constructeur public supplémentaire dans Transport.

44. Canaris déterministes pre.005

Les preuves ajoutées couvrent :

Block -> N signaux dans l'ordre exact source
signature/index/slot de chaque transaction Block conservés
family Block distincte
provenance hydration Block -> block_get_transaction
BlockMeta -> continuity-only
Slot -> continuity-only
mapping exact des sept YellowstoneSlotStatus
absence de signature/transaction/meta/payload/error dans le signal continuity
absence de YellowstoneSlotUpdate::dead_error
absence de getBlock/get_block_observed
absence d'open_standard_subscribe/next_update/source spawn
absence Config/Backfill/backend/reqwest/tonic/proto direct dans le Worker

45. Non-claims pre.005

pre.005 ne prétend pas avoir :

ouvert un stream Yellowstone productif
hydraté une transaction Block reçue en live
coalescé Block + Transaction + TransactionStatus
persisté un RAW depuis une update Block live
utilisé BlockMeta ou Slot comme preuve de complétude transactionnelle
branché la processing frontier
interprété from_slot ou ReplayInfo
détecté/réparé un gap de continuité
introduit une politique reconnect Worker

La tranche suivante reste pre.006 : source task productive, session Yellowstone via Transport, hydration/admission et coalescence bornée dans le supervisor existant.

46. Gate opérateur pre.005 et fix pre.005-fix.001

Le gate opérateur de pre.005 confirme :

General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (340 tables, 808 fichiers)
cargo check --workspace: PASS

Le gate strict échoue uniquement lors de la compilation des tests Worker avant exécution :

error[E0599]: no method named `into_bytes` found for YellowstoneTransactionSignature

La façade Transport expose YellowstoneTransactionSignature::as_bytes(). Le même fichier runtime_resources.rs utilisait déjà la conversion correcte pour les updates TransactionStatus :

RawTransactionSignature::new(*update.signature().as_bytes())

pre.005-fix.001 aligne donc l'adapter Block sur ce contrat exact :

RawTransactionSignature::new(*signature.as_bytes())

Aucun changement de sémantique n'est introduit : les 64 bytes canoniques sont copiés dans le même RawTransactionSignature; ordre Block, slot, index, provenance et séparation RAW/continuité restent inchangés. Aucun nouvel export, aucune dépendance et aucun scope de pre.006 n'est ajouté.

Gate opérateur à rejouer :

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

47. Gate opérateur pre.005-fix.001

Le gate opérateur communiqué pour 0.3.12-pre.5.fix.1 est entièrement vert :

General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (340 tables, 809 fichiers)
cargo check --workspace: PASS
cargo clippy --workspace --all-targets --all-features -- -D warnings: PASS
cargo test -p ksp-worker-raw-transaction-ingest-lib: PASS
56 unit tests Worker: PASS
6 dependency-boundary tests: PASS
12 hardening tests: PASS
8 public-api tests: PASS
3 release-completeness tests: PASS
Doc-tests: PASS

Cette base ferme donc pre.005 et son fix de conversion YellowstoneTransactionSignature::as_bytes() avant ouverture de la source productive.

48. pre.006 — source Yellowstone productive

start_with_runtime_resources ne délègue plus au foundation sans source. Après les validations synchrones Store/settings/runtime-resources déjà qualifiées, il :

consomme RawTransactionIngestRuntimeResources
extrait exactement une RawTransactionIngestYellowstoneSource
clone les settings nécessaires au child privé
spawn exactement un child dans le SourceTasks JoinSet existant
laisse le supervisor 0.3.11 posséder stop/drain/fault

Le child ouvre la session uniquement via :

YellowstoneGrpcChannel::open_standard_subscribe
SolanaYellowstoneGrpcSubscribeSession::next_update
SolanaYellowstoneGrpcSubscribeSession::close

Le Worker ne crée aucun tonic::Channel, client Geyser, client Reqwest ou actor gRPC parallèle. Transport reste propriétaire des metadata, credentials, ping/pong, message-size bounds et reconnect interne.

Le stop privé est prioritaire pendant l'ouverture, pendant la lecture de stream et pendant l'envoi vers l'admission. Un stop avant ouverture abandonne le futur d'ouverture sans session orpheline. À la sortie, les hydrations privées sont abort/join puis la session Transport est fermée via son close borné.

49. Routage productif des updates

Le dispatch productif est désormais :

Transaction       -> 1 RawTransactionIngestSourceSignal -> hydration
TransactionStatus -> 1 RawTransactionIngestSourceSignal -> hydration
Block             -> N RawTransactionIngestSourceSignal dans l'ordre source -> hydration
BlockMeta         -> RawTransactionIngestContinuitySignal continuity-only
Slot              -> RawTransactionIngestContinuitySignal continuity-only
Account/Entry/Ping/Pong -> aucun RAW Worker

BlockMeta et Slot restent délibérément sans admission RAW. dead_error et TransactionStatus.error ne sont pas lus. Aucun getBlock/get_block_observed n'est ajouté.

Les adapters pre.003-pre.005, précédemment gardés sous #[cfg(test)] faute de consumer productif, sont maintenant compilés dans le build normal. Le wrapper fixture hydrate_yellowstone_signal reste test-only ; la production utilise les deux étapes séparées fetch_yellowstone_hydration puis finalize_yellowstone_hydration.

50. Coalescence bornée d'hydration

La clé privée est exactement :

network
signature
commitment

Elle ne contient ni family ni filter. Ainsi Transaction, TransactionStatus et Block portant la même signature/network/commitment partagent au plus un getTransaction in-flight.

Le coordinator privé conserve :

BTreeMap<HydrationKey, PendingHydration>
JoinSet<HydrationFetch>
max_in_flight = persistence_concurrency validée
max_pending_signals = MAX_RAW_TRANSACTION_INGEST_ADMISSION_QUEUE_CAPACITY

Le nombre de tâches HTTP simultanées est donc borné par le réglage existant de concurrence, sans nouveau knob public. Le nombre de signaux coalescés/pending reste borné par la borne maximale déjà publiée du Worker. Quand cette borne est atteinte, la lecture Yellowstone est backpressurée ; un dépassement à l'intérieur d'une update composite produit un fault source sûr au lieu d'un drop silencieux.

À la complétion d'un unique fetch HTTP, chaque signal coalescé est finalisé séparément. Le fan-out reconstruit donc sa propre provenance :

transaction_get_transaction
status_get_transaction
block_get_transaction
filter_id direct ou fingerprint propre au signal
observed_at propre au signal quand représentable

Store idempotence reste ensuite la seconde barrière. Aucun cache de déduplication terminé/non borné n'est conservé.

51. Hydration productive et admission

Le fetch utilise toujours le contrat pre.004 :

get_transaction_observed
encoding = base64
commitment = confirmed | finalized de la source
maxSupportedTransactionVersion = 0

Le résultat observé est partagé uniquement entre les signaux ayant la même clé. Chaque finalisation réapplique avant admission :

network cohérent
route Yellowstone cohérente
slot HTTP == slot signal
transaction_index cohérent lorsqu'il est présent des deux côtés
signature embarquée == signature signal
provenance composite sûre depuis le winner HTTP réel

null reste Missing : aucun ingress n'est créé. Une erreur Transport est réduite à son ErrorCode KSP sûr. Aucun texte distant n'entre dans l'erreur Worker.

Les ingresses disponibles sont envoyés uniquement via le tokio::sync::mpsc::Sender<RawTransactionIngress> déjà créé par RawTransactionAdmission::new. Aucun second canal d'admission ou chemin Store n'est introduit.

52. Canaris pre.006

Les nouveaux canaris vérifient au minimum :

start_with_runtime_resources -> source.run -> children.spawn
open_standard_subscribe/next_update/close présents uniquement via la façade Transport
get_transaction_observed reste l'unique hydration HTTP
aucun get_block_observed
aucun Config/Backfill/backend/reqwest/tonic/proto direct
coalescence key = network/signature/commitment
Transaction + Status de même signature -> une seule entrée pending et une seule tâche HTTP in-flight
signature différente -> clé différente
pending et in-flight bornés
stop preemptible pendant admission
abort_all + join des hydrations privées
aucun remote error/dead_error/secret dans la source productive
public root inchangé
module inventory inchangé

53. Non-claims pre.006

pre.006 ne prétend pas encore :

maintenir une processing frontier
interpréter le snapshot reconnect Transport
modifier from_slot au niveau Worker
interpréter SubscribeReplayInfo
prouver une continuité blockchain
fault sur gap de rétention prouvé
faire un repair/backfill implicite
qualifier les races duplicate storm/Store lent finales de pre.009
réussir un smoke provider live sans credentials opérateur

Ces responsabilités restent respectivement pre.007, pre.008, pre.009 et pre.011 conformément au plan.

54. Gate opérateur requis pour pre.006

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
cargo tree --duplicates

Dans l'environnement d'assemblage, cargo, rustc et rustfmt ne sont pas installés ; aucun gate Cargo local n'est donc revendiqué.

55. Gate opérateur pre.006 et pre.006-fix.001

Le gate opérateur de pre.006 confirme :

General Rust rule audit : clean
Rust export completeness audit : 0 candidate(s)
KSP workspace Rust rule audit : clean
Markdown table audit : clean (340 tables, 810 fichiers)
cargo check --workspace : PASS
cargo test -p ksp-worker-raw-transaction-ingest-lib : 57 PASS / 1 FAIL

Le gate Clippy strict échoue uniquement sur trois clippy::implicit-return dans le nouveau chemin productif : la branche neutre du routage Yellowstone et les deux branches de la closure find_map qui sélectionne la prochaine hydration non lancée.

Le test rouge est pre_004_source_hydration_rejects_slot_index_signature_and_network_mismatch_before_admission. La cause n'est pas le test : depuis pre.006, le helper de qualification construit la clé et lance le fetch avant d'atteindre le guard réseau de finalize_yellowstone_hydration, ce qui transforme le contexte attendu hydration.network_mismatch en hydration.network_key_mismatch.

pre.006-fix.001 restaure l'invariant plus fort : hydration_key rejette immédiatement tout signal.network != source.network avec hydration.network_mismatch, donc avant coalescence et avant tout HTTP. Le guard de finalisation reste en place comme défense secondaire.

Les trois retours implicites sont rendus explicites sans lint neutralisé. La logique de coalescence, les bornes, le fan-out, les provenances et le contrat de stop ne changent pas.

56. Gate requis après pre.006-fix.001

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