v0.3.7-pre.013
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 437
|
# version: 438
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-solprices-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-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"]
|
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-solprices-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-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.3.7-pre.12.fix.1"
|
version = "0.3.7-pre.13"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-backfill-desk/tests/config_composition.rs
|
// file: crates/ksp-app-backfill-desk/tests/config_composition.rs
|
||||||
// version: 6
|
// version: 7
|
||||||
|
|
||||||
//! Config composite, Transport readiness and Store-network composition contracts for Backfill Desk through pre.006.
|
//! Config composite, Transport readiness and Store-network composition contracts for Backfill Desk through pre.006.
|
||||||
|
|
||||||
@@ -264,3 +264,45 @@ fn pre_006_default_mainnet_profile_exposes_pool_and_targeted_http_routes_without
|
|||||||
assert!(roles.contains("backfill_publicnode"));
|
assert!(roles.contains("backfill_publicnode"));
|
||||||
assert!(roles.contains("backfill_solana_public"));
|
assert!(roles.contains("backfill_solana_public"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_composite_profile_and_component_inventory_is_exact() {
|
||||||
|
let workspace = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../..");
|
||||||
|
let source = std::fs::read_to_string(workspace.join("config/composite.ksp-app-backfill-desk.json"));
|
||||||
|
assert!(source.is_ok(), "Backfill Desk composite should be readable");
|
||||||
|
let source = match source {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(_) => return,
|
||||||
|
};
|
||||||
|
let document = serde_json::from_str::<serde_json::Value>(source.as_str());
|
||||||
|
assert!(document.is_ok(), "Backfill Desk composite should remain valid JSON");
|
||||||
|
let document = match document {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(_) => return,
|
||||||
|
};
|
||||||
|
assert_eq!(document.get("default_profile").and_then(serde_json::Value::as_str), std::option::Option::Some("mainnet"));
|
||||||
|
let profiles = document.get("profiles").and_then(serde_json::Value::as_array);
|
||||||
|
assert!(profiles.is_some(), "Backfill Desk composite should expose profiles");
|
||||||
|
let profiles = match profiles {
|
||||||
|
std::option::Option::Some(value) => value,
|
||||||
|
std::option::Option::None => return,
|
||||||
|
};
|
||||||
|
let profile_ids = profiles
|
||||||
|
.iter()
|
||||||
|
.filter_map(|profile| return profile.get("profile_id").and_then(serde_json::Value::as_str))
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
assert_eq!(profile_ids, std::collections::BTreeSet::from(["devnet", "mainnet", "testnet"]));
|
||||||
|
for profile in profiles {
|
||||||
|
let documents = profile.get("documents").and_then(serde_json::Value::as_array);
|
||||||
|
assert!(documents.is_some(), "every Backfill Desk profile should expose component documents");
|
||||||
|
let documents = match documents {
|
||||||
|
std::option::Option::Some(value) => value,
|
||||||
|
std::option::Option::None => continue,
|
||||||
|
};
|
||||||
|
let component_ids = documents
|
||||||
|
.iter()
|
||||||
|
.filter_map(|document| return document.get("component_id").and_then(serde_json::Value::as_str))
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
assert_eq!(component_ids, std::collections::BTreeSet::from(["logging", "store", "transport"]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
78
crates/ksp-app-backfill-desk/tests/dependency_boundary.rs
Normal file
78
crates/ksp-app-backfill-desk/tests/dependency_boundary.rs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
// file: crates/ksp-app-backfill-desk/tests/dependency_boundary.rs
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
//! Final dependency-boundary checks for the KSP Backfill desktop application.
|
||||||
|
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
#![deny(unreachable_pub)]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
fn app_root() -> std::path::PathBuf {
|
||||||
|
return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_text(path: &std::path::Path) -> String {
|
||||||
|
let source = std::fs::read_to_string(path);
|
||||||
|
assert!(source.is_ok(), "unable to read {}", path.display());
|
||||||
|
return match source {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(_) => String::new(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_manifest_ksp_dependency_surface_is_exact_and_backend_neutral() {
|
||||||
|
let manifest = read_text(app_root().join("Cargo.toml").as_path());
|
||||||
|
let dependency_section = manifest.split("[dependencies]").nth(1).and_then(|tail| return tail.split("[dev-dependencies]").next());
|
||||||
|
assert!(dependency_section.is_some(), "Backfill Desk manifest should expose a dependency section");
|
||||||
|
let dependency_section = match dependency_section {
|
||||||
|
std::option::Option::Some(value) => value,
|
||||||
|
std::option::Option::None => return,
|
||||||
|
};
|
||||||
|
let ksp_dependencies = dependency_section
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| {
|
||||||
|
let name = line.split('=').next().map(str::trim);
|
||||||
|
return match name {
|
||||||
|
std::option::Option::Some(value) if value.starts_with("ksp-") => std::option::Option::Some(value),
|
||||||
|
_ => std::option::Option::None,
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
assert_eq!(
|
||||||
|
ksp_dependencies,
|
||||||
|
std::collections::BTreeSet::from([
|
||||||
|
"ksp-config-lib",
|
||||||
|
"ksp-core-lib",
|
||||||
|
"ksp-job-api",
|
||||||
|
"ksp-job-backfill-lib",
|
||||||
|
"ksp-logging-lib",
|
||||||
|
"ksp-onchain-transport-lib",
|
||||||
|
"ksp-store-lib",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
for forbidden in ["ksp-store-api", "ksp-store-postgres-lib", "tokio-postgres", "reqwest", "tonic", "yellowstone-grpc-proto", "mpl-token-metadata"] {
|
||||||
|
assert!(!dependency_section.contains(forbidden), "Backfill Desk manifest owns forbidden dependency {forbidden}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_production_sources_do_not_cross_into_physical_store_or_provider_clients() {
|
||||||
|
let source_root = app_root().join("src");
|
||||||
|
let entries = std::fs::read_dir(source_root.as_path());
|
||||||
|
assert!(entries.is_ok(), "Backfill Desk source directory should be readable");
|
||||||
|
let entries = match entries {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(_) => return,
|
||||||
|
};
|
||||||
|
for entry in entries.flatten() {
|
||||||
|
let path = entry.path();
|
||||||
|
if path.extension().and_then(std::ffi::OsStr::to_str) != std::option::Option::Some("rs") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let source = read_text(path.as_path());
|
||||||
|
for forbidden in ["ksp_store_api", "ksp_store_postgres_lib", "tokio_postgres", "reqwest::", "tonic::", "yellowstone_grpc_proto"] {
|
||||||
|
assert!(!source.contains(forbidden), "{} crosses forbidden dependency boundary via {forbidden}", path.display());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-backfill-desk/tests/desktop_contract.rs
|
// file: crates/ksp-app-backfill-desk/tests/desktop_contract.rs
|
||||||
// version: 14
|
// version: 15
|
||||||
|
|
||||||
//! Structural desktop contract checks for the Backfill Desk scaffold.
|
//! Structural desktop contract checks for the Backfill Desk scaffold.
|
||||||
|
|
||||||
@@ -434,3 +434,31 @@ fn pre_012_free_address_autocomplete_is_html_datalist_derived_from_core_registry
|
|||||||
assert!(!html.contains(forbidden), "HTML hardcodes canonical Program ID {forbidden}");
|
assert!(!html.contains(forbidden), "HTML hardcodes canonical Program ID {forbidden}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_final_v1_command_and_frontend_control_inventory_is_exact() {
|
||||||
|
let root = app_root();
|
||||||
|
let tauri = read_text(root.join("src/tauri.rs").as_path());
|
||||||
|
let commands = [
|
||||||
|
"backfill_cancel",
|
||||||
|
"backfill_options",
|
||||||
|
"backfill_resume",
|
||||||
|
"backfill_start",
|
||||||
|
"backfill_status",
|
||||||
|
"backfill_validate_request",
|
||||||
|
"emit_frontend_log",
|
||||||
|
"get_runtime_status",
|
||||||
|
"splash_frontend_ready",
|
||||||
|
];
|
||||||
|
for command in commands {
|
||||||
|
assert!(tauri.contains(format!("fn {command}").as_str()), "missing final Tauri command {command}");
|
||||||
|
}
|
||||||
|
assert_eq!(tauri.matches("#[tauri::command]").count(), commands.len());
|
||||||
|
for forbidden in ["backfill_reset", "backfill_delete", "backfill_retry", "backfill_schedule", "backfill_history"] {
|
||||||
|
assert!(!tauri.contains(forbidden), "unexpected V1 Tauri command marker {forbidden}");
|
||||||
|
}
|
||||||
|
let frontend = read_text(root.join("frontend/main.html").as_path());
|
||||||
|
for required in ["backfillStart", "backfillCancel", "backfillResume", "backfillRefresh", "backfillProgramIds"] {
|
||||||
|
assert!(frontend.contains(required), "missing final frontend control {required}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: crates/ksp-app-backfill-desk/tests/desktop_security.rs
|
// file: crates/ksp-app-backfill-desk/tests/desktop_security.rs
|
||||||
// version: 15
|
// version: 16
|
||||||
|
|
||||||
//! Security and dependency-boundary checks for the Backfill Desk scaffold.
|
//! Security and dependency-boundary checks for the Backfill Desk scaffold.
|
||||||
|
|
||||||
@@ -365,3 +365,31 @@ fn pre_012_program_id_autocomplete_exposes_only_public_registry_metadata_and_no_
|
|||||||
assert!(selection_source.contains("registryMatch"));
|
assert!(selection_source.contains("registryMatch"));
|
||||||
assert!(!selection_source.contains("address.value"));
|
assert!(!selection_source.contains("address.value"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_final_frontend_and_ipc_surface_keeps_physical_and_checkpoint_material_backend_owned() {
|
||||||
|
let root = app_root();
|
||||||
|
let frontend = read_text(root.join("frontend/ts/main.ts").as_path());
|
||||||
|
for forbidden in ["http://", "https://", "localStorage", "sessionStorage", "indexedDB", "document.cookie", "privateKey", "secretKey"] {
|
||||||
|
assert!(!frontend.contains(forbidden), "final frontend contains forbidden marker {forbidden}");
|
||||||
|
}
|
||||||
|
let tauri = read_text(root.join("src/tauri.rs").as_path());
|
||||||
|
for forbidden in ["BackfillCheckpoint", "HttpTransportPool", "ksp_store_postgres_lib", "tokio_postgres", "reqwest", "tonic"] {
|
||||||
|
assert!(!tauri.contains(forbidden), "Tauri IPC shell owns forbidden physical/runtime marker {forbidden}");
|
||||||
|
}
|
||||||
|
let dto = read_text(root.join("src/dto_backfill.rs").as_path());
|
||||||
|
for marker in ["BackfillStartResponseDto", "BackfillCancelResponseDto", "BackfillResumeResponseDto"] {
|
||||||
|
let source = struct_source(dto.as_str(), marker);
|
||||||
|
assert!(!source.is_empty(), "missing DTO {marker}");
|
||||||
|
for forbidden in [
|
||||||
|
"pub(crate) checkpoint:",
|
||||||
|
"pub(crate) endpoint:",
|
||||||
|
"pub(crate) provider:",
|
||||||
|
"pub(crate) credential:",
|
||||||
|
"pub(crate) token:",
|
||||||
|
"pub(crate) payload:",
|
||||||
|
] {
|
||||||
|
assert!(!source.contains(forbidden), "DTO {marker} leaks forbidden field {forbidden}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
121
crates/ksp-app-backfill-desk/tests/release_completeness.rs
Normal file
121
crates/ksp-app-backfill-desk/tests/release_completeness.rs
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
// file: crates/ksp-app-backfill-desk/tests/release_completeness.rs
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
//! Final V1 completeness canaries for the KSP Backfill desktop application.
|
||||||
|
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
#![deny(unreachable_pub)]
|
||||||
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
|
fn app_root() -> std::path::PathBuf {
|
||||||
|
return std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_text(path: &std::path::Path) -> String {
|
||||||
|
let source = std::fs::read_to_string(path);
|
||||||
|
assert!(source.is_ok(), "unable to read {}", path.display());
|
||||||
|
return match source {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(_) => String::new(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_production_module_inventory_is_exact() {
|
||||||
|
let lib = read_text(app_root().join("src/lib.rs").as_path());
|
||||||
|
let modules = lib
|
||||||
|
.lines()
|
||||||
|
.filter_map(|line| {
|
||||||
|
let line = line.trim();
|
||||||
|
if !line.starts_with("mod ") || !line.ends_with(';') {
|
||||||
|
return std::option::Option::None;
|
||||||
|
}
|
||||||
|
return std::option::Option::Some(line.trim_start_matches("mod ").trim_end_matches(';'));
|
||||||
|
})
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
assert_eq!(
|
||||||
|
modules,
|
||||||
|
std::collections::BTreeSet::from([
|
||||||
|
"app_state",
|
||||||
|
"backfill_request",
|
||||||
|
"backfill_run",
|
||||||
|
"backfill_status",
|
||||||
|
"bootstrap",
|
||||||
|
"constants",
|
||||||
|
"dto_backfill",
|
||||||
|
"dto_common",
|
||||||
|
"errors",
|
||||||
|
"frontend_logging",
|
||||||
|
"logging_runtime",
|
||||||
|
"splash",
|
||||||
|
"store_runtime",
|
||||||
|
"tauri",
|
||||||
|
"transport_runtime",
|
||||||
|
"tw_main",
|
||||||
|
"tw_splash",
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_integration_suite_inventory_closes_v1_contracts() {
|
||||||
|
let tests_root = app_root().join("tests");
|
||||||
|
let entries = std::fs::read_dir(tests_root.as_path());
|
||||||
|
assert!(entries.is_ok(), "Backfill Desk tests directory should be readable");
|
||||||
|
let entries = match entries {
|
||||||
|
std::result::Result::Ok(value) => value,
|
||||||
|
std::result::Result::Err(_) => return,
|
||||||
|
};
|
||||||
|
let files = entries
|
||||||
|
.flatten()
|
||||||
|
.filter_map(|entry| {
|
||||||
|
let path = entry.path();
|
||||||
|
if path.extension().and_then(std::ffi::OsStr::to_str) != std::option::Option::Some("rs") {
|
||||||
|
return std::option::Option::None;
|
||||||
|
}
|
||||||
|
return path.file_name().and_then(std::ffi::OsStr::to_str).map(str::to_owned);
|
||||||
|
})
|
||||||
|
.collect::<std::collections::BTreeSet<_>>();
|
||||||
|
assert_eq!(
|
||||||
|
files,
|
||||||
|
std::collections::BTreeSet::from([
|
||||||
|
"config_composition.rs".to_owned(),
|
||||||
|
"dependency_boundary.rs".to_owned(),
|
||||||
|
"desktop_contract.rs".to_owned(),
|
||||||
|
"desktop_security.rs".to_owned(),
|
||||||
|
"public_api.rs".to_owned(),
|
||||||
|
"release_completeness.rs".to_owned(),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_final_surface_contains_every_planned_v1_capability_without_deferred_extensions() {
|
||||||
|
let tauri = read_text(app_root().join("src/tauri.rs").as_path());
|
||||||
|
for required in ["backfill_start", "backfill_status", "backfill_cancel", "backfill_resume"] {
|
||||||
|
assert!(tauri.contains(required), "missing final V1 capability marker {required}");
|
||||||
|
}
|
||||||
|
let options = read_text(app_root().join("src/dto_common.rs").as_path());
|
||||||
|
assert!(options.contains("program_id_options"));
|
||||||
|
assert!(options.contains("program_id_autocomplete_options"));
|
||||||
|
let status = read_text(app_root().join("src/backfill_status.rs").as_path());
|
||||||
|
for required in ["checkpoint_present", "contiguous_completed", "failure_code", "failure_domain"] {
|
||||||
|
assert!(status.contains(required), "missing final monitoring marker {required}");
|
||||||
|
}
|
||||||
|
for forbidden in ["Grpc", "Yellowstone", "WebSocketBackfill", "scheduler", "job_history"] {
|
||||||
|
assert!(!tauri.contains(forbidden), "deferred capability leaked into V1 Tauri surface via {forbidden}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pre_013_shared_autocomplete_dto_remains_exported_and_consumed_through_crate_root() {
|
||||||
|
let root = app_root();
|
||||||
|
let lib = read_text(root.join("src/lib.rs").as_path());
|
||||||
|
assert!(lib.contains("pub(crate) use self::dto_common::ProgramIdAutocompleteOptionDto;"));
|
||||||
|
let dto = read_text(root.join("src/dto_common.rs").as_path());
|
||||||
|
assert!(dto.contains("pub(crate) struct ProgramIdAutocompleteOptionDto"));
|
||||||
|
assert!(dto.contains("std::vec::Vec<crate::ProgramIdAutocompleteOptionDto>"));
|
||||||
|
assert!(dto.contains("crate::ProgramIdAutocompleteOptionDto {"));
|
||||||
|
let bare_construction = dto.matches("\n ProgramIdAutocompleteOptionDto {").count();
|
||||||
|
assert_eq!(bare_construction, 0, "shared autocomplete DTO must not bypass the crate-root facade");
|
||||||
|
}
|
||||||
91
deltas/0.3.7/pre.013.md
Normal file
91
deltas/0.3.7/pre.013.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
<!-- file: deltas/0.3.7/pre.013.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta `0.3.7-pre.013` — hardening et complétude Backfill Desk V1
|
||||||
|
|
||||||
|
## 1. Base requise
|
||||||
|
|
||||||
|
```text
|
||||||
|
0.3.7-pre.012-fix.001
|
||||||
|
workspace.package.version = 0.3.7-pre.12.fix.1
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. Objectif
|
||||||
|
|
||||||
|
Fermer la surface fonctionnelle V1 de Backfill Desk par des canaries de dépendances, composition, desktop/security et release completeness, sans ajouter de capacité métier ni modifier le runtime.
|
||||||
|
|
||||||
|
## 3. Hardening ajouté
|
||||||
|
|
||||||
|
Deux suites d'intégration dédiées sont ajoutées :
|
||||||
|
|
||||||
|
- `dependency_boundary.rs` : dépendances KSP exactes et interdiction des backends/clients physiques ;
|
||||||
|
- `release_completeness.rs` : inventaire exact des modules/tests et présence des capacités V1 finales sans extensions différées.
|
||||||
|
|
||||||
|
Les suites existantes sont renforcées :
|
||||||
|
|
||||||
|
- `config_composition.rs` verrouille les trois profils et les trois composants exacts ;
|
||||||
|
- `desktop_contract.rs` verrouille les neuf commandes Tauri et les contrôles frontend V1 ;
|
||||||
|
- `desktop_security.rs` ajoute un scan final des matériaux physiques/checkpoint/browser storage ;
|
||||||
|
- la discipline crate-root du DTO autocomplete partagé est canariée explicitement.
|
||||||
|
|
||||||
|
## 4. Invariants fermés
|
||||||
|
|
||||||
|
```text
|
||||||
|
single active run
|
||||||
|
HTTP-only Backfill V1
|
||||||
|
backend-neutral Store facade
|
||||||
|
no physical provider/store client in app production
|
||||||
|
no checkpoint payload through IPC
|
||||||
|
no browser persistence
|
||||||
|
mainnet default + devnet/testnet configured
|
||||||
|
free Program ID autocomplete from ksp-core-lib
|
||||||
|
Start + monitoring + Cancel + Resume in-session
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5. Hors périmètre
|
||||||
|
|
||||||
|
Aucun runtime Job/Store/Transport, DTO/IPC, frontend, Config ou dépendance/feature n'est modifié. Aucun gRPC/WS Backfill, scheduler, history, retry Job, reset ou checkpoint durable n'est ajouté.
|
||||||
|
|
||||||
|
## 6. Version
|
||||||
|
|
||||||
|
```text
|
||||||
|
workspace.package.version = 0.3.7-pre.13
|
||||||
|
label = 0.3.7-pre.013
|
||||||
|
```
|
||||||
|
|
||||||
|
## 7. Fichiers ajoutés
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/ksp-app-backfill-desk/tests/dependency_boundary.rs
|
||||||
|
crates/ksp-app-backfill-desk/tests/release_completeness.rs
|
||||||
|
deltas/0.3.7/pre.013.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 8. Fichiers modifiés
|
||||||
|
|
||||||
|
```text
|
||||||
|
Cargo.toml
|
||||||
|
crates/ksp-app-backfill-desk/tests/config_composition.rs
|
||||||
|
crates/ksp-app-backfill-desk/tests/desktop_contract.rs
|
||||||
|
crates/ksp-app-backfill-desk/tests/desktop_security.rs
|
||||||
|
docs/plans/028-V0_3_7_BACKFILL_DESK_PLAN.md
|
||||||
|
docs/validation/024-V0_3_7_BACKFILL_DESK.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 9. Fichiers supprimés
|
||||||
|
|
||||||
|
Aucun.
|
||||||
|
|
||||||
|
## 10. Gate après application
|
||||||
|
|
||||||
|
```text
|
||||||
|
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/0.3.7
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets
|
||||||
|
cargo test -p ksp-job-backfill-lib
|
||||||
|
cargo test -p ksp-app-backfill-desk
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun `cargo tree` requis : aucune dépendance ni feature Cargo n'est modifiée.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/plans/028-V0_3_7_BACKFILL_DESK_PLAN.md -->
|
<!-- file: docs/plans/028-V0_3_7_BACKFILL_DESK_PLAN.md -->
|
||||||
<!-- version: 12 -->
|
<!-- version: 13 -->
|
||||||
|
|
||||||
# Plan v0.3.7 — Backfill Desk
|
# Plan v0.3.7 — Backfill Desk
|
||||||
|
|
||||||
@@ -296,7 +296,9 @@ La tranche matérialise ce contrat via `ProgramIdAutocompleteOptionDto`, ajouté
|
|||||||
|
|
||||||
### pre.013 — hardening et complétude
|
### pre.013 — hardening et complétude
|
||||||
|
|
||||||
Tests desktop/security/dependency/composition/release completeness, canaries DTO et scan des dépendances/interdictions.
|
Aucune nouvelle capacité métier. La tranche ferme la surface V1 par des canaries dédiés : inventaire exact des dépendances KSP et interdictions des backends/clients physiques, inventaire exact des modules de production et suites d’intégration, surface Tauri/contrôles frontend finaux, composition Config exacte sur `devnet`/`mainnet`/`testnet`, scan agrégé de sécurité IPC/frontend et contrôle de la discipline crate-root pour les DTO `pub(crate)` partagés introduits par la Desk.
|
||||||
|
|
||||||
|
Les nouvelles suites `dependency_boundary.rs` et `release_completeness.rs` complètent `desktop_contract.rs`, `desktop_security.rs` et `config_composition.rs`. Elles ne modifient ni runtime Job, ni Store, ni Transport, ni DTO/IPC, ni frontend. `pre.014` reste propriétaire du gate technique final workspace/Tauri build.
|
||||||
|
|
||||||
### pre.014 — gate technique final
|
### pre.014 — gate technique final
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/validation/024-V0_3_7_BACKFILL_DESK.md -->
|
<!-- file: docs/validation/024-V0_3_7_BACKFILL_DESK.md -->
|
||||||
<!-- version: 21 -->
|
<!-- version: 22 -->
|
||||||
|
|
||||||
# Validation v0.3.7 — Backfill Desk
|
# Validation v0.3.7 — Backfill Desk
|
||||||
|
|
||||||
@@ -461,7 +461,7 @@ Le correctif réutilise uniquement les helpers déjà possédés par chaque fich
|
|||||||
- [X] aucun fichier de production ou Config n'est modifié ;
|
- [X] aucun fichier de production ou Config n'est modifié ;
|
||||||
- [X] version Cargo synchronisée en `0.3.7-pre.9.fix.1` ;
|
- [X] version Cargo synchronisée en `0.3.7-pre.9.fix.1` ;
|
||||||
- [X] audits statiques Rust/Markdown rejoués dans l'environnement d'assemblage ;
|
- [X] audits statiques Rust/Markdown rejoués dans l'environnement d'assemblage ;
|
||||||
- [ ] replay opérateur `cargo fmt/check/clippy/test` du fix à exécuter ; aucun `cargo tree` requis car dépendances/features inchangées.
|
- [X] replay opérateur `cargo fmt/check/clippy/test` du fix propre : aucun warning, 50 tests unitaires Job Backfill et toutes les suites Backfill Desk passent ; aucun `cargo tree` requis car dépendances/features inchangées.
|
||||||
|
|
||||||
## 23. Correctif `pre.009-fix.002` — canari monitoring borné aux champs sérialisés
|
## 23. Correctif `pre.009-fix.002` — canari monitoring borné aux champs sérialisés
|
||||||
|
|
||||||
@@ -557,3 +557,21 @@ Le correctif conserve donc le réexport et normalise uniquement les trois usages
|
|||||||
- [X] audits statiques Rust/Markdown rejoués dans l'environnement d'assemblage ;
|
- [X] audits statiques Rust/Markdown rejoués dans l'environnement d'assemblage ;
|
||||||
- [ ] replay opérateur `cargo fmt/check/clippy/test` du fix à exécuter ; aucun `cargo tree` requis car dépendances/features inchangées.
|
- [ ] replay opérateur `cargo fmt/check/clippy/test` du fix à exécuter ; aucun `cargo tree` requis car dépendances/features inchangées.
|
||||||
|
|
||||||
|
## 27. `pre.013` — hardening et complétude V1
|
||||||
|
|
||||||
|
Le gate opérateur de `pre.012-fix.001` ferme la tranche frontend : audits Rust/Markdown, `cargo check --workspace`, Clippy, les 50 tests unitaires `ksp-job-backfill-lib` et toutes les suites Backfill Desk passent sans warning. `pre.013` n'ouvre donc aucune capacité et ajoute uniquement des canaries de clôture V1.
|
||||||
|
|
||||||
|
### Gate statique local `pre.013`
|
||||||
|
|
||||||
|
- [X] suite `dependency_boundary.rs` ajoutée avec inventaire exact des dépendances KSP normales ;
|
||||||
|
- [X] `ksp-store-api`, backend PostgreSQL direct, `tokio-postgres`, `reqwest`, `tonic` et Yellowstone interdits dans le manifest/app production ;
|
||||||
|
- [X] suite `release_completeness.rs` ajoutée avec inventaire exact des 17 modules de production et des 6 suites d’intégration ;
|
||||||
|
- [X] surface Tauri finale bornée à 9 commandes, sans reset/retry/scheduler/history V1 ;
|
||||||
|
- [X] contrôles frontend finaux Start/Cancel/Resume/Refresh/autocomplete présents ;
|
||||||
|
- [X] scan sécurité agrégé : aucune URL physique, browser storage, checkpoint concret ou client/backend physique dans IPC/frontend ;
|
||||||
|
- [X] composite final borné à `devnet`, `mainnet`, `testnet`, avec exactement `logging`, `transport`, `store` ;
|
||||||
|
- [X] `ProgramIdAutocompleteOptionDto` reste réexporté et consommé via `crate::ProgramIdAutocompleteOptionDto` ;
|
||||||
|
- [X] aucun code runtime, DTO/IPC, frontend, Config, Store, Transport ou Job modifié ;
|
||||||
|
- [X] aucune dépendance/feature Cargo ajoutée ;
|
||||||
|
- [X] audits statiques Rust/Markdown propres dans l'environnement d'assemblage ;
|
||||||
|
- [ ] replay opérateur `cargo fmt/check/clippy/test` de `pre.013` à exécuter avant le gate technique final `pre.014`.
|
||||||
|
|||||||
Reference in New Issue
Block a user