diff --git a/Cargo.toml b/Cargo.toml index 62656f9..c1eccfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 450 +# version: 451 [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-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib"] [workspace.package] -version = "0.3.8-pre.4" +version = "0.3.8-pre.4.fix.1" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/crates/ksp-store-postgres-lib/tests/dependency_boundary.rs b/crates/ksp-store-postgres-lib/tests/dependency_boundary.rs index f9fef2d..1780f4b 100644 --- a/crates/ksp-store-postgres-lib/tests/dependency_boundary.rs +++ b/crates/ksp-store-postgres-lib/tests/dependency_boundary.rs @@ -1,5 +1,5 @@ // file: crates/ksp-store-postgres-lib/tests/dependency_boundary.rs -// version: 25 +// version: 26 #![warn(missing_docs)] #![deny(unreachable_pub)] @@ -315,7 +315,21 @@ fn pre_006_raw_pagination_is_keyset_cursor_bound_and_policy_free() { } assert!(index.contains("ON ksp_raw_transactions (slot, signature)")); assert!(index.contains("WHERE retention_state <> 'purged'")); - for forbidden in [" OFFSET ", "limit.min(", "clamp(", "500", "1000"] { + let ascending = raw.lines().find(|line| return line.starts_with("const LIST_TRANSACTIONS_ASC_SQL")); + let ascending = match ascending { + std::option::Option::Some(value) => value, + std::option::Option::None => panic!("missing canonical ascending keyset SQL"), + }; + let descending = raw.lines().find(|line| return line.starts_with("const LIST_TRANSACTIONS_DESC_SQL")); + let descending = match descending { + std::option::Option::Some(value) => value, + std::option::Option::None => panic!("missing canonical descending keyset SQL"), + }; + for statement in [ascending, descending] { + assert!(!statement.contains(" OFFSET "), "pre.006 canonical keyset SQL must remain OFFSET-free"); + } + assert!(!cursor.contains(" OFFSET "), "pre.006 cursor contains forbidden OFFSET material"); + for forbidden in ["limit.min(", "clamp(", "500", "1000"] { assert!(!raw.contains(forbidden), "pre.006 contains forbidden pagination/policy/later-scope material: {forbidden}"); assert!(!cursor.contains(forbidden), "pre.006 cursor contains forbidden pagination/policy/later-scope material: {forbidden}"); } diff --git a/crates/ksp-store-postgres-lib/tests/hardening_completeness.rs b/crates/ksp-store-postgres-lib/tests/hardening_completeness.rs index b39c30f..944e608 100644 --- a/crates/ksp-store-postgres-lib/tests/hardening_completeness.rs +++ b/crates/ksp-store-postgres-lib/tests/hardening_completeness.rs @@ -1,5 +1,5 @@ // file: crates/ksp-store-postgres-lib/tests/hardening_completeness.rs -// version: 18 +// version: 19 #![warn(missing_docs)] #![deny(unreachable_pub)] @@ -328,12 +328,12 @@ fn v0_3_8_pre_004_raw_capability_implementation_inventory_is_exactly_eleven() { #[test] fn v0_3_8_pre_004_raw_transaction_keyset_sql_remains_offset_free_and_unchanged_in_role() { let source = include_str!("../src/raw_transaction.rs"); - let ascending = source.lines().find(|line| line.starts_with("const LIST_TRANSACTIONS_ASC_SQL")); + let ascending = source.lines().find(|line| return line.starts_with("const LIST_TRANSACTIONS_ASC_SQL")); let ascending = match ascending { std::option::Option::Some(value) => value, std::option::Option::None => panic!("missing canonical ascending keyset SQL"), }; - let descending = source.lines().find(|line| line.starts_with("const LIST_TRANSACTIONS_DESC_SQL")); + let descending = source.lines().find(|line| return line.starts_with("const LIST_TRANSACTIONS_DESC_SQL")); let descending = match descending { std::option::Option::Some(value) => value, std::option::Option::None => panic!("missing canonical descending keyset SQL"), @@ -359,12 +359,12 @@ fn v0_3_8_pre_004_raw_transaction_keyset_sql_remains_offset_free_and_unchanged_i #[test] fn v0_3_8_pre_004_transaction_inspection_sql_is_single_statement_payload_free_counted_and_random_access() { let source = include_str!("../src/raw_transaction.rs"); - let ascending = source.lines().find(|line| line.starts_with("const INSPECT_TRANSACTIONS_ASC_SQL")); + let ascending = source.lines().find(|line| return line.starts_with("const INSPECT_TRANSACTIONS_ASC_SQL")); let ascending = match ascending { std::option::Option::Some(value) => value, std::option::Option::None => panic!("missing ascending inspection SQL"), }; - let descending = source.lines().find(|line| line.starts_with("const INSPECT_TRANSACTIONS_DESC_SQL")); + let descending = source.lines().find(|line| return line.starts_with("const INSPECT_TRANSACTIONS_DESC_SQL")); let descending = match descending { std::option::Option::Some(value) => value, std::option::Option::None => panic!("missing descending inspection SQL"), diff --git a/crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs b/crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs index cbda70d..2a0439e 100644 --- a/crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs +++ b/crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs @@ -1,5 +1,5 @@ // file: crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs -// version: 6 +// version: 7 #![warn(missing_docs)] #![deny(unreachable_pub)] @@ -73,7 +73,10 @@ enum LiveRetentionResult { #[test] #[ignore = "opt-in real PostgreSQL RawTransaction proof; reads one dedicated URI from stdin"] fn pre_009_real_postgres_raw_transaction_vertical_slice_is_atomic_concurrent_and_recoverable() { - eprintln!("KSP Store RawTransaction live proof: reading one dedicated URI from stdin without echoing it from the test."); + eprintln!( + "KSP Store RawTransaction live proof: waiting for one dedicated PostgreSQL URI line on stdin; the scenario does not start until Enter is pressed." + ); + eprintln!("KSP Store RawTransaction live proof: the test itself never echoes the URI."); let uri_result = read_uri_from_stdin(); let uri = match uri_result { std::result::Result::Ok(value) => value, diff --git a/deltas/0.3.8/pre.004-fix.001.md b/deltas/0.3.8/pre.004-fix.001.md new file mode 100644 index 0000000..2fd2289 --- /dev/null +++ b/deltas/0.3.8/pre.004-fix.001.md @@ -0,0 +1,97 @@ + + + +# Delta `0.3.8-pre.004-fix.001` — réconciliation des canaris PostgreSQL `pre.004` + +## Base requise + +```text +0.3.8-pre.004 +workspace.package.version = 0.3.8-pre.4 +``` + +La livraison devient : + +```text +0.3.8-pre.004-fix.001 +workspace.package.version = 0.3.8-pre.4.fix.1 +commit = v0.3.8-pre.004-fix.001 +tag = aucun +``` + +## Cause du fix + +Le gate opérateur révèle deux défauts de tests : + +1. quatre closures ajoutées dans `hardening_completeness.rs` enfreignent `clippy::implicit-return` ; +2. le canari historique `pre_006_raw_pagination_is_keyset_cursor_bound_and_policy_free` interdit encore `OFFSET` sur l'intégralité de `raw_transaction.rs`, alors que `pre.004` autorise explicitement `OFFSET` uniquement dans les statements d'inspection random-access. + +Les tests fonctionnels PostgreSQL `pre.004` eux-mêmes sont verts : 66 tests unitaires passent, y compris les trois nouveaux tests d'inspection. + +## Correction + +Les quatre closures utilisent désormais un `return` explicite. + +Le canari `pre.006` conserve son invariant historique mais le mesure au bon niveau : + +```text +LIST_TRANSACTIONS_ASC_SQL -> OFFSET interdit +LIST_TRANSACTIONS_DESC_SQL -> OFFSET interdit +raw_transaction/cursor.rs -> OFFSET interdit +inspection SQL -> OFFSET autorisé uniquement par pre.004 +``` + +Les autres interdictions de policy (`limit.min`, `clamp`, plafonds arbitraires) restent globales dans le chemin transaction/cursor. + +## Live proof + +Le run opérateur interrompu après plus de 60 secondes n'a jamais imprimé `server major ...`; il ne constitue donc pas une preuve que le scénario PostgreSQL a commencé. Le message du test précise désormais qu'il attend une ligne URI sur stdin et ne démarre qu'après Enter. + +Commande recommandée avec saisie masquée : + +```bash +read -rsp 'Dedicated PostgreSQL URI: ' KSP_LIVE_PG_URI +printf '\n' +printf '%s\n' "$KSP_LIVE_PG_URI" | cargo test -p ksp-store-postgres-lib --test postgres_raw_transaction_live -- --ignored --nocapture +unset KSP_LIVE_PG_URI +``` + +## Scope + +Aucun SQL de production, runtime PostgreSQL, contrat Store, façade, migration, capability Account ou UI n'est modifié. + +## Fichiers ajoutés + +```text +deltas/0.3.8/pre.004-fix.001.md +``` + +## Fichiers modifiés + +```text +Cargo.toml +crates/ksp-store-postgres-lib/tests/dependency_boundary.rs +crates/ksp-store-postgres-lib/tests/hardening_completeness.rs +crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs +docs/validation/025-V0_3_8_STORE_DESK.md +``` + +## Fichiers supprimés + +```text +aucun +``` + +## Gate 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 +cargo test -p ksp-store-postgres-lib +cargo test -p ksp-store-lib +cargo check -p ksp-store-lib --no-default-features +cargo test -p ksp-store-api +``` diff --git a/docs/validation/025-V0_3_8_STORE_DESK.md b/docs/validation/025-V0_3_8_STORE_DESK.md index d46ff5f..3e8f880 100644 --- a/docs/validation/025-V0_3_8_STORE_DESK.md +++ b/docs/validation/025-V0_3_8_STORE_DESK.md @@ -1,5 +1,5 @@ - + # Validation v0.3.8 — Store Desk V1 RAW @@ -333,3 +333,29 @@ Le canari d'inventaire façade corrigé est vert. `pre.003` est fermé et `pre.0 - [X] inventaires exacts Store/PostgreSQL passent de 10 à 11 implementations RAW et restent symétriques ; - [X] aucune migration, table, index, capability Account inspection, UI Desk ou protocole DataTables n'est ajouté dans cette tranche. +## 19. Gate opérateur `pre.004` et ouverture de `pre.004-fix.001` + +Le gate opérateur de `pre.004` confirme que les audits Rust/Markdown, `cargo check --workspace`, `ksp-store-lib`, `ksp-store-api` et les 66 tests unitaires PostgreSQL sont verts. Deux défauts de tests empêchent toutefois la fermeture de la tranche : + +```text +cargo clippy --workspace --all-targets: FAIL + 4 x clippy::implicit-return dans hardening_completeness.rs + +cargo test -p ksp-store-postgres-lib: FAIL + pre_006_raw_pagination_is_keyset_cursor_bound_and_policy_free + canari historique interdisant OFFSET sur tout raw_transaction.rs +``` + +Le second échec ne remet pas en cause le contrat `pre.004` : l'`OFFSET` est volontairement autorisé uniquement dans les statements d'inspection random-access, tandis que les statements `LIST_TRANSACTIONS_*` cursor/keyset doivent rester OFFSET-free. `pre.004-fix.001` rescope donc le canari historique sur les statements keyset eux-mêmes au lieu de l'appliquer au fichier physique complet. + +Le live proof lancé ensuite n'a pas fourni de preuve PostgreSQL exploitable : le journal ne contient pas la ligne `server major ...`, émise seulement après lecture de l'URI et connexion initiale. L'exécution observée est compatible avec une attente sur `stdin().read_line()`. Le fix rend cette attente explicite dans le message du test. Pour une saisie locale masquée : + +```bash +read -rsp 'Dedicated PostgreSQL URI: ' KSP_LIVE_PG_URI +printf '\n' +printf '%s\n' "$KSP_LIVE_PG_URI" | cargo test -p ksp-store-postgres-lib --test postgres_raw_transaction_live -- --ignored --nocapture +unset KSP_LIVE_PG_URI +``` + +Aucun SQL, contrat Store, runtime PostgreSQL ou comportement d'inspection de production n'est modifié par ce fix. +