v0.3.14-pre.002-fix.002

This commit is contained in:
2026-09-11 20:55:53 +02:00
parent 5932250314
commit 7bf938c19f
7 changed files with 261 additions and 50 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 568
# version: 569
[workspace]
resolver = "3"
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
[workspace.package]
version = "0.3.14-pre.2.fix.1"
version = "0.3.14-pre.2.fix.2"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,16 +1,16 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
// version: 2
// version: 3
/// Maximum number of simultaneously retained non-repaired run-local gaps.
pub(crate) const MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS: usize = 64;
const MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS: usize = 64;
/// Maximum number of run-local gaps that may actively repair at once.
pub(crate) const MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS: usize = 1;
const MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS: usize = 1;
/// Maximum number of logical block fetches that a later repair scheduler may admit concurrently.
pub(crate) const MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT: usize = 4;
const MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT: usize = 4;
/// Maximum number of slots admitted by one later HTTP repair discovery window.
pub(crate) const MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS: u64 = 512;
const MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS: u64 = 512;
/// Maximum inclusive slot span admitted for one run-local repair gap.
pub(crate) const MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS: u64 = 4_096;
const MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS: u64 = 4_096;
/// Private source scope used to prove whether one configured live source can cover another run-local requirement.
#[derive(Clone, Debug, Eq, PartialEq)]
@@ -107,7 +107,7 @@ impl RawTransactionIngestGapRange {
std::option::Option::Some(value) => value,
std::option::Option::None => return std::result::Result::Err(crate::runtime_error("continuity.gap_range_overflow")),
};
if slot_count > crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS {
if slot_count > MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS {
return std::result::Result::Err(crate::runtime_error("continuity.gap_range_too_large"));
}
return std::result::Result::Ok(Self { end_slot, start_slot });
@@ -143,7 +143,7 @@ impl RawTransactionIngestGapRange {
std::option::Option::Some(value) => value,
std::option::Option::None => return std::result::Result::Ok(std::option::Option::None),
};
if slot_count > crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS {
if slot_count > MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS {
return std::result::Result::Ok(std::option::Option::None);
}
return std::result::Result::Ok(std::option::Option::Some(Self { end_slot, start_slot }));
@@ -211,10 +211,10 @@ impl RawTransactionIngestGapLedger {
return std::result::Result::Err(error);
}
}
if open_gap_count > crate::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS {
if open_gap_count > MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS {
return std::result::Result::Err(crate::runtime_error("continuity.open_gap_limit_exceeded"));
}
if active_gap_count > crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS {
if active_gap_count > MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS {
return std::result::Result::Err(crate::runtime_error("continuity.active_gap_limit_exceeded"));
}
if !self.gaps.is_empty() && self.next_gap_id <= highest_gap_id {
@@ -250,7 +250,7 @@ impl RawTransactionIngestGapLedger {
}
/// Private source capability descriptor prepared without network I/O from already validated runtime resources.
pub(crate) struct RawTransactionIngestRepairCapabilityDescriptor {
pub(crate) struct RawTransactionIngestContinuityCapabilityDescriptor {
block_material: bool,
commitment: ksp_onchain_transport_lib::SolanaCommitment,
http_block_scan: bool,
@@ -263,7 +263,7 @@ pub(crate) struct RawTransactionIngestRepairCapabilityDescriptor {
source_scope: crate::RawTransactionIngestCoverageScope,
}
impl crate::RawTransactionIngestRepairCapabilityDescriptor {
impl crate::RawTransactionIngestContinuityCapabilityDescriptor {
/// Creates one private descriptor from source-local capabilities that were validated without issuing repair I/O.
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
@@ -324,7 +324,7 @@ struct RawTransactionIngestTargetCoverage {
}
impl RawTransactionIngestTargetCoverage {
fn from_capabilities(capabilities: &[crate::RawTransactionIngestRepairCapabilityDescriptor]) -> ksp_core_lib::Result<Self> {
fn from_capabilities(capabilities: &[crate::RawTransactionIngestContinuityCapabilityDescriptor]) -> ksp_core_lib::Result<Self> {
let mut value = Self { requirements: std::vec::Vec::new() };
for capability in capabilities {
if let std::result::Result::Err(error) = value.include(capability.commitment, capability.source_scope.clone()) {
@@ -363,14 +363,14 @@ impl RawTransactionIngestTargetCoverage {
/// Run-local continuity contracts prepared from the exact caller-composed live-source aggregate before productive source execution.
pub(crate) struct RawTransactionIngestContinuityContracts {
capabilities: std::vec::Vec<crate::RawTransactionIngestRepairCapabilityDescriptor>,
capabilities: std::vec::Vec<crate::RawTransactionIngestContinuityCapabilityDescriptor>,
gap_ledger: RawTransactionIngestGapLedger,
target_coverage: RawTransactionIngestTargetCoverage,
}
impl crate::RawTransactionIngestContinuityContracts {
/// Builds the private capability inventory, conservative `TargetCoverage` and empty run-local gap ledger without issuing network or Store I/O.
pub(crate) fn new(capabilities: std::vec::Vec<crate::RawTransactionIngestRepairCapabilityDescriptor>) -> ksp_core_lib::Result<Self> {
pub(crate) fn new(capabilities: std::vec::Vec<crate::RawTransactionIngestContinuityCapabilityDescriptor>) -> ksp_core_lib::Result<Self> {
if capabilities.is_empty() || capabilities.len() > crate::MAX_RAW_TRANSACTION_INGEST_LIVE_SOURCES {
return std::result::Result::Err(crate::runtime_error("continuity.capability_inventory_size_invalid"));
}
@@ -398,9 +398,9 @@ impl crate::RawTransactionIngestContinuityContracts {
if !coverage_scope_catalog_is_complete() {
return std::result::Result::Err(crate::runtime_error("continuity.coverage_scope_catalog_invalid"));
}
if crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT == 0
|| crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS == 0
|| crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS > crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS
if MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT == 0
|| MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS == 0
|| MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS > MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS
{
return std::result::Result::Err(crate::runtime_error("continuity.repair_bounds_invalid"));
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/lib.rs
// version: 27
// version: 28
#![warn(missing_docs)]
#![deny(unreachable_pub)]
@@ -111,22 +111,12 @@ pub use self::snapshot::RawTransactionIngestSourceState;
pub(crate) use self::admission::RawTransactionAdmission;
/// Crate-private source-neutral ingress sent through the bounded central admission queue.
pub(crate) use self::admission::RawTransactionIngress;
/// Maximum number of simultaneously retained non-repaired run-local continuity gaps.
pub(crate) use self::continuity::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS;
/// Maximum number of run-local continuity gaps that may actively repair at once.
pub(crate) use self::continuity::MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS;
/// Maximum number of logical block fetches reserved for the later bounded repair scheduler.
pub(crate) use self::continuity::MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT;
/// Maximum number of slots reserved for one later HTTP repair discovery window.
pub(crate) use self::continuity::MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS;
/// Maximum inclusive slot span accepted by one run-local repair gap.
pub(crate) use self::continuity::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS;
/// Private source continuity-capability descriptor prepared without network or Store I/O.
pub(crate) use self::continuity::RawTransactionIngestContinuityCapabilityDescriptor;
/// Private run-local continuity aggregate containing capabilities, TargetCoverage and the gap ledger.
pub(crate) use self::continuity::RawTransactionIngestContinuityContracts;
/// Private provider-neutral coverage scope used by run-local continuity proof contracts.
pub(crate) use self::continuity::RawTransactionIngestCoverageScope;
/// Private source capability descriptor prepared without repair I/O.
pub(crate) use self::continuity::RawTransactionIngestRepairCapabilityDescriptor;
/// Creates one terminal content-conflict error without copying conflicting material into diagnostics.
pub(crate) use self::error::content_conflict_error;
/// Creates one terminal counter-exhaustion error without exposing runtime material.

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
// version: 28
// version: 29
use sha2::Digest; // rust-rules: trait-import
@@ -76,7 +76,7 @@ impl RawTransactionIngestLiveSource {
};
}
fn repair_capability_descriptor(&self) -> ksp_core_lib::Result<crate::RawTransactionIngestRepairCapabilityDescriptor> {
fn repair_capability_descriptor(&self) -> ksp_core_lib::Result<crate::RawTransactionIngestContinuityCapabilityDescriptor> {
let commitment = match self {
Self::HeliusTransaction(source) => source.commitment,
Self::HttpBlockPolling(source) => source.commitment,
@@ -142,7 +142,7 @@ impl RawTransactionIngestLiveSource {
};
let block_material = live_block_material || http_block_scan;
let slot_enumerating = http_block_scan;
return crate::RawTransactionIngestRepairCapabilityDescriptor::new(
return crate::RawTransactionIngestContinuityCapabilityDescriptor::new(
self.source_key(),
self.network().clone(),
commitment,

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
// version: 25
// version: 26
//! External public, security, redaction and release-boundary hardening canaries through `v0.3.14-pre.002`.
@@ -974,7 +974,7 @@ fn v0_3_14_pre_002_continuity_contracts_are_private_bounded_and_io_free() {
"KnownReferences",
"RawTransactionIngestGapLedger",
"RawTransactionIngestTargetCoverage",
"RawTransactionIngestRepairCapabilityDescriptor",
"RawTransactionIngestContinuityCapabilityDescriptor",
"RawTransactionIngestContinuityContracts",
"continuity.known_references_not_target_scope",
"continuity.coalescible_gap_ranges",
@@ -1008,6 +1008,7 @@ fn v0_3_14_pre_002_continuity_contracts_are_private_bounded_and_io_free() {
assert!(!continuity.contains(forbidden), "pre.002 continuity contract performed or imported forbidden I/O/boundary: {forbidden}");
}
assert!(!root.contains("pub use self::continuity::"));
assert!(!root.contains("repair"), "pre.002 private continuity wiring leaked repair responsibility through crate root");
assert!(root.contains("pub(crate) use self::continuity::RawTransactionIngestContinuityContracts;"));
return;
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs
// version: 1
// version: 2
fn network() -> std::option::Option<ksp_store_lib::RawNetworkId> {
return match ksp_store_lib::RawNetworkId::new("mainnet") {
@@ -16,12 +16,12 @@ fn capability(
source_key_byte: u8,
commitment: ksp_onchain_transport_lib::SolanaCommitment,
scope: crate::RawTransactionIngestCoverageScope,
) -> std::option::Option<crate::RawTransactionIngestRepairCapabilityDescriptor> {
) -> std::option::Option<crate::RawTransactionIngestContinuityCapabilityDescriptor> {
let network = match network() {
std::option::Option::Some(value) => value,
std::option::Option::None => return std::option::Option::None,
};
return match crate::RawTransactionIngestRepairCapabilityDescriptor::new(
return match crate::RawTransactionIngestContinuityCapabilityDescriptor::new(
[source_key_byte; 32],
network,
commitment,
@@ -67,19 +67,19 @@ fn gap(
#[test]
fn pre_002_repair_bounds_are_exact_and_run_local() {
assert_eq!(crate::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS, 64);
assert_eq!(crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS, 1);
assert_eq!(crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT, 4);
assert_eq!(crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS, 512);
assert_eq!(crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS, 4_096);
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS, 64);
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS, 1);
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT, 4);
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS, 512);
assert_eq!(super::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS, 4_096);
return;
}
#[test]
fn pre_002_gap_range_is_inclusive_bounded_and_overflow_safe() {
assert!(super::RawTransactionIngestGapRange::new(10, 9).is_err());
assert!(super::RawTransactionIngestGapRange::new(10, 10 + crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS - 1).is_ok());
assert!(super::RawTransactionIngestGapRange::new(10, 10 + crate::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS).is_err());
assert!(super::RawTransactionIngestGapRange::new(10, 10 + super::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS - 1).is_ok());
assert!(super::RawTransactionIngestGapRange::new(10, 10 + super::MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS).is_err());
assert!(super::RawTransactionIngestGapRange::new(u64::MAX, u64::MAX).is_ok());
return;
}
@@ -168,7 +168,7 @@ fn pre_002_known_references_can_never_be_configured_target_coverage() {
std::option::Option::Some(value) => value,
std::option::Option::None => panic!("network fixture unavailable"),
};
let result = crate::RawTransactionIngestRepairCapabilityDescriptor::new(
let result = crate::RawTransactionIngestContinuityCapabilityDescriptor::new(
[1_u8; 32],
network,
ksp_onchain_transport_lib::SolanaCommitment::Confirmed,
@@ -220,7 +220,7 @@ fn pre_002_gap_ledger_enforces_open_gap_bound_and_next_id_monotonicity() {
std::option::Option::None => panic!("network fixture unavailable"),
};
let mut gaps = std::vec::Vec::new();
for index in 0..=crate::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS {
for index in 0..=super::MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS {
let gap_id = (index as u64) + 1;
let slot = (index as u64) * 2;
let gap = match gap(gap_id, 1, slot, slot, super::RawTransactionIngestGapState::Pending) {

View File

@@ -0,0 +1,220 @@
<!-- file: deltas/0.3.14/pre.002-fix.002.md -->
<!-- version: 1 -->
# Delta `0.3.14-pre.002-fix.002` — correction façade crate-root continuity
## Base requise
```text
0.3.14-pre.002-fix.001
workspace.package.version = 0.3.14-pre.2.fix.1
deltas/0.3.14/pre.002-fix.001.md présent
```
## Objectif
Corriger strictement la tranche `pre.002` après le second gate opérateur, sans étendre son périmètre fonctionnel :
```text
préserver le canari historique pre.007 interdisant le vocabulaire repair dans la crate-root
conserver les contrats continuity/gap de pre.002 entièrement privés
ne réexporter au crate-root que les éléments pub(crate) réellement partagés entre modules
conserver pre.002 sans repair I/O
```
## Défaut observé
Le gate opérateur sur `0.3.14-pre.2.fix.1` a produit :
```text
cargo fmt --all : PASS
cargo fmt --all -- --check : PASS
audit Rust workspace rules : PASS
audit Markdown tables : PASS
cargo check --workspace : PASS
cargo clippy --workspace --all-targets --all-features -- -D warnings : PASS
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features : FAIL
```
Les `114` unit tests passaient, ainsi que les suites `cross_layer_completeness`, `dependency_boundary` et `hardening` exécutées avant l'échec.
Échec :
```text
v0_3_12_pre_007_processing_frontier_snapshot_getters_are_public_and_processing_only : FAIL
pre.007 public root overclaims continuity/replay: repair
```
Le test historique vérifie directement `src/lib.rs` et interdit les tokens suivants :
```text
ReplayInfo
from_slot
repair
backfill
```
## Cause
`pre.002` avait correctement gardé ses nouveaux contrats en `pub(crate)`, mais avait réexporté au crate-root plusieurs bornes internes nommées `*_REPAIR_*` ainsi que `RawTransactionIngestRepairCapabilityDescriptor`.
Ces éléments n'étaient pas publics hors crate, mais leur présence textuelle dans `src/lib.rs` violait malgré tout le contrat historique `pre.007` : la façade crate-root ne doit pas revendiquer une responsabilité de replay/repair.
Cinq bornes étaient en outre utilisées uniquement dans `continuity.rs` et son module de unit tests ; elles n'avaient donc pas besoin d'être `pub(crate)` ni réexportées.
## Correction
### Bornes de continuity
Les cinq bornes restent inchangées en valeur et en sémantique, mais deviennent strictement privées au module `continuity` :
```text
MAX_RAW_TRANSACTION_INGEST_OPEN_REPAIR_GAPS = 64
MAX_RAW_TRANSACTION_INGEST_REPAIR_ACTIVE_GAPS = 1
MAX_RAW_TRANSACTION_INGEST_REPAIR_BLOCK_FETCH_IN_FLIGHT = 4
MAX_RAW_TRANSACTION_INGEST_REPAIR_DISCOVERY_WINDOW_SLOTS = 512
MAX_RAW_TRANSACTION_INGEST_REPAIR_RANGE_SLOTS = 4096
```
Leurs réexports `pub(crate)` sont supprimés de `src/lib.rs`.
Les unit tests rattachés au module parent y accèdent maintenant via `super::...`, conformément à la règle de visibilité des éléments strictement privés.
### Capability descriptor partagé
Le seul descriptor réellement partagé entre `continuity.rs` et `runtime_resources.rs` reste `pub(crate)` et réexporté au crate-root, mais sous un nom source-neutre :
```text
RawTransactionIngestRepairCapabilityDescriptor
-> RawTransactionIngestContinuityCapabilityDescriptor
```
Sa structure, ses validations et ses données ne changent pas.
Le helper privé `repair_capability_descriptor` de `runtime_resources.rs` n'est pas une façade crate-root et conserve son rôle actuel ; aucun repair I/O n'est ajouté.
### Canari de non-régression
Le test historique `tests/public_api.rs` n'est ni modifié ni assoupli.
Le canari `v0_3_14_pre_002_continuity_contracts_are_private_bounded_and_io_free` est renforcé afin d'exiger lui aussi :
```text
src/lib.rs ne contient pas "repair"
```
## Fichiers ajoutés
```text
deltas/0.3.14/pre.002-fix.002.md
```
## Fichiers modifiés
```text
Cargo.toml
crates/ksp-worker-raw-transaction-ingest-lib/src/lib.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/continuity.rs
crates/ksp-worker-raw-transaction-ingest-lib/src/runtime_resources.rs
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/continuity.rs
crates/ksp-worker-raw-transaction-ingest-lib/tests/hardening.rs
```
## Fichiers supprimés
```text
aucun
```
## Version Cargo
Le fix modifie du code Rust ; conformément à `VER-ID-007` et `VER-ID-010` :
```text
header Cargo.toml : 568 -> 569
workspace.package.version : 0.3.14-pre.2.fix.1 -> 0.3.14-pre.2.fix.2
```
Versions de fichiers :
```text
src/lib.rs : 27 -> 28
src/continuity.rs : 2 -> 3
src/runtime_resources.rs : 28 -> 29
unit_tests/continuity.rs : 1 -> 2
tests/hardening.rs : 25 -> 26
```
## Frontières préservées
```text
aucun repair I/O
aucune nouvelle tâche
aucune nouvelle socket
aucun retry Worker
aucune nouvelle dépendance
aucune nouvelle feature
aucun accès Config depuis Worker
aucun accès Job Backfill depuis Worker
aucun backend Store physique depuis Worker
aucune mutation Worker de Yellowstone from_slot
aucun nouveau symbole public
crate-root toujours exempte de ReplayInfo/from_slot/repair/backfill
```
## Validations exécutées
Dans le sandbox de préparation :
```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
scan exact des tokens ReplayInfo/from_slot/repair/backfill dans src/lib.rs
scan des références vers l'ancien RawTransactionIngestRepairCapabilityDescriptor
scan des références des bornes privées de continuity
comparaison exacte pre.002-fix.001 -> pre.002-fix.002
contrôle contenu archive delta
unzip -t archive delta
```
## Validations non exécutées
Le sandbox de préparation ne fournit pas le toolchain Cargo/Rust. Les gates suivants restent à exécuter côté opérateur :
```text
cargo fmt --all
cargo fmt --all -- --check
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test -p ksp-worker-raw-transaction-ingest-lib --all-targets --all-features
```
Le test historique `v0_3_12_pre_007_processing_frontier_snapshot_getters_are_public_and_processing_only` n'est pas modifié.
## Décisions prises
```text
fix strict de pre.002, sans nouvelle responsabilité fonctionnelle
les bornes non partagées restent privées à continuity.rs
seuls les éléments réellement partagés sont pub(crate) et réexportés au crate-root
le descriptor partagé porte une identité continuity source-neutre
aucun contournement du canari historique n'est accepté
```
## Questions ouvertes
```text
aucune pour ce fix
```
## Gate opérateur après application
```bash
cargo fmt --all
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 --all-targets --all-features
```