# Delta `0.3.12-pre.008` — reconnect / replay / gap de rétention prouvé ## Base requise ```text 0.3.12-pre.007-fix.002 workspace.package.version = 0.3.12-pre.7.fix.2 ``` Le gate opérateur communiqué pour cette base est entièrement vert : audits Rust/Markdown, `cargo check --workspace`, Clippy strict, 61 tests unitaires Worker, 8 `dependency_boundary`, 14 `hardening`, 9 `public_api`, 3 `release_completeness` et doc-tests sans échec. ## Objectif Brancher la continuité Yellowstone déjà possédée par Transport dans le Worker sans dupliquer la politique de replay : ```text Transport reconnect snapshot -> Worker source-neutral latest-value projection -> reconnect/replay/gap observability -> proven retention gap => source fault ``` Le Worker ne calcule ni `from_slot`, ni `SubscribeReplayInfo.first_available`; il ne déclenche aucun repair historique. ## Version ```text workspace.package.version = 0.3.12-pre.8 ``` ## Façade Transport ajoutée `ksp-onchain-transport-lib` expose désormais : ```text YellowstoneGrpcSubscribeSnapshotSource SolanaYellowstoneGrpcSubscribeSession::snapshot_source() YellowstoneGrpcSubscribeSnapshotSource::current() YellowstoneGrpcSubscribeSnapshotSource::wait_for_change() ``` Cette façade encapsule le `tokio::sync::watch::Receiver` déjà possédé par la session. Elle n'expose ni Tonic, ni protobuf upstream, ni actor interne, ni credentials. Le snapshot Transport reste la source autoritaire pour : ```text state reconnect_count replay_attempt_count continuity_gap_count ``` La sélection/clamp de `from_slot` et l'appel `SubscribeReplayInfo` restent exclusivement dans Transport. ## Projection Worker Le snapshot Worker ajoute le type public source-neutral : ```text RawTransactionIngestSourceState Active Reconnecting Closing Closed Failed ``` et les getters : ```text source_state() source_reconnect_total() source_replay_attempt_total() source_continuity_gap_total() ``` La même watch privée que la processing frontier transporte ces latest-values ; aucune nouvelle watch Worker n'est ajoutée. Les champs processing-only `hydration_pending`, `processing_frontier_slot` et `oldest_pending_slot` restent inchangés et sont conservés pendant reconnect. ## Politique reconnect/replay Le source task : ```text ouvre la session Yellowstone via Transport obtient snapshot_source() publie le snapshot initial Active observe les changements Transport en parallèle de next_update et des hydrations continue les hydrations déjà en vol pendant Reconnecting laisse le stop préempter reconnect/hydration/admission ``` `replay_attempt_count` et `reconnect_count` restent distincts. Un replay attempt peut être observé alors qu'aucun reconnect n'a encore réussi. ## Gap de rétention prouvé Le Worker ne fault que si `continuity_gap_count` augmente. Transport incrémente ce compteur uniquement lorsqu'il prouve : ```text SubscribeReplayInfo.first_available > requested replay slot ``` La hausse est publiée dans le snapshot Worker, puis le source task retourne `source.continuity_gap_proven`; le supervisor classe ensuite le terminal en `ERROR_CODE_RAW_TRANSACTION_INGEST_SOURCE_FAILED`. Cette preuve reste conservatrice : elle prouve une couverture de replay demandée devenue indisponible, pas l'existence certaine d'un update filtré perdu. Les compteurs Transport observés doivent être monotones ; une régression impossible est rejetée avec `source.continuity_counter_regression`. ## Non-claims `pre.008` n'ajoute pas : ```text repair/backfill automatique source secondaire ou failover multi-provider checkpoint durable inter-process getBlock de repair retry Worker spécifique getTransaction null exactly-once preuve de continuité blockchain globale ownership Worker de from_slot ownership Worker de SubscribeReplayInfo ``` ## Fichiers modifiés ```text Cargo.toml crates/ksp-onchain-transport-lib/src/grpc_stream.rs crates/ksp-onchain-transport-lib/src/lib.rs crates/ksp-onchain-transport-lib/tests/public_api.rs crates/ksp-onchain-transport-lib/tests/release_completeness.rs crates/ksp-onchain-transport-lib/unit_tests/grpc_stream.rs crates/ksp-worker-raw-transaction-ingest-lib/src/lib.rs crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs crates/ksp-worker-raw-transaction-ingest-lib/src/snapshot.rs crates/ksp-worker-raw-transaction-ingest-lib/tests/dependency_boundary.rs crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs crates/ksp-worker-raw-transaction-ingest-lib/tests/public_api.rs crates/ksp-worker-raw-transaction-ingest-lib/tests/release_completeness.rs crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/runtime_resources.rs crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/snapshot.rs docs/validation/029-V0_3_12_YELLOWSTONE_HYDRATION_CONTINUITY.md ``` ## Fichier ajouté ```text deltas/0.3.12/pre.008.md ``` ## Fichiers supprimés ```text aucun ``` ## Validations exécutées dans l'environnement d'assemblage ```text 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 canaris statiques pre.008 replay/frontier/redaction/public API contrôle des versions de fichiers modifiés contrôle diff exact contre pre.007-fix.002 unzip -t du delta final reproduction du delta sur la base exacte ``` `cargo`, `rustc` et `rustfmt` ne sont pas installés dans l'environnement d'assemblage. Aucun `cargo check`, Clippy ou test Cargo local n'est déclaré PASS ici. ## Gate opérateur requis ```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-onchain-transport-lib 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 ``` ## Décisions durables ```text Transport reste propriétaire de reconnect/from_slot/ReplayInfo. Worker observe les résultats sûrs, il ne réimplémente pas la stratégie Transport. reconnect != replay attempt != successful reconnect != proven retention gap. proven retention gap => fault/stop, jamais repair implicite dans 0.3.12. processing frontier reste run-local et processing-only. ``` ## Suite `pre.009` reste consacré au hardening races/retry/backpressure : stop pendant hydration/reconnect, duplicate storm, Store lent, source failure, counter exhaustion et no-orphan, sans élargissement fonctionnel.