v0.3.15-pre.006-fix.003

This commit is contained in:
2026-09-13 17:11:21 +02:00
parent f12e67bdc7
commit 487bcbf0c1
10 changed files with 101 additions and 33 deletions

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml
# version: 604
# version: 605
[workspace]
resolver = "3"
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-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.15-pre.6.fix.2"
version = "0.3.15-pre.6.fix.3"
edition = "2024"
license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-raw-transaction-ingest-desk/README.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# `ksp-app-raw-transaction-ingest-desk`
@@ -28,6 +28,7 @@ Worker -> acquisition continue et lifecycle d'exécution
L'inventaire de routes est calculé côté Rust à partir du composite Config validé et des settings Transport/Store résolus. Il ne lance aucun probe réseau et n'ouvre ni Store ni Worker.
Les profils applicatifs sont réseau-centriques (`devnet`, `mainnet`, `testnet`). Un profil peut agréger plusieurs profils Transport du même réseau : le provider reste une source de capability et ne devient jamais une identité réseau ni un choix de profil applicatif.
Une route explicitement liée à un provider nest projetée pour un réseau que si le composite déclare une source Transport de ce provider. Ainsi, la route Helius Transaction existe sur Devnet/Mainnet mais nest pas présentée sur Testnet tant quHelius ne fournit pas de source Testnet configurée.
Le frontend ne reçoit aucune URL, credential, URI Store, metadata secrète, source key, handle runtime ou payload `RawTransaction`.

View File

