# Delta `0.3.4-pre.003` — contraintes, index et compatibilité V002 ## 1. Base Base appliquée : ```text 0.3.4-pre.002-fix.001 workspace.package.version = 0.3.4-pre.2.fix.1 ``` Le gate opérateur fourni le 2026-08-30 est intégralement vert : audits Rust/Markdown, `cargo check --workspace`, Clippy all-targets, suites `ksp-store-api`, `ksp-store-lib`, `ksp-store-postgres-lib`, `ksp-config-lib` et `cargo check -p ksp-store-lib --no-default-features` passent. Le backend PostgreSQL exécute notamment 43 tests unitaires sans échec après `pre.002-fix.001`. ## 2. Version Cette tranche contient des changements Rust/SQL fonctionnels : ```text workspace.package.version = 0.3.4-pre.3 label = 0.3.4-pre.003 ``` ## 3. Scope exécuté `pre.003` ferme uniquement le schéma physique V002 et sa compatibilité de migration. Aucun repository account ni dispatch façade n'est ouvert. Inventaire V002 final : ```text 2 tables 29 contraintes = 2 PK + 1 FK + 26 CHECK 1 index non unique 32 resources au total ``` Les 26 `CHECK` ajoutés matérialisent les invariants déjà possédés par `ksp-store-api` : - pubkeys, state hashes, observation keys et source hashes aux largeurs fixes attendues ; - transaction signature optionnelle à 64 bytes ; - `slot`, `lamports`, `rent_epoch`, `account_slot` et `write_version` dans le domaine `u64` exact, avec stockage `NUMERIC(20,0)` lorsque nécessaire ; - `data` account bornée à 16 MiB, vide autorisé ; - provenance logique obligatoire/optionnelle bornée à 1..128 octets avec l'alphabet sûr KSP ; - origin limité à `backfill`, `import`, `live`, `repair`, `replay` ; - timestamps bornés à `MAX_RAW_UNIX_MILLIS` et ordre `observed_at <= received_at` ; - source payload size optionnelle bornée à 64 MiB. `is_startup` reste un `BOOLEAN NULL` sans contrainte artificielle supplémentaire. ## 4. Index de navigation Un seul index métier est ajouté : ```text ix_ksp_raw_account_states_slot_pubkey_state_hash (slot, pubkey, state_hash) ``` Il est non unique et sans prédicat. Aucun index owner/provider/method/time/status n'est introduit sans query publique qui le justifie. ## 5. Checksum V002 final et transition de prerelease Checksum V002 intermédiaire écrit par `pre.002` : ```text 30ac87496f1bb3805d816660891d7eab2127c599a636eb40c17ade5926311f55 ``` Checksum V002 final calculé sur les 32 resources ordonnées : ```text ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e ``` V000 et V001 restent byte-inchangées et conservent leurs checksums : ```text V000 = d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450 V001 = 31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51 ``` Le moteur accepte le checksum V002 intermédiaire **uniquement** avec `schema_update=update_if_needed`. Dans ce cas, sous la transaction de migration existante : 1. l'historique reconnaît uniquement le checksum provisoire explicitement connu ; 2. les resources V002 manquantes sont matérialisées et réinspectées ; 3. la compatibilité externe V002 est vérifiée ; 4. l'entrée V002 de `ksp_store_schema_migrations` est remplacée par le checksum final avec un `UPDATE` conditionné par version, nom et ancien checksum ; 5. le commit publie ensemble schéma et historique final. Avec `schema_update=disabled`, le checksum provisoire reste un `MigrationMismatch`. Tout checksum V002 inconnu reste rejeté même avec update activé. ## 6. Schema compatibility V002 La vérification externe générique couvre désormais V001 et V002 avec leurs inventaires propres. Pour les deux tables account, elle conserve les mêmes principes que V001 : - colonnes attendues et types physiques compatibles ; - contraintes KSP attendues reconnues par nom/définition ; - extension externe bloquante rejetée ; - unique index externe non adossé à une contrainte rejeté ; - triggers/rules externes rejetés. Le probe d'adoption inclut désormais les deux tables V002 afin qu'un schéma KSP account existant sans metadata de migration ne soit pas considéré comme vide. Le contrat d'index interne supporte explicitement les deux formes possédées : V001 avec prédicat `retention_state <> 'purged'`, V002 sans prédicat. ## 7. Canaries et tests modifiés Les canaries backend prouvent désormais : - 32 resources V002, ordonnées par tables/constraints/index ; - inventaire exact 2/29/1 ; - checksum final exact et checksums V000/V001 stables ; - acceptation conditionnelle du checksum provisoire et rejet des historiques arbitraires ; - bornes physiques majeures et absence de narrowing `u64` ; - index unique de navigation non filtré/non unique ; - compatibilité externe V002 ; - absence persistante de `src/raw_account.rs`, d'implémentation `RawAccount*` et de dispatch runtime account. ## 8. Scope négatif préservé Cette tranche n'ajoute pas : ```text ksp-store-api change raw_account repository module RawAccount* implementation on PostgresBackend RawAccount* implementation on Store Store account dispatch account retention/archive/purge owner/provider/time/status indexes worker/job/backfill policy Transport -> Store coupling new backend ``` ## 9. Documentation `docs/plans/025-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT_PLAN.md` conserve le forecast souple sous forme de sous-paragraphes `### pre.NNN` / `#### pre.NNN-fix.MMM`. `pre.002-fix.001` y passe au statut gate opérateur complet PASS et `pre.003` au statut réalisé / gate opérateur à rejouer. `docs/validation/021-V0_3_4_STORE_POSTGRES_RAW_ACCOUNT.md` enregistre le gate vert de la base, l'inventaire V002 final, les checksums et la stratégie de transition de prerelease. ## 10. Validation exécutée dans l'environnement d'assemblage ```text python3 scripts/audit_rust_workspace_rules.py => General Rust rule audit: clean => Rust export completeness audit: 0 candidate(s) => KSP workspace Rust rule audit: clean python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas/0.3.4 => Markdown table audit: clean (239 table(s), 138 file(s)) ``` Le calcul indépendant de checksum sur les bytes des resources V002 donne : ```text ff21605ed45f7ab4c0f92bbb692700b4118a9488b04d50a31d259ac59bdb550e ``` `cargo`, `clippy` et les tests Rust ne sont pas disponibles dans l'environnement d'assemblage. Aucun résultat Cargo de `pre.003` n'est donc revendiqué ici. ## 11. Gate opérateur demandé ```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 ``` Les preuves PostgreSQL live account restent hors de cette tranche et sont prévues plus tard dans le forecast. ## 12. Fichiers Le delta contient uniquement `Cargo.toml`, les fichiers Rust/tests/schema réellement modifiés, les nouvelles resources V002, les deux documents de suivi modifiés et ce fichier `pre.003.md`. Aucun snapshot complet, aucune archive historique et aucun artefact de build ne sont inclus. ## 13. Verdict `0.3.4-pre.003` : **READY FOR OPERATOR GATE**.