diff --git a/Cargo.toml b/Cargo.toml index 4a845ac..36c26cd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 373 +# version: 374 [workspace] resolver = "3" members = ["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-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.4-pre.7" +version = "0.3.4-pre.7.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 6d5fcf0..14128e0 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: 21 +// version: 22 #![warn(missing_docs)] #![deny(unreachable_pub)] @@ -152,7 +152,7 @@ fn pre_003_v002_schema_is_complete_without_account_trait_or_write_dispatch() { } #[test] -fn pre_005_raw_account_acquisition_is_atomic_idempotent_and_keeps_later_scope_closed() { +fn pre_005_raw_account_acquisition_is_atomic_idempotent_and_keeps_destructive_trait_scope_closed() { let crate_root = include_str!("../src/lib.rs"); let raw = include_str!("../src/raw_account.rs"); let runtime = include_str!("../src/runtime.rs"); @@ -180,7 +180,7 @@ fn pre_005_raw_account_acquisition_is_atomic_idempotent_and_keeps_later_scope_cl assert!(raw.contains(required), "missing private RAW account acquisition contract: {required}"); } assert!(runtime.contains("pub async fn persist_raw_account_acquisition")); - for forbidden in ["UPDATE ", "DELETE FROM", "ON CONFLICT DO UPDATE", " OFFSET ", "list_raw_account_states"] { + for forbidden in ["UPDATE ", "DELETE FROM", "ON CONFLICT DO UPDATE", " OFFSET "] { assert!(!raw.contains(forbidden), "pre.005 account module contains later/destructive scope: {forbidden}"); } for forbidden in [ @@ -198,7 +198,7 @@ fn pre_005_raw_account_acquisition_is_atomic_idempotent_and_keeps_later_scope_cl } #[test] -fn pre_006_raw_account_additional_observation_is_reference_guarded_and_cancellation_safe() { +fn pre_006_raw_account_additional_observation_is_reference_guarded_cancellation_safe_and_keeps_destructive_scope_closed() { let raw = include_str!("../src/raw_account.rs"); let runtime = include_str!("../src/runtime.rs"); for required in [ @@ -213,7 +213,7 @@ fn pre_006_raw_account_additional_observation_is_reference_guarded_and_cancellat assert!(raw.contains(required), "missing pre.006 additional-observation contract: {required}"); } assert!(runtime.contains("pub async fn record_raw_account_observation")); - for forbidden in ["UPDATE ", "DELETE FROM", "ON CONFLICT DO UPDATE", " OFFSET ", "list_raw_account_states"] { + for forbidden in ["UPDATE ", "DELETE FROM", "ON CONFLICT DO UPDATE", " OFFSET "] { assert!(!raw.contains(forbidden), "pre.006 account module contains later/destructive scope: {forbidden}"); } for forbidden in [ diff --git a/crates/ksp-store-postgres-lib/unit_tests/raw_account.rs b/crates/ksp-store-postgres-lib/unit_tests/raw_account.rs index f096fbb..d77f446 100644 --- a/crates/ksp-store-postgres-lib/unit_tests/raw_account.rs +++ b/crates/ksp-store-postgres-lib/unit_tests/raw_account.rs @@ -1,5 +1,5 @@ // file: crates/ksp-store-postgres-lib/unit_tests/raw_account.rs -// version: 4 +// version: 5 fn network() -> ksp_store_api::RawNetworkId { return match ksp_store_api::RawNetworkId::new("devnet") { @@ -404,7 +404,7 @@ fn pre_007_account_cursor_v1_round_trip_is_fixed_109_bytes_and_exact() { let pubkey = ksp_store_api::Pubkey::new_from_array([7_u8; 32]); let query = page_query( "devnet", - std::option::Option::Some(pubkey.clone()), + std::option::Option::Some(pubkey), std::option::Option::Some(10), std::option::Option::Some(20), ksp_store_api::RawSortDirection::Ascending, @@ -433,7 +433,7 @@ fn pre_007_account_cursor_rejects_replay_across_query_context_and_transaction_fa let pubkey = ksp_store_api::Pubkey::new_from_array([4_u8; 32]); let query = page_query( "devnet", - std::option::Option::Some(pubkey.clone()), + std::option::Option::Some(pubkey), std::option::Option::Some(10), std::option::Option::Some(20), ksp_store_api::RawSortDirection::Ascending, @@ -443,11 +443,11 @@ fn pre_007_account_cursor_rejects_replay_across_query_context_and_transaction_fa std::result::Result::Ok(value) => value, std::result::Result::Err(error) => panic!("valid account cursor encoding rejected: {error:?}"), }; - let other_network = page_query("mainnet-beta", Some(pubkey.clone()), Some(10), Some(20), ksp_store_api::RawSortDirection::Ascending); + let other_network = page_query("mainnet-beta", Some(pubkey), Some(10), Some(20), ksp_store_api::RawSortDirection::Ascending); let other_pubkey = page_query("devnet", Some(ksp_store_api::Pubkey::new_from_array([6_u8; 32])), Some(10), Some(20), ksp_store_api::RawSortDirection::Ascending); - let other_direction = page_query("devnet", Some(pubkey.clone()), Some(10), Some(20), ksp_store_api::RawSortDirection::Descending); - let other_range = page_query("devnet", Some(pubkey.clone()), Some(11), Some(20), ksp_store_api::RawSortDirection::Ascending); + let other_direction = page_query("devnet", Some(pubkey), Some(10), Some(20), ksp_store_api::RawSortDirection::Descending); + let other_range = page_query("devnet", Some(pubkey), Some(11), Some(20), ksp_store_api::RawSortDirection::Ascending); for candidate in [&other_network, &other_pubkey, &other_direction, &other_range] { let error = crate::decode_raw_account_cursor(candidate, &cursor).err(); assert_eq!(error.map(|value| return value.kind()), Some(crate::PostgresBackendErrorKind::QueryInvalid)); diff --git a/deltas/0.3.4/pre.007-fix.001.md b/deltas/0.3.4/pre.007-fix.001.md new file mode 100644 index 0000000..ab30d40 --- /dev/null +++ b/deltas/0.3.4/pre.007-fix.001.md @@ -0,0 +1,70 @@ + + + +# Delta `0.3.4-pre.007-fix.001` + +## Base + +```text +0.3.4-pre.007 +``` + +## Objectif + +Corriger exclusivement le gate opérateur de `pre.007` : cinq warnings Clippy `clone_on_copy` dans les tests cursor account et deux canaris historiques `pre.005/pre.006` qui interdisaient encore `list_raw_account_states` alors que cette surface est devenue légitime en `pre.007`. + +## Modifications + +- `workspace.package.version` passe à `0.3.4-pre.7.fix.1` ; +- suppression des cinq `Pubkey::clone()` inutiles dans `unit_tests/raw_account.rs` ; +- transformation des canaris historiques `pre.005/pre.006` pour conserver les interdictions destructives et les interdictions de capabilities `pre.008`, sans interdire la pagination account désormais possédée ; +- mise à jour du plan et de la validation pour tracer le gate et le correctif. + +## Invariants préservés + +```text +aucun changement src/raw_account.rs +aucun changement src/raw_account/cursor.rs +aucun changement src/runtime.rs +aucun changement SQL runtime +aucune migration V000/V001/V002 modifiée +aucune impl RawAccount* ouverte +aucun dispatch Store account ajouté +``` + +Le checksum V002 reste : + +```text +ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e +``` + +## Fichiers modifiés + +```text +Cargo.toml +crates/ksp-store-postgres-lib/tests/dependency_boundary.rs +crates/ksp-store-postgres-lib/unit_tests/raw_account.rs +docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md +docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md +``` + +## Fichier ajouté + +```text +deltas/0.3.4/pre.007-fix.001.md +``` + +## Gate opérateur à rejouer + +```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.4 +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-store-api +cargo test -p ksp-store-lib +cargo test -p ksp-store-postgres-lib +cargo test -p ksp-config-lib +cargo check -p ksp-store-lib --no-default-features +``` diff --git a/docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md b/docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md index 16a4b65..95d0d16 100644 --- a/docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md +++ b/docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md @@ -1,11 +1,11 @@ - + # Plan `0.3.4` — Store/PostgreSQL `RawAccountState` + complétude RAW ## 1. Statut de la release -`0.3.4-pre.001` a figé le design. `0.3.4-pre.002` a matérialisé la fondation physique V002 minimale puis `pre.002-fix.001` a corrigé deux canaris sans toucher au SQL. `0.3.4-pre.003` complète V002 avec les contraintes de domaine, l'index de navigation, la compatibilité de schéma et le checksum final ; `pre.003-fix.001` corrige uniquement l'ordre alphabétique du bloc `const` de `migration.rs` et son gate opérateur complet est PASS. `0.3.4-pre.004` ouvre le mapping PostgreSQL privé et les deux lectures `get` account ; `pre.004-fix.001` corrige uniquement leur conformité au profil Clippy KSP et un canari inutilisé, sans write, pagination ni implémentation de capability. +`0.3.4-pre.001` a figé le design. `0.3.4-pre.002` a matérialisé la fondation physique V002 minimale puis `pre.002-fix.001` a corrigé deux canaris sans toucher au SQL. `0.3.4-pre.003` complète V002 avec les contraintes de domaine, l'index de navigation, la compatibilité de schéma et le checksum final ; `pre.003-fix.001` corrige uniquement l'ordre alphabétique du bloc `const` de `migration.rs` et son gate opérateur complet est PASS. `0.3.4-pre.004` ouvre le mapping PostgreSQL privé et les deux lectures `get` account ; `pre.004-fix.001` corrige uniquement leur conformité au profil Clippy KSP et un canari inutilisé, sans write, pagination ni implémentation de capability. `pre.005` ajoute l'acquisition atomique, `pre.006` l'observation supplémentaire, et `pre.007` la pagination/cursor account ; son gate opérateur a révélé uniquement cinq `clone()` inutiles sur `Pubkey: Copy` et deux canaris historiques encore configurés pour interdire la pagination désormais légitime. Base canonique auditée : @@ -17,8 +17,8 @@ workspace.package.version = 0.3.3 Version de travail de cette prerelease : ```text -workspace.package.version = 0.3.4-pre.4.fix.1 -label = 0.3.4-pre.004-fix.001 +workspace.package.version = 0.3.4-pre.7.fix.1 +label = 0.3.4-pre.007-fix.001 ``` Décision de scope : `ksp-store-api` reste inchangée. L'audit n'a révélé aucun gap backend-agnostic bloquant ; la difficulté restante est exclusivement l'implémentation physique PostgreSQL et son dispatch par la façade. @@ -655,6 +655,12 @@ Le cursor V1 account est fixe à **109 bytes** : magic `KSPA`, version `1`, `las `PostgresBackend::list_raw_account_states` expose uniquement `RawAccountStateQuery -> RawPage`. Les quatre implémentations `RawAccount*` et le dispatch `Store` restent réservés à `pre.008`. +#### `pre.007-fix.001` — Réconciliation Clippy/canaris pagination + +**Statut : réalisé ; gate opérateur complet à rejouer.** + +Fix strictement borné aux tests/canaris : suppression de cinq `clone()` sur `Pubkey: Copy` dans les canaris cursor, et transformation des canaris hérités de `pre.005/pre.006` pour qu'ils continuent d'interdire `UPDATE`, `DELETE`, `ON CONFLICT DO UPDATE`, `OFFSET` et les quatre implémentations `RawAccount*`, sans interdire `list_raw_account_states` désormais possédée par `pre.007`. Aucun code de pagination, SQL métier ou migration n'est modifié. + ### `pre.008` — Implémentations backend, dispatch Store et conformance 10/10 **Statut : planifié.** diff --git a/docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md b/docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md index 5468f5c..87a6ec1 100644 --- a/docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md +++ b/docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md @@ -1,5 +1,5 @@ - + # Validation `0.3.4` — Store/PostgreSQL `RawAccountState` + complétude RAW @@ -503,7 +503,7 @@ La preuve de race/cancellation de cette tranche est volontairement unitaire/stru Restent fermés : `list_raw_account_states`, cursor `KSPA`, `OFFSET`, `UPDATE`/`DELETE`, `ON CONFLICT DO UPDATE`, les quatre implémentations `RawAccount*` sur `PostgresBackend` et tout dispatch account dans `Store`. Les migrations V000/V001/V002 sont inchangées ; le checksum V002 final reste `ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e`. ## 24. Verdict `pre.007` -Pagination `RawAccountStateQuery` et cursor `KSPA` : **PASS statique ; gate opérateur complet à rejouer**. +Pagination `RawAccountStateQuery` et cursor `KSPA` : **PASS fonctionnel ; gate `pre.007` non clos uniquement à cause de cinq warnings Clippy `clone_on_copy` et de deux canaris historiques stales. `pre.007-fix.001` corrige exclusivement ces tests/canaris ; gate opérateur complet à rejouer.** Ordre physique figé : @@ -539,3 +539,8 @@ PostgresBackend::list_raw_account_states( Les quatre `impl RawAccount* for PostgresBackend` et tout dispatch account dans `ksp-store-lib::Store` restent absents jusqu'à `pre.008`. Les migrations V000/V001/V002 restent byte-inchangées et le checksum V002 demeure `ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e`. +## 25. Verdict `pre.007-fix.001` + +Le fix ne modifie ni `src/raw_account.rs`, ni `src/raw_account/cursor.rs`, ni le SQL runtime, ni aucune migration. Les cinq `Pubkey::clone()` inutiles des tests cursor sont supprimés. Les canaris `pre.005/pre.006` sont transformés pour accepter `list_raw_account_states`, devenu scope légitime en `pre.007`, tout en continuant d'interdire les surfaces destructives (`UPDATE`, `DELETE`, `ON CONFLICT DO UPDATE`, `OFFSET`) et les quatre implémentations `RawAccount*` réservées à `pre.008`. + +Le checksum V002 reste `ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e`.