v0.3.4-pre.010
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 377
|
||||
# version: 378
|
||||
|
||||
[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.9"
|
||||
version = "0.3.4-pre.10"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-lib/tests/hardening_completeness.rs
|
||||
// version: 5
|
||||
// version: 6
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -84,6 +84,27 @@ fn manifest_dependency_names(source: &str) -> std::vec::Vec<&str> {
|
||||
return names;
|
||||
}
|
||||
|
||||
fn raw_capability_trait_names<'a>(source: &'a str, implementor: &str) -> std::vec::Vec<&'a str> {
|
||||
let mut names = std::vec::Vec::new();
|
||||
for line in source.lines() {
|
||||
let trimmed = line.trim();
|
||||
if !trimmed.starts_with("impl ksp_store_api::Raw") || !trimmed.contains(implementor) {
|
||||
continue;
|
||||
}
|
||||
let trait_tail = match trimmed.strip_prefix("impl ksp_store_api::") {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => continue,
|
||||
};
|
||||
let trait_name = match trait_tail.split(" for ").next() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => continue,
|
||||
};
|
||||
names.push(trait_name);
|
||||
}
|
||||
names.sort_unstable();
|
||||
return names;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_009_facade_modules_and_crate_root_exports_are_exact() {
|
||||
let crate_root = include_str!("../src/lib.rs");
|
||||
@@ -284,3 +305,19 @@ fn pre_010_facade_raw_capability_inventory_is_exactly_ten() {
|
||||
assert_eq!(store.matches("validate_operation_network(").count(), 14);
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_facade_and_backend_raw_capability_sets_match_exactly_without_account_retention() {
|
||||
let store = include_str!("../src/store.rs");
|
||||
let backend = include_str!("../../ksp-store-postgres-lib/src/runtime.rs");
|
||||
let store_traits = raw_capability_trait_names(store, " for Store");
|
||||
let backend_traits = raw_capability_trait_names(backend, " for PostgresBackend");
|
||||
assert_eq!(store_traits.len(), 10);
|
||||
assert_eq!(backend_traits.len(), 10);
|
||||
assert_eq!(store_traits, backend_traits);
|
||||
for forbidden in ["RawAccountRetentionRead", "RawAccountRetentionWrite", "RawAccountDelete", "RawAccountCompaction"] {
|
||||
assert!(!store_traits.contains(&forbidden), "unexpected account capability added to Store: {forbidden}");
|
||||
assert!(!backend_traits.contains(&forbidden), "unexpected account capability added to PostgreSQL backend: {forbidden}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
|
||||
// version: 16
|
||||
// version: 17
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
@@ -342,3 +342,73 @@ fn pre_010_raw_transaction_private_sql_keeps_keyset_navigation_and_bounded_state
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_raw_account_private_sql_is_non_destructive_keyset_and_family_local() {
|
||||
let source = include_str!("../src/raw_account.rs");
|
||||
let cursor = include_str!("../src/raw_account/cursor.rs");
|
||||
for required in [
|
||||
"ON CONFLICT (pubkey, slot, state_hash) DO NOTHING",
|
||||
"ON CONFLICT (observation_key) DO NOTHING",
|
||||
"FOR UPDATE",
|
||||
"FOR KEY SHARE",
|
||||
"ORDER BY slot ASC, pubkey ASC, state_hash ASC",
|
||||
"ORDER BY slot DESC, pubkey DESC, state_hash DESC",
|
||||
"(slot, pubkey, state_hash) >",
|
||||
"(slot, pubkey, state_hash) <",
|
||||
] {
|
||||
assert!(source.contains(required), "required hardened RawAccount SQL contract missing: {required}");
|
||||
}
|
||||
for forbidden in [
|
||||
" OFFSET ",
|
||||
"SELECT *",
|
||||
"ON CONFLICT DO UPDATE",
|
||||
"UPDATE ksp_raw_account",
|
||||
"DELETE FROM ksp_raw_account",
|
||||
"TRUNCATE",
|
||||
"batch_size",
|
||||
"priority",
|
||||
] {
|
||||
assert!(!source.contains(forbidden), "forbidden RawAccount scope/policy SQL detected: {forbidden}");
|
||||
}
|
||||
for required in ["b\"KSPA\"", "KSP/raw-account-state-cursor/v1", "CURSOR_BYTES: usize = 109"] {
|
||||
assert!(cursor.contains(required), "missing hardened RawAccount cursor family contract: {required}");
|
||||
}
|
||||
assert!(!cursor.contains("b\"KSPT\""));
|
||||
let state_fk = include_str!("../migrations/v002_raw_account_state/constraints/003_fk_ksp_raw_account_observations_state.sql");
|
||||
let transaction_signature = include_str!("../migrations/v002_raw_account_state/constraints/028_ck_ksp_raw_account_observations_transaction_signature.sql");
|
||||
assert!(state_fk.contains("REFERENCES ksp_raw_account_states(pubkey, slot, state_hash)"));
|
||||
assert!(!state_fk.contains("ksp_raw_transactions"));
|
||||
assert!(transaction_signature.contains("octet_length(transaction_signature) = 64"));
|
||||
assert!(!transaction_signature.contains("REFERENCES"));
|
||||
assert!(!transaction_signature.contains("ksp_raw_transactions"));
|
||||
return;
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pre_010_v002_schema_inventory_is_exact_family_local_and_query_justified() {
|
||||
let schema = include_str!("../src/schema.rs");
|
||||
let v002_tail = match schema.split("pub(crate) const V002_RESOURCES: &[SchemaResource] = &[").nth(1) {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => panic!("V002 resource inventory missing"),
|
||||
};
|
||||
let v002 = match v002_tail.split("\n];").next() {
|
||||
std::option::Option::Some(value) => value,
|
||||
std::option::Option::None => panic!("V002 resource inventory terminator missing"),
|
||||
};
|
||||
assert_eq!(v002.matches("SchemaResource {").count(), 32);
|
||||
assert_eq!(v002.matches("SchemaObjectContract::Table(").count(), 2);
|
||||
assert_eq!(v002.matches("kind: \"p\"").count(), 2);
|
||||
assert_eq!(v002.matches("kind: \"f\"").count(), 1);
|
||||
assert_eq!(v002.matches("kind: \"c\"").count(), 26);
|
||||
assert_eq!(v002.matches("SchemaObjectContract::Index(").count(), 1);
|
||||
assert_eq!(v002.matches("predicate_fragment: std::option::Option::None").count(), 1);
|
||||
assert!(v002.contains("key_fragment: \"slot,pubkey,state_hash\""));
|
||||
assert!(!v002.contains("ksp_raw_transactions"));
|
||||
assert!(!v002.contains("ksp_raw_transaction_observations"));
|
||||
for forbidden in ["owner", "provider", "received_at_unix_millis", "acquisition_method"] {
|
||||
let index_marker = std::format!("key_fragment: \"{forbidden}");
|
||||
assert!(!v002.contains(index_marker.as_str()), "unjustified V002 business index detected: {forbidden}");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
49
deltas/0.3.4/pre.010.md
Normal file
49
deltas/0.3.4/pre.010.md
Normal file
@@ -0,0 +1,49 @@
|
||||
<!-- file: deltas/0.3.4/pre.010.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.4-pre.010` — hardening et complétude cross-family
|
||||
|
||||
## Base
|
||||
|
||||
Base directe : `0.3.4-pre.009`. Le gate opérateur standard de `pre.009` est PASS et le live `postgres_raw_account_live` est PASS sur PostgreSQL 17 avec URI dédiée lue depuis stdin.
|
||||
|
||||
## Scope
|
||||
|
||||
Cette tranche est strictement limitée aux canaris de hardening et de complétude. Aucun runtime, SQL, migration, modèle API, capability ou export public n'est ajouté.
|
||||
|
||||
Modifications fonctionnelles de tests :
|
||||
|
||||
- `ksp-store-postgres-lib/tests/hardening_completeness.rs` fige la surface SQL account non destructive/keyset-only, la séparation `KSPA`/`KSPT`, l'absence de FK cross-family et l'inventaire V002 exact de 32 resources ;
|
||||
- `ksp-store-lib/tests/hardening_completeness.rs` compare directement les ensembles de capabilities RAW de `Store` et `PostgresBackend`, qui doivent être exactement identiques à dix traits, sans retention/delete/compaction account.
|
||||
|
||||
## Invariants préservés
|
||||
|
||||
```text
|
||||
ksp-store-api inchangée
|
||||
ksp-store-lib/src inchangé
|
||||
ksp-store-postgres-lib/src inchangé
|
||||
tests live inchangés
|
||||
migrations V000/V001/V002 byte-inchangées
|
||||
V002 checksum ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e
|
||||
RAW capabilities PostgresBackend 10
|
||||
RAW capabilities Store 10
|
||||
```
|
||||
|
||||
## Contrôles d'assemblage
|
||||
|
||||
Les audits Rust et Markdown doivent passer avant packaging. L'environnement d'assemblage ne possède pas Cargo ; le gate opérateur complet reste donc requis après application du delta.
|
||||
|
||||
## 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
|
||||
```
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md -->
|
||||
<!-- version: 15 -->
|
||||
<!-- version: 16 -->
|
||||
|
||||
# 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é. `pre.005` ajoute l'acquisition atomique, `pre.006` l'observation supplémentaire, `pre.007` la pagination/cursor account et `pre.007-fix.001` réconcilie ses canaris ; le gate opérateur complet du fix est PASS. `pre.008` ouvre les quatre capabilities account sur `PostgresBackend` puis leur dispatch dans `Store`, pour porter l'inventaire RAW à 10/10 sans nouveau SQL ; `pre.008-fix.001` corrige son unique canari mal réconcilié et son gate opérateur complet est PASS. `pre.009` ajoute la preuve PostgreSQL live account et réconcilie l'isolation du live RawTransaction avec le schéma V002 complet.
|
||||
`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é. `pre.005` ajoute l'acquisition atomique, `pre.006` l'observation supplémentaire, `pre.007` la pagination/cursor account et `pre.007-fix.001` réconcilie ses canaris ; le gate opérateur complet du fix est PASS. `pre.008` ouvre les quatre capabilities account sur `PostgresBackend` puis leur dispatch dans `Store`, pour porter l'inventaire RAW à 10/10 sans nouveau SQL ; `pre.008-fix.001` corrige son unique canari mal réconcilié et son gate opérateur complet est PASS. `pre.009` ajoute la preuve PostgreSQL live account et réconcilie l'isolation du live RawTransaction avec le schéma V002 complet ; son gate standard et son live account sur PostgreSQL 17 sont PASS. `pre.010` ferme le hardening et la complétude cross-family sans modifier le runtime ou les migrations.
|
||||
|
||||
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.9
|
||||
label = 0.3.4-pre.009
|
||||
workspace.package.version = 0.3.4-pre.10
|
||||
label = 0.3.4-pre.010
|
||||
```
|
||||
|
||||
Décision de scope : `ksp-store-api` reste inchangée. L'inventaire backend/façade est désormais 10/10 ; les tranches restantes portent uniquement sur la preuve PostgreSQL réelle, le hardening cross-family, le gate final et la réconciliation documentaire.
|
||||
@@ -687,7 +687,7 @@ Fix strictement borné à `tests/dependency_boundary.rs` : la déclaration `runt
|
||||
|
||||
### `pre.009` — Preuve PostgreSQL live account
|
||||
|
||||
**Statut : réalisé ; gate opérateur standard à rejouer, live opt-in à exécuter sur URI dédiée.**
|
||||
**Statut : réalisé ; gate opérateur standard PASS et live account PASS sur PostgreSQL 17.**
|
||||
|
||||
Budget cible : **15-20 min**. La preuve réelle est matérialisée dans `tests/postgres_raw_account_live.rs`, ignored/opt-in et alimentée exclusivement par une URI dédiée lue depuis stdin sans écho. Elle refuse tout schéma KSP déjà présent, exige PostgreSQL >= 15, ouvre/ferme/re-ouvre le backend V002, vérifie la réparation de l'index account selon `schema_autoupdate`, puis nettoie uniquement le schéma qu'elle a prouvé absent avant démarrage.
|
||||
|
||||
@@ -697,9 +697,15 @@ La coexistence cross-family est prouvée dans le même schéma : une acquisition
|
||||
|
||||
### `pre.010` — Hardening et complétude cross-family
|
||||
|
||||
**Statut : planifié.**
|
||||
**Statut : réalisé ; gate opérateur complet à rejouer.**
|
||||
|
||||
Budget cible : **15-20 min**. Fermer les canaries de sécurité, ownership et complétude cross-family sans ajouter de nouveau scope métier.
|
||||
Budget cible : **15-20 min**. La tranche n'ajoute aucun runtime, SQL, migration, capability ou type public. Elle ferme les canaris de sécurité, ownership et complétude cross-family autour de la surface effectivement validée.
|
||||
|
||||
Les canaris backend figent désormais explicitement : surface SQL account non destructive et keyset-only ; cursor `KSPA` distinct du cursor transaction `KSPT` ; V002 exactement 32 resources (2 tables, 2 PK, 1 FK state-local, 26 CHECK, 1 index non filtré) ; absence totale de table/FK/registry transaction dans V002 ; `transaction_signature` account reste une metadata fixed-width sans FK vers `ksp_raw_transactions`.
|
||||
|
||||
Les canaris façade comparent directement les noms des dix traits RAW implémentés par `Store` et `PostgresBackend`, imposent l'égalité exacte des deux ensembles et interdisent toute apparition implicite de retention/delete/compaction account. Les inventaires publics, dépendances, guards réseau, erreurs sûres, absence d'environnement/SQL physique dans la façade et placement des implémentations backend restent couverts par les canaris hérités.
|
||||
|
||||
`ksp-store-api`, tous les fichiers `src/`, les tests live et les migrations V000/V001/V002 restent byte-inchangés par cette tranche.
|
||||
|
||||
### `pre.011` — Gate technique final
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<!-- file: docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md -->
|
||||
<!-- version: 14 -->
|
||||
<!-- version: 15 -->
|
||||
|
||||
# Validation `0.3.4` — Store/PostgreSQL `RawAccountState` + complétude RAW
|
||||
|
||||
## 1. Portée
|
||||
|
||||
Cette matrice est ouverte par `0.3.4-pre.001`. `0.3.4-pre.002` matérialise la fondation V002 minimale et `pre.002-fix.001` corrige deux canaris sans modifier le SQL ; son gate opérateur complet est PASS. `0.3.4-pre.003` complète les contraintes de domaine, l'index de navigation, la compatibilité externe et le checksum V002 final ; `pre.003-fix.001` corrige uniquement l'ordre alphabétique du bloc `const` et son gate opérateur complet est PASS. `pre.004` à `pre.007` matérialisent successivement mapping/read, writes, observation supplémentaire et pagination account ; `pre.007-fix.001` clôt son gate opérateur en PASS. `pre.008` ouvre les quatre capabilities account dans `PostgresBackend` et `Store`, portant l'inventaire RAW statique à 10/10 ; `pre.008-fix.001` corrige son unique canari mal réconcilié et son gate opérateur complet est PASS. `pre.009` matérialise la preuve PostgreSQL live account, la concurrence/cancellation réelle et la coexistence RawTransaction sans modifier les migrations.
|
||||
Cette matrice est ouverte par `0.3.4-pre.001`. `0.3.4-pre.002` matérialise la fondation V002 minimale et `pre.002-fix.001` corrige deux canaris sans modifier le SQL ; son gate opérateur complet est PASS. `0.3.4-pre.003` complète les contraintes de domaine, l'index de navigation, la compatibilité externe et le checksum V002 final ; `pre.003-fix.001` corrige uniquement l'ordre alphabétique du bloc `const` et son gate opérateur complet est PASS. `pre.004` à `pre.007` matérialisent successivement mapping/read, writes, observation supplémentaire et pagination account ; `pre.007-fix.001` clôt son gate opérateur en PASS. `pre.008` ouvre les quatre capabilities account dans `PostgresBackend` et `Store`, portant l'inventaire RAW statique à 10/10 ; `pre.008-fix.001` corrige son unique canari mal réconcilié et son gate opérateur complet est PASS. `pre.009` matérialise la preuve PostgreSQL live account, la concurrence/cancellation réelle et la coexistence RawTransaction sans modifier les migrations ; son gate standard et son live account sur PostgreSQL 17 sont PASS. `pre.010` ferme les canaris cross-family sans modifier le runtime.
|
||||
|
||||
Base :
|
||||
|
||||
@@ -603,7 +603,7 @@ Le checksum V002 reste `ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac5
|
||||
|
||||
## 28. Verdict `pre.009`
|
||||
|
||||
Preuve PostgreSQL live `RawAccountState` : **matérialisée ; gate opérateur standard et exécution live opt-in à rejouer**.
|
||||
Preuve PostgreSQL live `RawAccountState` : **PASS complet opérateur**.
|
||||
|
||||
Nouveau test :
|
||||
|
||||
@@ -653,9 +653,27 @@ Matrice matérialisée :
|
||||
|
||||
Le test `postgres_raw_transaction_live.rs` est ajusté uniquement sur son inventaire de schéma managé : il probe et supprime désormais aussi `ksp_raw_account_states` et `ksp_raw_account_observations`, nécessaires depuis V002. Aucun scénario métier RawTransaction n'est modifié.
|
||||
|
||||
Le gate standard du 2026-08-30 est PASS : audits Rust/Markdown, workspace check, Clippy all-targets, Store API, Store façade, backend PostgreSQL, Config et `--no-default-features` sont verts. Le live account est ensuite PASS sur PostgreSQL 17 en 2,72 s, avec URI dédiée lue depuis stdin sans écho.
|
||||
|
||||
Les migrations V000/V001/V002 restent byte-inchangées ; le checksum V002 reste :
|
||||
|
||||
```text
|
||||
ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e
|
||||
```
|
||||
|
||||
## 29. Verdict `pre.010`
|
||||
|
||||
Hardening et complétude cross-family : **matérialisés ; gate opérateur complet à rejouer**.
|
||||
|
||||
Aucun fichier de production n'est modifié. Les nouveaux canaris backend vérifient que le SQL account reste limité aux lectures, inserts idempotents, locks et pagination keyset ; ils interdisent `UPDATE`, `DELETE`, `TRUNCATE`, `OFFSET`, `ON CONFLICT DO UPDATE` et toute policy worker. Le cursor account reste `KSPA`, domaine `KSP/raw-account-state-cursor/v1`, 109 bytes, distinct de `KSPT`.
|
||||
|
||||
Le registre V002 est figé à exactement 32 resources : 2 tables, 2 PK, 1 FK observation->state, 26 CHECK et 1 index `(slot,pubkey,state_hash)` non filtré. Les canaris imposent l'absence de `ksp_raw_transactions` et `ksp_raw_transaction_observations` dans V002. Le CHECK de `transaction_signature` impose seulement 64 bytes lorsqu'elle est présente et aucune FK transaction.
|
||||
|
||||
La façade compare directement son inventaire de traits RAW avec celui de `PostgresBackend` : les deux ensembles doivent être strictement identiques et contenir exactement dix capabilities. Aucune capability account de retention, delete ou compaction n'est admise.
|
||||
|
||||
Les fichiers `ksp-store-api`, `ksp-store-lib/src`, `ksp-store-postgres-lib/src`, les tests live et les migrations V000/V001/V002 restent inchangés. Le checksum V002 demeure :
|
||||
|
||||
```text
|
||||
ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user