@@ -1,5 +1,5 @@
<!-- file: crates/ksp-app-raw-transaction-ingest-desk/USAGE.md -->
<!-- version: 4 -->
<!-- version: 5 -->
# Utilisation de `ksp-app-raw-transaction-ingest-desk`
@@ -32,6 +32,7 @@ génération d'inventaire
`Configured` signifie uniquement que toutes les requirements Config nécessaires à la route sont cohérentes. Les profils `solana-public` standard committés déclarent explicitement les capabilities `Logs` et `Block`; `standard-block-direct` est donc Configured sur les trois réseaux logiques tant que ce socle Config reste valide. Aucun probe réseau, aucune ouverture de Store et aucun Worker ne sont déclenchés par l'inventaire.
Un refresh reconstruit l'inventaire depuis Config et publie une nouvelle génération. La sélection visuelle d'un réseau ne choisit aucune URL, provider ou ressource physique et ne démarre aucune acquisition. Une capability optionnelle dont le secret n'est pas résolu rend uniquement la route qui en dépend indisponible ; les routes satisfaites par le Transport de base du même réseau restent composables.
Une route provider-specific dont aucune source nest déclarée pour le réseau nest pas une erreur de configuration : elle est hors inventaire pour ce réseau. Par exemple, Helius Transaction est projetée sur Devnet/Mainnet lorsque `transport.helius` existe, mais pas sur Testnet lorsquaucune source Helius Testnet nest déclarée.
Les URLs, tokens, metadata secrètes, handles Transport/Store/Worker, URI Store, source keys et payloads RAW restent backend-only.

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-raw-transaction-ingest-desk/src/dto_route.rs
// version: 2
// version: 3
//! Safe route-identity, Config-composability and lifecycle DTOs for Raw Transaction Ingest Desk.
@@ -206,7 +206,7 @@ pub(crate) struct RawIngestProfileInventoryDto {
pub(crate) network: std::option::Option<String>,
/// Stable composite profile identifier.
pub(crate) profile_id: String,
/// Five logical routes in stable V1 presentation order.
/// Logical routes applicable to this network profile in stable V1 presentation order; provider-specific routes may be absent when their Config source is not declared.
pub(crate) routes: std::vec::Vec<crate::RawIngestRouteDto>,
}

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-raw-transaction-ingest-desk/src/route_inventory.rs
// version: 2
// version: 3
//! Config-only logical route inventory for Raw Transaction Ingest Desk.
@@ -16,6 +16,7 @@ struct RouteCapabilities {
has_standard_logs: bool,
has_standard_block: bool,
has_helius_transaction: bool,
helius_source_declared: bool,
helius_source_missing_secret: bool,
yellowstone_source_missing_secret: bool,
}
@@ -199,6 +200,9 @@ fn build_profile_inventory(
crate::RawIngestRouteUnavailableReason::ProfileUnresolved,
);
}
if component_id == crate::COMPOSITE_COMPONENT_ID_TRANSPORT_HELIUS {
capabilities.helius_source_declared = true;
}
if component.resolved().file_id().as_str() != ksp_config_lib::FILE_ID_STD_TRANSPORT {
return unavailable_profile(
profile_id,
@@ -257,7 +261,7 @@ fn build_configured_profile_routes(capabilities: &RouteCapabilities, network: &s
} else {
crate::RawIngestRouteUnavailableReason::MissingHeliusTransactionCapability
};
return vec![
let mut routes = vec![
route_with_requirements(
crate::RawIngestRouteId::YellowstoneHydrated,
network,
@@ -279,20 +283,23 @@ fn build_configured_profile_routes(capabilities: &RouteCapabilities, network: &s
network,
&[(capabilities.has_standard_block, crate::RawIngestRouteUnavailableReason::MissingWsBlockCapability)],
),
route_with_requirements(
];
if capabilities.helius_source_declared {
routes.push(route_with_requirements(
crate::RawIngestRouteId::HeliusTransactionHydrated,
network,
&[
(capabilities.has_helius_transaction, helius_reason),
(capabilities.has_get_transaction, crate::RawIngestRouteUnavailableReason::MissingHttpGetTransaction),
],
),
route_with_requirements(
crate::RawIngestRouteId::HttpBlockPolling,
network,
&[(capabilities.has_http_block_scan, crate::RawIngestRouteUnavailableReason::MissingHttpBlockScan)],
),
];
));
}
routes.push(route_with_requirements(
crate::RawIngestRouteId::HttpBlockPolling,
network,
&[(capabilities.has_http_block_scan, crate::RawIngestRouteUnavailableReason::MissingHttpBlockScan)],
));
return routes;
}
fn route_with_requirements(

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-raw-transaction-ingest-desk/tests/desktop_security.rs
// version: 2
// version: 3
//! Desktop security canaries for the Raw Transaction Ingest Desk scaffold.
@@ -64,7 +64,7 @@ fn pre_006_frontend_tracing_is_control_inventory_and_command_oriented_only() {
assert!(main.contains("navigation tab clicked"));
assert!(main.contains("runtime status refresh requested"));
assert!(main.contains("Config route inventory refresh requested"));
assert!(main.contains("logical profile selected"));
assert!(main.contains("logical network selected"));
let invoke = read_text(app_root().join("frontend/ts/invoke.ts").as_path());
assert!(invoke.contains("Frontend IPC command requested"));
for forbidden in ["apiKey", "authorization", "connectionUri", "endpointUrl", "sourceKey", "rawTransaction", "transactionPayload", "x-token"] {

View File

@@ -1,5 +1,5 @@
// file: crates/ksp-app-raw-transaction-ingest-desk/unit_tests/route_inventory.rs
// version: 3
// version: 4
#[test]
fn pre_006_route_requirement_projection_is_fail_closed_and_ordered() {
@@ -38,7 +38,7 @@ fn pre_006_unavailable_profile_projects_all_five_routes_without_physical_materia
}
#[test]
fn pre_006_fix_002_network_profiles_aggregate_same_network_transport_capabilities_and_standard_block() {
fn pre_006_fix_003_network_profiles_aggregate_same_network_capabilities_and_omit_undeclared_provider_routes() {
let management = committed_management();
assert!(management.is_ok());
let management = match management {
@@ -91,12 +91,8 @@ fn pre_006_fix_002_network_profiles_aggregate_same_network_transport_capabilitie
assert_optional_secret_route(testnet, crate::RawIngestRouteId::YellowstoneHydrated);
assert_route(testnet, crate::RawIngestRouteId::StandardLogsHydrated, true, std::option::Option::None);
assert_route(testnet, crate::RawIngestRouteId::StandardBlockDirect, true, std::option::Option::None);
assert_route(
testnet,
crate::RawIngestRouteId::HeliusTransactionHydrated,
false,
std::option::Option::Some(crate::RawIngestRouteUnavailableReason::MissingHeliusTransactionCapability),
);
assert_route_absent(testnet, crate::RawIngestRouteId::HeliusTransactionHydrated);
assert_eq!(testnet.routes.len(), 4);
assert_route(testnet, crate::RawIngestRouteId::HttpBlockPolling, true, std::option::Option::None);
}
let serialized = serde_json::to_string(&inventory);
@@ -121,7 +117,7 @@ fn pre_006_fix_002_network_profiles_aggregate_same_network_transport_capabilitie
}
#[test]
fn pre_006_fix_002_base_network_routes_remain_configured_independently_of_optional_sources() {
fn pre_006_fix_003_base_network_routes_remain_configured_independently_of_optional_sources() {
let management = committed_management();
assert!(management.is_ok());
let management = match management {
@@ -198,6 +194,11 @@ fn assert_optional_secret_route(profile: &crate::RawIngestProfileInventoryDto, r
}
}
fn assert_route_absent(profile: &crate::RawIngestProfileInventoryDto, route_id: crate::RawIngestRouteId) {
let route = profile.routes.iter().find(|route| return route.route_id == route_id);
assert!(route.is_none());
}
fn assert_route(
profile: &crate::RawIngestProfileInventoryDto,
route_id: crate::RawIngestRouteId,

View File

@@ -0,0 +1,44 @@
<!-- file: deltas/0.3.15/pre.006-fix.003.md -->
<!-- version: 1 -->
# Delta `0.3.15-pre.006-fix.003`
## Objet
Corriger la classification de `helius-transaction-hydrated` sur Testnet sans inventer une capability provider absente, et réaligner le canari de tracing frontend sur le modèle réseau-centrique.
## Applicabilité des routes provider-specific
Le catalogue V1 reste globalement borné à cinq IDs. Un profil réseau ne projette cependant une route explicitement liée à un provider que si son composite déclare la source Transport correspondante.
Pour Helius :
- Devnet déclare `transport.helius` et projette `helius-transaction-hydrated` ;
- Mainnet déclare `transport.helius` et projette `helius-transaction-hydrated` ;
- Testnet ne déclare pas `transport.helius` et ne projette donc pas cette route.
L'absence d'une source provider-specific n'est pas transformée en faux `Configured`, ni en faux incident `Unavailable`. La route est simplement hors inventaire pour ce réseau.
## Testnet
Le profil Testnet expose donc quatre routes applicables :
1. `yellowstone-hydrated` ;
2. `standard-logs-hydrated` ;
3. `standard-block-direct` ;
4. `http-block-polling`.
`helius-transaction-hydrated` reste dans le catalogue global V1 et dans les profils Devnet/Mainnet, mais n'est pas présenté sur Testnet.
## Canari frontend
Le test `desktop_security` attend désormais la trace `logical network selected`, conforme au frontend réseau-centrique introduit par `pre.006-fix.001`, au lieu de l'ancien libellé `logical profile selected`.
## Version
- header racine `604 -> 605` ;
- workspace `0.3.15-pre.6.fix.2 -> 0.3.15-pre.6.fix.3`.
## Non-claims
Ce fix n'ajoute aucun endpoint Helius Testnet, aucun fallback cross-network, aucun probe réseau, aucun Store ouvert, aucun Worker et aucun Start/Stop runtime.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Plan v0.3.15 — Raw Transaction Ingest Desk
@@ -728,7 +728,7 @@ Restauration du template Desk KSP clair, bornage de la grille de routes et corre
Résoudre Config côté Rust et projeter les routes composables/non composables avec raisons sûres et génération d'inventaire, sans endpoint, URL, secret ou source key côté frontend.
**État : implémenté puis corrigé par `pre.006-fix.001` et `pre.006-fix.002`.** Le Desk ouvre uniquement la dépendance directe `ksp-onchain-transport-lib` nécessaire aux capabilities typées. Le composite applicatif est réseau-centrique (`devnet`, `mainnet`, `testnet`) et peut référencer plusieurs profils Transport du même réseau. Le backend agrège leurs capabilities sans inférer quoi que ce soit du provider : PublicNode Mainnet Yellowstone est donc une capability de `mainnet`, pas un pseudo-réseau ni un profil opérateur séparé. Les sources optionnelles Helius/Yellowstone dont le secret manque ne désactivent que la route qui dépend de cette source. HTTP est prouvé directement par rôles + `request_kinds`, WS par `WsProtocolKind` + `WsSubscriptionKind`, Yellowstone par présence d'un endpoint gRPC activé. Aucun Store, session Transport ou Worker n'est ouvert.
**État : implémenté puis corrigé par `pre.006-fix.001`, `pre.006-fix.002` et `pre.006-fix.003`.** Le Desk ouvre uniquement la dépendance directe `ksp-onchain-transport-lib` nécessaire aux capabilities typées. Le composite applicatif est réseau-centrique (`devnet`, `mainnet`, `testnet`) et peut référencer plusieurs profils Transport du même réseau. Le backend agrège leurs capabilities sans inférer quoi que ce soit du provider : PublicNode Mainnet Yellowstone est donc une capability de `mainnet`, pas un pseudo-réseau ni un profil opérateur séparé. Les sources optionnelles Helius/Yellowstone dont le secret manque ne désactivent que la route qui dépend de cette source. HTTP est prouvé directement par rôles + `request_kinds`, WS par `WsProtocolKind` + `WsSubscriptionKind`, Yellowstone par présence d'un endpoint gRPC activé. Aucun Store, session Transport ou Worker n'est ouvert.
Budget cible : une tranche composition.
@@ -736,9 +736,17 @@ Budget cible : une tranche composition.
Correction du modèle de classification : les providers redeviennent des sources Transport same-network et le sélecteur applicatif ne porte plus que `devnet`, `mainnet` et `testnet`. Ajout d'un profil `testnet_public` sans secret pour dissocier le Transport standard Testnet de PublicNode Yellowstone. Les canaris d'inventaire utilisent désormais des racines Config committées et un environnement injecté, sans dépendre du Config utilisateur de la machine.
#### `pre.006-fix.002` — Standard Block explicite
Qualification explicite de `Block` sur les endpoints Standard WS publics de Devnet/Mainnet/Testnet et correction des canaris qui appelaient une API Config crate-private.
#### `pre.006-fix.003` — applicabilité provider-specific par réseau
Une route liée à un provider n'est projetée que si le composite réseau déclare la source Transport correspondante. L'absence de `transport.helius` sur Testnet signifie donc « route Helius non applicable/non exposée », et non « route en panne ». Le catalogue V1 garde cinq IDs globaux ; un profil réseau peut en exposer un sous-ensemble applicable.
### `pre.007` — reconstruction Start des ressources Transport
Revalider Config au Start et reconstruire les ressources Transport exactes nécessaires aux cinq routes, sans lancer encore le Worker. Le choix des endpoints physiques reste Transport-owned.
Revalider Config au Start et reconstruire les ressources Transport exactes nécessaires aux routes applicables du réseau sélectionné, dans le catalogue global de cinq IDs V1, sans lancer encore le Worker. Le choix des endpoints physiques reste Transport-owned.
Budget cible : une tranche intégration Transport/Desk.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
<!-- version: 9 -->
<!-- version: 10 -->
# Validation v0.3.15 — Raw Transaction Ingest Desk
@@ -362,7 +362,7 @@ Le forecast durable est porté par la section 20 du plan `036` sous forme hiéra
### `pre.006` — inventaire composable
**Statut : gate opérateur de `pre.006` en échec fonctionnel, puis corrections `pre.006-fix.001` et `pre.006-fix.002`.** Le premier inventaire classait encore les capabilities par profil Transport fournisseur : `Yellowstone + HTTP hydration` Mainnet n'était donc `Configured` que sous `publicnode_mainnet`. Le fix remplace cette projection par trois profils réseau (`devnet`, `mainnet`, `testnet`) qui agrègent les sources Transport same-network. PublicNode, Helius et OrbitFlare restent des sources de capabilities et ne deviennent jamais des identités réseau. Un secret optionnel absent n'invalide que la route dépendante. Le canari qui dépendait du Config utilisateur de la machine est remplacé par un moteur Config committé et un environnement injecté. Aucun I/O runtime n'est ajouté.
**Statut : gate opérateur de `pre.006` en échec fonctionnel, puis corrections `pre.006-fix.001`, `pre.006-fix.002` et `pre.006-fix.003`.** Le premier inventaire classait encore les capabilities par profil Transport fournisseur : `Yellowstone + HTTP hydration` Mainnet n'était donc `Configured` que sous `publicnode_mainnet`. Le fix remplace cette projection par trois profils réseau (`devnet`, `mainnet`, `testnet`) qui agrègent les sources Transport same-network. PublicNode, Helius et OrbitFlare restent des sources de capabilities et ne deviennent jamais des identités réseau. Un secret optionnel absent n'invalide que la route dépendante. Le canari qui dépendait du Config utilisateur de la machine est remplacé par un moteur Config committé et un environnement injecté. Aucun I/O runtime n'est ajouté.
#### `pre.006-fix.001` — correction classification réseau
@@ -376,9 +376,15 @@ Le fix déclare explicitement `Block` sur les endpoints `solana-public` Standard
Les canaris Desk n'utilisent plus l'API crate-private de Config. Ils valident les routes standard à partir de `ConfigEnvironment::load()` et acceptent que les routes optionnelles Helius/Yellowstone soient soit `Configured`, soit `missing_required_secret` selon l'environnement opérateur.
#### `pre.006-fix.003` — Helius Testnet non applicable
Le parcours visuel de `pre.006-fix.002` montre toutes les routes composables en vert sauf `helius-transaction-hydrated` sur Testnet. Ce rouge était trompeur : le composite Testnet ne déclare aucune source `transport.helius`, et Helius Enhanced WebSocket `transactionSubscribe` n'est pas une capability Testnet configurée. Le fix ne falsifie donc pas la capability ; il retire cette route provider-specific de l'inventaire Testnet. Devnet/Mainnet continuent à la projeter et à la qualifier selon leur source Helius.
Le catalogue global reste exactement cinq IDs V1, mais l'inventaire d'un profil réseau contient uniquement les routes applicables à ses sources déclarées. Le canari frontend obsolète `logical profile selected` est également réaligné sur le tracing réseau-centrique `logical network selected`.
### `pre.007` — ressources Start
Reconstruction/revalidation Start des ressources Transport pour les cinq routes, sans launch Worker.
Reconstruction/revalidation Start des ressources Transport pour les routes applicables du réseau sélectionné, dans le catalogue global de cinq IDs V1, sans launch Worker.
### `pre.008` — runtime mono-route