diff --git a/CHANGELOG.md b/CHANGELOG.md index 24c5a36..13f9fce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,18 @@ - + # Changelog KSP +## 0.3.2 — Store/PostgreSQL runtime foundation — 2026-08-30 + +`0.3.2` introduit ensemble `ksp-store-lib` et `ksp-store-postgres-lib` comme fondation runtime/backend PostgreSQL au-dessus des contrats backend-agnostic de `ksp-store-api`, sans encore implémenter de capability RAW métier. La façade `Store` conserve un backend connu `Postgres` activé par défaut via Cargo feature, reste compilable avec `--no-default-features`, lie chaque instance à exactement un `RawNetworkId` et n'expose aucun `Pool`, `Client`, `Row`, `Statement`, driver ou SQL physique. `ksp-config-lib` possède désormais `std.store` avec trois targets nommés `devnet`, `mainnet` et `testnet`, chacun associé à un réseau explicite et à une URI PostgreSQL Secret indépendante ; Store/backend ne lisent directement ni `.env`, ni `KSP_*`, ni `PG*`, ni `.pgpass`. + +Le backend de référence utilise `tokio-postgres 0.7.18`, `deadpool-postgres 0.14.2`, `tokio-postgres-rustls 0.14.0`, Rustls 0.23 avec roots système/AWS-LC et des modes TLS KSP limités à `Disabled` et `VerifyFull`. Les URI sont parsées puis normalisées sous la policy typée KSP, le pool et les deadlines connect/wait/create/recycle/shutdown sont bornés, et une ouverture réussie exige une connexion physique puis un bootstrap valide. Le moteur de migrations privé commence par `V000__bootstrap.sql`, enregistre version/nom/SHA-256 dans `ksp_store_schema_migrations`, sérialise les runners par advisory transaction lock borné et refuse checksum mismatch ou schema plus récent sans down automatique. La façade fournit également `runtime_snapshot()` et `health().await` avec une projection portable/redacted de readiness et des compteurs pool sûrs. + +Les canaris de hardening verrouillent 84 exports crate-root côté façade, la frontière backend/Config, l'absence de bypass environnement, la redaction des URI/erreurs, la matrice de features et l'absence de persistence `RawTransaction`/`RawAccountState`. Le gate technique final a été rejoué après `cargo clean` : audits Rust/Markdown, `cargo check --workspace`, Clippy, tests ciblés de toutes les crates, `cargo test --workspace`, graphes Cargo et les trois builds Tauri Linux passent. Le smoke PostgreSQL réel passe sur **PostgreSQL 17** et prouve bootstrap initial/idempotent/concurrent, mismatch/recovery checksum, rollback transactionnel, health `Ready` et fermeture bornée ; la policy de fondation reste PostgreSQL >= 15 sans maximum KSP artificiel. + +`prompts/022-V0_3_3_START_PROMPT.md` ouvre ensuite uniquement la vertical slice PostgreSQL `RawTransaction` complète sur les mêmes crates et la même fondation : six capabilities transaction/observation/rétention, atomicité, idempotence/conflit, get/list cursorisé, tombstone et `ForceRehydrate`. `RawAccountState` PostgreSQL et la complétude RAW restent réservés à `0.3.4`. L'archive historique `khadhroony-bot3_v0.5.3-pre.005-fix010.zip` reste obligatoire au `pre.001` de `0.3.3`, mais seulement pour réauditer l'ancien schéma/repository RAW transaction comme source d'héritage, jamais comme autorité KSP. + ## 0.3.1 — Store API RAW foundation — 2026-08-29 `0.3.1` introduit `ksp-store-api` comme contrat backend-agnostic de persistence N1 RAW, sans runtime Store ni backend physique. La release stabilise deux familles réellement convergentes : `RawTransaction` avec payload canonique opaque/versionné, identité réseau+signature et observations d’acquisition séparées, puis `RawAccountState` avec bytes complets, identité réseau+pubkey+slot+hash et observations pouvant conserver les enrichissements Yellowstone sans les confondre avec l’état canonique. `TransactionStatusObservation` reste reporté faute de convergence sémantique suffisante entre snapshot HTTP, transition WebSocket et update Yellowstone ; `logsSubscribe`, slot/root/slotsUpdates et vote restent event-only candidats, `RawBlock` reste une idée conditionnelle et Yellowstone `Entry` reste rejeté de la taxonomie active. diff --git a/Cargo.toml b/Cargo.toml index 5f9ac8c..1cf63bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ # file: Cargo.toml -# version: 345 +# version: 346 [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.2-pre.11" +version = "0.3.2-pre.12" edition = "2024" license = "MIT" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" diff --git a/ROADMAP.md b/ROADMAP.md index 4ef07f0..8c7ff11 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,5 @@ - + # Roadmap KSP @@ -94,8 +94,8 @@ RAW -> STRUCTURAL -> DECODED -> DOMAIN ## 0.3.x — RAW / acquisition persistée - [X] `0.3.1` — `ksp-store-api` stable : modèles N1 RAW backend-agnostic `RawTransaction` et `RawAccountState` avec observations, provenance, payload/hash/timestamps bornés, 10 capabilities object-safe, queries cursorisées sans plafond métier arbitraire, outcomes idempotence/conflit et lifecycle logique rétention/tombstone/force-rehydrate ; aucun backend physique, Config, runtime Store, notification dédiée ni surface STRUCTURAL/DECODED/DOMAIN. -- [ ] `0.3.2` — Introduire ensemble `ksp-store-lib` et `ksp-store-postgres-lib` pour la **fondation runtime/backend PostgreSQL uniquement** : façade Store, feature `postgres` par défaut, dispatch des backends compilés, Config `std.store`/secrets, connexion/pool/TLS à réauditer, bootstrap/migrations privés et health/readiness seulement si un contrat portable est réellement justifié. Aucun schéma `RawTransaction`/`RawAccountState` n’est ajouté dans cette slice. -- [ ] `0.3.3` — Étendre le même couple `ksp-store-lib` + `ksp-store-postgres-lib` avec la vertical slice PostgreSQL `RawTransaction` complète : persistence/observation atomiques, get/list cursorisé, idempotence/conflit, rétention/tombstone/force-rehydrate, concurrence et rollback validés sur PostgreSQL réel. +- [X] `0.3.2` — `ksp-store-lib` + `ksp-store-postgres-lib` stables comme fondation runtime/backend PostgreSQL : feature `postgres` par défaut, `Store` lié à un unique `RawNetworkId`, Config `std.store` avec targets/bases `devnet`/`mainnet`/`testnet`, pool Deadpool borné, `tokio-postgres`, TLS Rustls `Disabled`/`VerifyFull`, moteur de migrations privé `V000` + SHA-256/advisory lock, health/readiness portable et close borné. Gate complet + PostgreSQL réel major 17 verts ; aucune table/capability `RawTransaction`/`RawAccountState` métier n'est encore ajoutée. +- [ ] `0.3.3` — Étendre le même couple avec la vertical slice PostgreSQL `RawTransaction` complète : les six capabilities transaction/observation/rétention de `ksp-store-api`, persistence acquisition atomique, get/list cursorisé, idempotence/conflit, binding réseau, rétention/tombstone/force-rehydrate, concurrence et rollback validés sur PostgreSQL réel. - [ ] `0.3.4` — Étendre le même couple avec `RawAccountState` + observation, puis fermer la complétude/conformance RAW cross-family, les indexes/migrations physiques nécessaires et le hardening PostgreSQL final. - [ ] `0.3.5` — Étendre `ksp-interface-lib` uniquement avec les modèles passifs/events réellement partagés par les premiers consumers d’acquisition, sans dupliquer les modèles persistants de `ksp-store-api`. - [ ] `0.3.6` — Introduire `ksp-job-api` et un premier job de backfill historique concret consommant `ksp-store-lib`, avec policy/batch-size/progression possédés par le job et non par Store. diff --git a/deltas/0.3.2/pre.012.md b/deltas/0.3.2/pre.012.md new file mode 100644 index 0000000..dd834ba --- /dev/null +++ b/deltas/0.3.2/pre.012.md @@ -0,0 +1,320 @@ + + + +# Delta `0.3.2-pre.012` — préparation de publication et prompt `0.3.3` + +## 1. Base requise + +Base directe attendue : + +```text +0.3.2-pre.011 +workspace.package.version = 0.3.2-pre.11 +``` + +Le gate opérateur de `pre.011`, exécuté le **30 août 2026**, est entièrement vert : + +```text +cargo fmt --all PASS +python3 scripts/audit_rust_workspace_rules.py PASS / clean +python3 scripts/audit_markdown_tables.py PASS / clean — 186 tables / 142 fichiers +cargo check --workspace PASS +cargo clippy --workspace --all-targets PASS +cargo test -p ksp-store-api PASS +cargo test -p ksp-store-lib PASS +cargo test -p ksp-store-lib --no-default-features PASS +cargo test -p ksp-store-postgres-lib PASS +cargo test -p ksp-config-lib PASS — 126 unit tests + ownership/public API +cargo check -p ksp-store-lib --no-default-features PASS +``` + +Le gate technique complet de référence de `pre.010` reste également acquis : il a été rejoué après `cargo clean`, passe `cargo test --workspace`, les graphes Cargo, les trois builds Tauri Linux et le live PostgreSQL sur **major 17**. + +## 2. Objectif + +Dernière prerelease avant `rel.001`, strictement limitée à la préparation de publication minimale définie par `VER-LIFECYCLE-003` : + +```text +bump workspace vers 0.3.2-pre.12 +entrée stable candidate 0.3.2 dans CHANGELOG.md +fermeture 0.3.2 et précision de 0.3.3 dans ROADMAP.md +création du prompt 0.3.3 +delta pre.012 +``` + +Aucun code, test, manifest de crate, README/USAGE, plan, validation, architecture, règle, config, schema ou migration n'est rouvert. + +## 3. Version Cargo + +```text +0.3.2-pre.11 +-> 0.3.2-pre.12 +``` + +Le header `Cargo.toml` passe de la version fichier `345` à `346` parce que le fichier est réellement modifié. + +## 4. Changelog `0.3.2` + +`CHANGELOG.md` enregistre la fondation stable candidate réellement livrée : + +```text +ksp-store-lib + ksp-store-postgres-lib +feature postgres par défaut +Store lié à exactement un RawNetworkId +Config std.store avec targets devnet/mainnet/testnet et URI Secret séparées +tokio-postgres + Deadpool + Rustls +TLS Disabled / VerifyFull +pool/connect/wait/create/recycle/shutdown bornés +V000 bootstrap + ksp_store_schema_migrations +history version/name/SHA-256 +advisory transaction lock +health/readiness portable et redacted +84 exports crate-root façade au gate hardening +aucune capability/table RawTransaction ou RawAccountState métier +``` + +Il enregistre également le gate technique complet, le live PostgreSQL major 17 et la policy supportée PostgreSQL >= 15. + +## 5. Roadmap + +`ROADMAP.md` : + +```text +passe 0.3.2 à [X] +remplace les formulations prospectives par la fondation réellement livrée +conserve 0.3.3 ouverte comme vertical slice RawTransaction complète +précise que 0.3.3 couvre les six capabilities transaction/observation/rétention +conserve RawAccountState + complétude RAW pour 0.3.4 +``` + +La séparation durable reste : + +```text +Store = persistence/navigation +workers/jobs/executors = batch-size, priorité, backlog et policy +``` + +## 6. Prompt `0.3.3` + +Le nouveau prompt : + +```text +prompts/022-V0_3_3_START_PROMPT.md +``` + +est confronté à : + +```text +docs/rules/PROMPT_STRUCTURE.md +docs/rules/VERSION_WORKFLOW.md +docs/rules/FILE_CONTRACTS.md +docs/rules/RULES_KSP.md +docs/rules/RULES_DEPENDENCIES.md + +docs/architecture/003-COMPONENT_CONTRACTS.md +docs/architecture/004-COMPONENT_INVENTORY.md +docs/architecture/005-DEPENDENCY_GRAPH.md +docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md +docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md + +docs/plans/022-V0_3_1_STORE_RAW_PLAN.md +docs/validation/018-V0_3_1_STORE_RAW.md +docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md +docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md + +crates/ksp-store-api/src/** +crates/ksp-store-lib/src/** +crates/ksp-store-postgres-lib/src/** +``` + +Il impose une première tranche `pre.001` d'audit/design avant tout SQL métier lourd. + +## 7. Archive historique requise pour la session suivante + +L'archive : + +```text +khadhroony-bot3_v0.5.3-pre.005-fix010.zip +``` + +reste **obligatoire au `0.3.3-pre.001`**, mais sa portée est réduite à l'ancien RAW transaction PostgreSQL : + +```text +raw transaction table +transaction observations +indexes/constraints +raw queries +raw transaction repository +contrats DTO/entity/repository pertinents +``` + +Elle sert à produire une matrice : + +```text +REPRENDRE / REDESSINER / REPORTER / REJETER +``` + +Elle n'est ni une base de code ni une autorité sur `ksp-store-api` ou l'architecture KSP actuelle. + +## 8. Scope strict du prompt suivant + +`0.3.3` doit implémenter les six capabilities : + +```text +RawTransactionRead +RawTransactionWrite +RawTransactionObservationRead +RawTransactionObservationWrite +RawTransactionRetentionRead +RawTransactionRetentionWrite +``` + +sur le même couple Store/PostgreSQL, avec notamment : + +```text +migration métier à partir de V001 +atomicité canonical + observation +idempotence identical +ERROR_CODE_RAW_CONFLICT pour contenu divergent +get/list cursorisé +network mismatch avant I/O +retention/tombstone/ForceRehydrate +concurrence/rollback +PostgreSQL live gate +``` + +Le prompt force `pre.001` à fermer plusieurs questions physiques importantes avant code lourd : + +```text +binding de la database au RawNetworkId +représentation PostgreSQL des u64/u32 sans narrowing +ordre total + format du cursor +concurrence/idempotence +rétention physique honnête pour Full/Compacted/Archived/Purged +error mapping SQL sûr +``` + +Sont explicitement réservés : + +```text +0.3.4 -> RawAccountState PostgreSQL + complétude RAW +0.3.5 -> Interface events partagés si consumer réel +0.3.6 -> Job API + premier backfill +0.3.7 -> application backfill/inspection +``` + +## 9. Prévision souple intégrée au prompt + +Le prompt réserve : + +```text +pre.001 audit contrats/kbot3/schema/concurrence/sizing +pre.002 migration V001 + schema/indexes +pre.003 mapping physique + lectures +pre.004 persistence acquisition atomique + observations +pre.005 list/query + cursor +pre.006 retention/tombstone/ForceRehydrate +pre.007 composition façade + conformance six capabilities +pre.008 PostgreSQL integration réelle RawTransaction +pre.009 hardening/completeness +pre.010 gate technique final +pre.011 réconciliation documentaire +pre.012 préparation de publication +rel.001 publication stable +``` + +La prévision reste souple et doit être recalibrée par `0.3.3-pre.001` selon le budget de 15–20 minutes par tranche intermédiaire. + +## 10. Fichiers ajoutés + +```text +prompts/022-V0_3_3_START_PROMPT.md +deltas/0.3.2/pre.012.md +``` + +## 11. Fichiers modifiés + +```text +Cargo.toml +CHANGELOG.md +ROADMAP.md +``` + +## 12. Fichiers supprimés + +```text +aucun +``` + +## 13. Surfaces explicitement non rouvertes + +```text +README.md +RULES.md +.env.example +config/** +crates/** +docs/** +prompts/001..021 +``` + +En particulier : + +```text +crates/ksp-store-api/** +crates/ksp-store-lib/** +crates/ksp-store-postgres-lib/** +docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md +docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md +docs/architecture/** +``` + +## 14. Validations de préparation + +À exécuter sur l'arbre reconstruit : + +```text +audit Rust workspace +audit Markdown +contrôle exact du payload overlay +contrôle versions/file headers +contrôle qu'aucun fichier hors lane n'est modifié +``` + +Aucun résultat Cargo nouveau n'est revendiqué par l'environnement de génération si Cargo n'y est pas disponible. + +## 15. Gate opérateur + +La lane est documentaire/de publication ; le gate ciblé suffit : + +```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/0.3.2 +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 +``` + +Le live PostgreSQL, les trois builds Tauri et le workspace lourd n'ont pas besoin d'être rejoués dans cette tranche puisque `pre.012` ne touche aucune surface runtime/build/config/dependency. + +## 16. Étape suivante + +Si le gate reste vert : + +```text +0.3.2-rel.001 +``` + +La publication stable doit être strictement mécanique : + +```text +workspace.package.version = 0.3.2 +deltas/0.3.2/rel.001.md +``` + +`rel.001` ne doit rouvrir ni `CHANGELOG.md`, ni `ROADMAP.md`, ni le prompt `0.3.3`, ni aucun autre document/code. diff --git a/prompts/022-V0_3_3_START_PROMPT.md b/prompts/022-V0_3_3_START_PROMPT.md new file mode 100644 index 0000000..c95ae51 --- /dev/null +++ b/prompts/022-V0_3_3_START_PROMPT.md @@ -0,0 +1,1172 @@ + + + +# Prompt de démarrage `0.3.3` — Store/PostgreSQL `RawTransaction` vertical slice + +## 1. Identité de la release et base exacte requise + +La release à ouvrir est : + +```text +0.3.3 — Store/PostgreSQL RawTransaction vertical slice +``` + +La base autoritaire attendue est exclusivement la release stable : + +```text +v0.3.2 +workspace.package.version = 0.3.2 +``` + +La nouvelle session doit partir de l'archive opérateur stable `0.3.2` lorsqu'elle est fournie. Cette archive gagne sur les souvenirs, snippets, anciens overlays et prompts intermédiaires. + +L'archive historique suivante est également **obligatoire pour `pre.001`** : + +```text +khadhroony-bot3_v0.5.3-pre.005-fix010.zip +``` + +Elle sert uniquement à auditer l'ancien schéma/repository PostgreSQL des transactions RAW et leurs observations. Elle n'est jamais une base de code ni une autorité architecturale. + +Ne pas ouvrir `0.3.3` depuis : + +```text +0.3.2-pre.* +0.3.2-pre.*-fix.* +0.3.2-rel.* non encore publié stable +une archive de travail intermédiaire +khadhroony-bot3 comme base de code +un souvenir de session +``` + +À l'ouverture, vérifier au minimum : + +```text +tag Git v0.3.2 si metadata Git disponible +workspace.package.version = 0.3.2 +deltas/0.3.2/rel.001.md présent +prompts/022-V0_3_3_START_PROMPT.md présent +ksp-store-api présent +ksp-store-lib présent +ksp-store-postgres-lib présent +migration bootstrap V000 présente +Config std.store présent +archive khadhroony-bot3_v0.5.3-pre.005-fix010.zip disponible +``` + +Si une divergence existe entre ce prompt et la base stable réelle, **la base stable réelle gagne** et la divergence devient une sortie explicite de `pre.001`. + +`pre.001` reste obligatoirement une tranche de **lecture + audit + brainstorming + threat model + design physique + sizing + planification**. Ne pas commencer la migration métier `RawTransaction` ni les repositories SQL avant la sortie cohérente de ce gate. + +--- + +## 2. Mission et résultat attendu + +`0.3.3` étend le couple existant : + +```text +ksp-store-lib +ksp-store-postgres-lib +``` + +avec la première vertical slice métier PostgreSQL complète de `ksp-store-api` : + +```text +RawTransaction +RawTransactionObservation +RawTransaction query/pagination +RawTransaction retention/tombstone/force-rehydrate +``` + +Les six capabilities `ksp-store-api` concernées sont : + +```text +RawTransactionRead +RawTransactionWrite +RawTransactionObservationRead +RawTransactionObservationWrite +RawTransactionRetentionRead +RawTransactionRetentionWrite +``` + +Le résultat attendu à la clôture est que : + +```text +ksp-store-postgres-lib implémente réellement la persistence physique RawTransaction +ksp-store-lib::Store expose/dispatch les six capabilities via la façade commune +une acquisition transaction + observation est atomique +les writes sont idempotents pour un contenu identique +une même identité avec contenu divergent retourne ERROR_CODE_RAW_CONFLICT +une observation supplémentaire est idempotente et liée à une transaction existante +get/list respectent les contrats backend-agnostic +la pagination est déterministe et cursorisée sans policy worker cachée +la rétention/tombstone/force-rehydrate est atomique et conforme aux contrats acquis +les mismatches de network sont rejetés avant I/O +aucun type PostgreSQL/row/SQL ne fuit par ksp-store-lib +le tout est prouvé sur PostgreSQL réel par un gate opt-in non destructif +``` + +La release **ne doit pas** ouvrir `RawAccountState`. Cette famille reste réservée à : + +```text +0.3.4 — RawAccountState PostgreSQL + complétude/conformance RAW +``` + +--- + +## 3. Sources de vérité internes obligatoires — ordre de lecture + +### 3.1 Règles globales + +Lire d'abord : + +```text +RULES.md +docs/000-README.md + +docs/rules/RULES_GENERAL.md +docs/rules/RULES_KSP.md +docs/rules/RULES_RUST.md +docs/rules/RULES_DEPENDENCIES.md +docs/rules/RULES_DOCUMENTATION.md +docs/rules/FILE_CONTRACTS.md +docs/rules/VERSION_WORKFLOW.md +docs/rules/PROMPT_STRUCTURE.md +``` + +Relire particulièrement les règles applicables aux frontières : + +```text +KSP-API-* +KSP-CONFIG-* +KSP-STORE-* +KSP-NOTIFY-* +KSP-PROC-* +KSP-REL-* + +DEP-KSP-* +DEP-CARGO-* +DEP-LOG-* +DEP-STORE-* +DEP-WORKER-* +DEP-JOB-* +``` + +Rappels directement structurants : + +```text +ksp-store-lib -> ksp-store-api +ksp-store-lib[postgres] -> ksp-store-postgres-lib +ksp-store-postgres-lib -> ksp-store-api +ksp-store-postgres-lib -X-> ksp-store-lib +Config -> Store autorisé +Store/backend -X-> Config +Transport -X-> Store +Program/Materializer -X-> Store +consumer ordinaire -> ksp-store-lib +consumer ordinaire -X-> ksp-store-postgres-lib +``` + +### 3.2 Architecture durable + +Lire ensuite : + +```text +docs/architecture/000-README.md +docs/architecture/001-PROJECT_OBJECTIVES.md +docs/architecture/002-LAYERS_AND_DEPENDENCIES.md +docs/architecture/003-COMPONENT_CONTRACTS.md +docs/architecture/004-COMPONENT_INVENTORY.md +docs/architecture/005-DEPENDENCY_GRAPH.md +docs/architecture/007-EXECUTION_AND_POLICY.md +docs/architecture/008-DATA_MATERIALIZATION_AND_STORE.md +docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md +docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md +``` + +Préserver notamment : + +```text +Store persiste et sert ; il ne possède pas la policy de travail +pagination/cursorisation Store != batch-size/priorité/backlog worker/job +1 Store instance = 1 RawNetworkId + 1 backend physique +pas de multiplexage automatique de réseaux/bases dans Store +Config possède targets/URI/.env/secrets +backend PostgreSQL possède driver/pool/TLS/SQL/migrations +aucun type backend physique ne traverse la façade commune +``` + +### 3.3 Contrats RAW stables `0.3.1` + +Lire intégralement : + +```text +docs/plans/022-V0_3_1_STORE_RAW_PLAN.md +docs/validation/018-V0_3_1_STORE_RAW.md +crates/ksp-store-api/Cargo.toml +crates/ksp-store-api/src/** +crates/ksp-store-api/tests/** +``` + +Relire particulièrement : + +```text +RawTransaction / RawTransactionObservation +RawTransactionReference +RawPayload / RawContentHash / RawObservationKey +RawAcquisitionProvenance +RawTransactionQuery / RawPage* / RawSlotRange / RawSortDirection +RawAcquisitionWriteOutcome / RawEntityWriteOutcome / RawObservationWriteOutcome +RawRetentionState +RawTransactionAcquisitionMode +RawTransactionRetentionTransition +RawTransactionTombstone +les six capabilities RawTransaction/observation/retention +``` + +Ne pas redessiner ces contrats pour simplifier PostgreSQL. Une modification de `ksp-store-api` n'est recevable que si `pre.001` démontre un **gap backend-agnostic réel et bloquant**. + +### 3.4 Fondation runtime/backend stable `0.3.2` + +Lire ensuite : + +```text +docs/plans/023-V0_3_2_STORE_POSTGRES_FOUNDATION_PLAN.md +docs/validation/019-V0_3_2_STORE_POSTGRES_FOUNDATION.md + +crates/ksp-store-lib/Cargo.toml +crates/ksp-store-lib/README.md +crates/ksp-store-lib/USAGE.md +crates/ksp-store-lib/src/** +crates/ksp-store-lib/tests/** + +crates/ksp-store-postgres-lib/Cargo.toml +crates/ksp-store-postgres-lib/README.md +crates/ksp-store-postgres-lib/USAGE.md +crates/ksp-store-postgres-lib/src/** +crates/ksp-store-postgres-lib/tests/** + +crates/ksp-config-lib/README.md +crates/ksp-config-lib/USAGE.md +config/std.store.json +config/schemas/std.store.schema.json +config/examples/std.store.example.json +``` + +Lire enfin : + +```text +CHANGELOG.md +ROADMAP.md +``` + +Créer en `pre.001` : + +```text +docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md +docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md +``` + +--- + +## 4. Audit historique kbot3 obligatoire et ciblé + +L'archive kbot3 est requise parce que `0.3.3` ouvre la première vraie persistence métier PostgreSQL. Réauditer uniquement les éléments historiques pouvant informer la conception physique de `RawTransaction` : + +```text +ks-store/Cargo.toml +ks-store/README.md +ks-store/USAGE.md +ks-store/src/contracts/dto/raw.rs +ks-store/src/contracts/entity/raw.rs +ks-store/src/contracts/repository.rs +ks-store/src/postgres/query/raw_queries.rs +ks-store/src/postgres/repository/raw_transaction_repository.rs + +ks-store/migrations/postgres/schema/tables/create_table_if_not_exists_k_sol_raw_transactions.sql +ks-store/migrations/postgres/schema/tables/create_table_if_not_exists_k_sol_obs_transaction_observations.sql +ks-store/migrations/postgres/schema/indexes/*raw_transactions* +ks-store/migrations/postgres/schema/indexes/*transaction_observations* +ks-store/migrations/postgres/schema/constraints/*raw_transactions* +ks-store/migrations/postgres/schema/constraints/*transaction_observations* + +docs/guides/POSTGRES_STORAGE.md +docs/plans/V0_5_3_KS_STORE_NORMALIZATION_PLAN.md +``` + +Classer explicitement chaque idée utile sous : + +```text +REPRENDRE +REDESSINER +REPORTER +REJETER +``` + +L'audit doit notamment comparer : + +```text +identité physique transaction +stockage signature/hash/payload +observation/idempotence +atomicité acquisition + observation +conflit de contenu +indexes de lecture/pagination +ordre/cursorisation +rétention/purge +concurrence +SQL error mapping +``` + +Ne pas reprendre automatiquement : + +```text +SQLx +ancien monolithe Store +processing_state/processing ledger anticipé +CORE/DECODE/materialization +maintenance destructive publique +identifiants SQL comme API publique +JSON métier comme excuse pour contourner RawPayload KSP +batch/replay policy dans Store +``` + +Si l'archive historique n'est pas disponible : + +```text +ne pas inventer son contenu depuis la mémoire +ne pas déclarer l'audit héritage terminé +ne pas figer le schéma/indexes RawTransaction définitifs +``` + +--- + +## 5. Sources externes à réauditer lorsque nécessaire + +La fondation dépend déjà de : + +```text +tokio-postgres 0.7.x +deadpool-postgres 0.14.x +tokio-postgres-rustls 0.14.x +rustls 0.23 +sha2 0.11 +``` + +La base `0.3.2` a réellement résolu lors de son gate : + +```text +tokio-postgres 0.7.18 +deadpool-postgres 0.14.2 +tokio-postgres-rustls 0.14.0 +rustls 0.23.43 +sha2 0.11.0 +``` + +`0.3.3` n'est pas une release de mise à jour de dépendances. Ne modifier ces versions/features que si l'audit de la tranche concernée démontre un besoin concret. + +Consulter les sources PostgreSQL/tokio-postgres actuelles lorsque le design l'exige, en particulier pour : + +```text +transactions et rollback +isolation/locking concurrent +INSERT ... ON CONFLICT et garanties réelles +constraints/checks/indexes +BYTEA et représentation de valeurs fixed-width +représentation exacte des u64/u32 KSP sans narrowing +ordre stable et keyset pagination +limites SQL/parameter/row applicables +comportement de statement/transaction sous cancellation +``` + +Préférer les sources primaires PostgreSQL et upstream tokio-postgres. Ne pas ajouter ORM/query builder/codec externe par habitude. + +--- + +## 6. État validé `0.3.2` à préserver + +### 6.1 Façade/runtime + +La base stable possède : + +```text +ksp-store-lib +84 exports crate-root au gate 0.3.2 +feature default = postgres +ksp-store-postgres-lib optional dependency +Store::open(settings).await +Store::runtime_snapshot() +Store::health().await +Store::close(self).await +Store non Clone +Store lié à exactement un RawNetworkId +``` + +`ksp-store-lib` ne possède ni SQL ni type physique PostgreSQL. + +### 6.2 Backend PostgreSQL + +La base stable possède : + +```text +ksp-store-postgres-lib +PostgresBackend / PostgresBackendSettings +pool Deadpool borné +TLS Disabled / VerifyFull +Rustls + roots système + AWS-LC +URI parsing/normalization/redaction +aucune lecture env/PG*/.pgpass +bootstrap privé +health/readiness sûr +shutdown borné +``` + +Les types suivants restent privés : + +```text +Pool +Client +Row +Statement +Transaction SQL +config driver +TLS internals +``` + +### 6.3 Migrations + +La fondation stable possède : + +```text +V000__bootstrap.sql +ksp_store_schema_migrations +version/name/SHA-256 +advisory transaction lock borné +bootstrap transactionnel +mismatch/newer schema explicites +aucun down automatique +``` + +La prochaine migration métier commence donc normalement à : + +```text +V001 +``` + +`pre.001` doit confirmer la convention exacte avant création. + +### 6.4 Config et réseaux + +`std.store` possède les targets : + +```text +devnet -> network devnet +mainnet -> network mainnet-beta +testnet -> network testnet +``` + +Chaque target utilise une URI/base PostgreSQL indépendante. `Store` n'est pas un registry multi-target. + +Invariant acquis : + +```text +Store.network != input/query/reference.network + -> rejet avant I/O + -> jamais de routage automatique vers une autre Store +``` + +### 6.5 Preuve PostgreSQL réelle + +Le gate `0.3.2` a exercé la fondation sur : + +```text +PostgreSQL major 17 +``` + +La policy de fondation supportée reste : + +```text +PostgreSQL >= 15 +``` + +Aucun maximum artificiel n'est imposé par KSP. + +### 6.6 Ce qui est encore absent + +À l'ouverture de `0.3.3`, le backend PostgreSQL ne doit encore implémenter aucune capability métier : + +```text +RawTransaction* +RawAccountState* +``` + +Aucune table/index métier RAW ne doit exister dans les migrations KSP `0.3.2`. + +--- + +## 7. Décisions acquises et questions réellement ouvertes + +### 7.1 Décisions acquises + +```text +mêmes crates ksp-store-lib + ksp-store-postgres-lib +pas de nouvelle façade Store +pas de nouvelle crate repository +PostgreSQL reste le backend de référence +les six capabilities RawTransaction sont la surface fonctionnelle de 0.3.3 +ksp-store-postgres-lib réalise la persistence physique +ksp-store-lib::Store dispatch les capabilities aux backends compilés +network mismatch rejeté avant I/O +acquisition transaction + observation atomique +même identité + même contenu = idempotence +même identité + contenu divergent = ERROR_CODE_RAW_CONFLICT +observation_key est la clé d'idempotence observation +normal sur tombstone purgé = SkippedPurged / NotRecorded +ForceRehydrate est explicite et ne masque jamais un conflit +pagination Store reste navigation/cursorisation uniquement +batch-size/priorité/backlog/policy restent hors Store +SQL/rows/index ids restent privés au backend +Config reste propriétaire des URI/secrets/targets +``` + +### 7.2 Questions à fermer obligatoirement en `pre.001` + +#### Schéma physique et binding réseau + +Décider explicitement : + +```text +noms des tables/indexes/constraints KSP +clé physique transaction +clé physique observation +comment la database prouve son RawNetworkId en cas d'URI mal configurée +network stocké par ligne, metadata de database, ou autre preuve robuste +``` + +Une mauvaise URI ne doit jamais permettre de relire silencieusement des données Devnet comme Mainnet ou inversement. + +#### Représentation des entiers KSP + +Auditer sans narrowing : + +```text +slot u64 +format_version u32 +source_payload_size_bytes u64 borné +RawTimestamp u64 borné +page limit u64 +``` + +PostgreSQL `BIGINT` est signé. Il est interdit de résoudre la différence par un cast silencieux ou une réduction arbitraire du contrat `ksp-store-api`. + +#### Idempotence et concurrence + +Figer l'algorithme exact pour : + +```text +deux inserts identiques concurrents +deux inserts divergents concurrents +transaction déjà présente + observation nouvelle +observation_key déjà présent identique +observation_key déjà présent divergent +ForceRehydrate concurrent +rollback si l'observation échoue après la partie canonical +``` + +Éviter tout pattern race-prone du type : + +```text +SELECT/has puis INSERT séparé sans garantie transactionnelle +``` + +#### Pagination/cursor + +Figer : + +```text +ordre total déterministe +clé de tie-break +format/version du cursor opaque +validation d'un cursor hostile +liaison du cursor à network/range/direction si nécessaire +comportement pour une RawPageLimit trop grande pour une limite physique PostgreSQL réelle +``` + +Le cursor : + +```text +ne contient aucun SQL public +ne contient aucun secret +ne devient pas un protocole public documenté +reste <= MAX_RAW_PAGE_CURSOR_BYTES +``` + +Ne pas ajouter `bincode`. Si un encodage privé fixe suffit, le coder directement sans ouvrir un codec wire KSP. Les codecs wire officiels restent possédés par `ksp-interface-lib` et ne sont ajoutés que lorsqu'un protocole réel l'exige. + +#### Rétention physique + +Les contrats logiques acquis sont : + +```text +Full -> Compacted -> Archived -> Purged +Full -> Archived +Compacted -> Archived +``` + +`pre.001` doit décider comment PostgreSQL peut représenter **honnêtement** chaque état supporté. + +Ne pas marquer `Compacted` si aucun compactage réel n'existe, ni `Archived` si le payload reste simplement dans le même hot path sans sémantique d'archive. Si un gap backend-agnostic empêche une conformance honnête, le documenter avant de modifier `ksp-store-api`. + +`Purged` doit conserver le tombstone minimal défini par l'API et supprimer l'accès ordinaire au payload complet. + +#### Erreurs + +Définir une taxonomie sûre pour les échecs de persistence/query backend : + +```text +conflit logique -> ERROR_CODE_RAW_CONFLICT +input/query invalide -> codes Store API existants +backend/SQL failure -> code(s) Store runtime sûrs à définir si nécessaires +aucun SQLSTATE/message serveur/valeur bindée sensible dans l'erreur publique +``` + +--- + +## 8. Livrables fonctionnels et hors périmètre + +### 8.1 Livrables + +`0.3.3` doit livrer : + +```text +migration(s) métier RawTransaction à partir de V001 +schema/constraints/indexes PostgreSQL minimaux justifiés +mapping privé rows <-> ksp-store-api +impl des six capabilities sur le backend PostgreSQL +impl/dispatch des six capabilities sur Store +atomicité canonical + observation +idempotence/conflits +get transaction +get observation +record observation +list références transaction cursorisé +retention state +retention transition atomique +tombstone +ForceRehydrate +tests déterministes +canaris API/dependency/security +PostgreSQL live integration +README/USAGE/plan/validation réconciliés en fermeture +``` + +### 8.2 Hors périmètre strict + +Ne pas ouvrir : + +```text +RawAccountState PostgreSQL +RawAccountObservation PostgreSQL +schema/indexes account state +N2 STRUCTURAL +N3 DECODED +N4 DOMAIN +processing ledger +worker/job/backfill +batch scheduler +Store Desk / inspection app +event bus / LISTEN NOTIFY +nouveau transport/acquisition provider +conversion HTTP/WS/gRPC -> RawTransaction +codec wire officiel +compression/archive worker global +maintenance destructive publique +backend MySQL/SQLite/Oracle/RocksDB/ClickHouse +``` + +Les tests peuvent construire directement des modèles `ksp-store-api`; `0.3.3` ne doit pas aspirer Transport uniquement pour fabriquer des fixtures. + +--- + +## 9. Contraintes sécurité/API/architecture spécifiques + +### 9.1 Atomicité + +```text +persist_raw_transaction_acquisition + canonical + observation dans une unité atomique + jamais canonical durable si observation échoue + jamais observation orpheline +``` + +Toute course concurrente doit produire un outcome déterministe ou une erreur stable, jamais un overwrite silencieux. + +### 9.2 Network boundary + +Avant toute acquisition/query/retention : + +```text +input.network == Store.network +``` + +Sinon : + +```text +rejet avant pool.get / SQL +aucun fallback +aucun auto-routing +``` + +Le backend doit également empêcher une mauvaise URI de transformer l'identité réseau des données déjà persistées. + +### 9.3 SQL + +```text +SQL statique ou paramètres bindés +aucune interpolation de valeur métier +identifiants physiques constants KSP +constraints correspondant aux invariants exacts lorsqu'elles sont utiles +pas de SQL exposé dans API/log/error +pas d'ORM ajouté sans besoin démontré +``` + +### 9.4 Représentation des bytes + +Préserver exactement : + +```text +signature 64 bytes +content hash 32 bytes +observation key 32 bytes +payload canonical opaque <= 16 MiB +source payload hash optionnel 32 bytes +``` + +Une lecture de row invalide est un échec backend sûr ; elle ne doit jamais reconstruire un modèle partiel ou tronqué. + +### 9.5 Pagination + +Utiliser une pagination keyset/cursor déterministe si retenue par `pre.001`; ne pas utiliser un `OFFSET` non borné comme substitut automatique à un cursor opaque lorsque cela compromet stabilité ou coût. + +Aucune limite `100`, `500`, `1000`, etc. n'est inventée par Store. Une limitation physique réelle doit être représentée honnêtement par continuation ou erreur backend justifiée. + +### 9.6 Rétention et policy + +Store applique la transition demandée par le caller ; il ne décide jamais : + +```text +quand compacter +quand archiver +quand purger +si STRUCTURAL/DECODED est suffisamment complet +``` + +Ces décisions appartiennent aux futurs jobs/workers/policies. + +### 9.7 Secrets et diagnostics + +Aucun : + +```text +URI +credential +payload RAW +signature complète +hash complet +observation key complète +SQL +bind value +server error brut +``` + +ne doit apparaître dans un log/error/debug non explicitement conçu pour l'exposer. Les `Debug` existants de Store API restent la référence de redaction. + +### 9.8 Async/runtime + +```text +async-first +pas de runtime global additionnel +pas de spawn orphelin +pas de mutex sync gardé à travers await +transactions SQL bornées par les timeouts existants ou des bounds justifiés +pool central réutilisé +shutdown foundation inchangé +``` + +### 9.9 Logging + +Utiliser uniquement `ksp-logging-lib` avec `TRACING_TARGET` existant. Ne pas journaliser les données métier RAW ni le SQL. + +--- + +## 10. Première mission `0.3.3-pre.001` + +`pre.001` ne crée pas encore la migration métier ni les repositories lourds. + +### 10.1 Vérifier la base stable réelle + +Inventorier : + +```text +versions Cargo/features Store +exports/modules exacts des trois crates Store +migrations présentes et checksum V000 +Config std.store final +Store/network lifecycle final +tests hardening/completeness 0.3.2 +PostgreSQL live proof 0.3.2 +``` + +### 10.2 Auditer exactement les six capabilities + +Pour chacune, écrire une matrice : + +```text +input +invariants pré-I/O +transaction SQL nécessaire +row(s) touchée(s) +idempotence +conflit +absence/not-found +error mapping +concurrence +test déterministe +test PostgreSQL live +``` + +### 10.3 Audit historique kbot3 ciblé + +Exécuter l'audit de la section 4 et produire la classification `REPRENDRE / REDESSINER / REPORTER / REJETER`. + +### 10.4 Design physique + +Proposer puis figer : + +```text +V001 exact +noms tables/columns/indexes/constraints +network binding database/rows +mapping de tous les champs API +représentation u64/u32 sans narrowing +algorithme conflict/idempotence +transaction boundaries +observation uniqueness +cursor format/order +retention storage +purge/tombstone +ForceRehydrate +error taxonomy +``` + +Aucun champ physique ne doit être ajouté « au cas où » pour les futurs processors. + +### 10.5 Threat model + +Couvrir au minimum : + +```text +wrong-network input avant I/O +wrong-network database URI +signature/hash/key malformed dans DB +payload oversized/corrupted dans DB +u64 overflow/narrowing +observation orphan +canonical orphan après rollback +identical concurrent insert +divergent concurrent insert +observation-key collision +cursor hostile/replayed against another query +pagination duplicate/skip sous ordre ambigu +retention compare-and-transition race +purge vs read/write race +ForceRehydrate vs normal acquisition race +SQL/server error leak +pool cancellation pendant transaction +schema/index migration mismatch +``` + +### 10.6 Sizing + +Chaque tranche intermédiaire prévue au-delà d'environ **15 à 20 minutes de travail effectif** doit être scindée avant implémentation. Ce budget sert au sizing, pas à promettre un délai. + +Si `RawTransaction` complet ne semble plus clôturable dans une session, redécouper la release avant le SQL lourd. Ne jamais tirer `RawAccountState` dans `0.3.3`. + +### 10.7 Documents de gate + +Créer : + +```text +docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md +docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md +``` + +Le plan doit reprendre la prévision souple recalibrée et les décisions physiques exactes. + +### 10.8 Critères de sortie de `pre.001` + +`pre.001` est terminé seulement si : + +```text +base stable vérifiée +règles/architecture 0.3.1/0.3.2 relues +six capabilities auditées +archive kbot3 ciblée relue et classée +schema V001 proposé +network binding décidé +représentation u64/u32 décidée +atomicité/idempotence/conflit décidés +cursor/order décidés +retention/tombstone/rehydrate décidés ou gap API explicitement identifié +error taxonomy décidée +indexes minimaux justifiés +threat model complet +stratégie live PostgreSQL définie +plan 024 créé +validation 020 créée +prévision souple recalibrée +aucun RawAccountState/N2/worker aspiré +``` + +--- + +## 11. Prévision souple initiale des prereleases + +Cette prévision est volontairement fine et peut être scindée/recalibrée par `pre.001`. + +### `pre.001` — Audit contrats, kbot3, schéma, concurrence et sizing + +Lecture complète, matrice des six capabilities, audit historique ciblé, design V001/indexes/network binding/u64/cursor/rétention, threat model et plan/validation. + +### `pre.002` — Migration V001 + schéma/indexes RawTransaction + +Ajouter uniquement les structures physiques réellement nécessaires à `RawTransaction`, observations et rétention, via le moteur de migrations KSP existant. Tests checksum/history/schema. Pas encore de façade métier complète. + +### `pre.003` — Mapping physique + lectures unitaires + +Introduire les mappings privés rows/API et les primitives SQL de lecture `get transaction`, `get observation`, retention metadata/tombstone, avec validation hostile des rows. Aucun type SQL public. + +### `pre.004` — Persistence acquisition atomique + observations + +Implémenter `persist_raw_transaction_acquisition` et `record_raw_transaction_observation` avec atomicité, idempotence, conflit et concurrence déterministes. + +### `pre.005` — List/query + cursorisation + +Implémenter `RawTransactionQuery`, ordre total, slot range, directions, cursor opaque/versionné, continuation et gestion honnête des limites physiques. + +### `pre.006` — Rétention, tombstone et ForceRehydrate + +Implémenter compare-and-transition atomique, lecture state/tombstone, purge conforme et réhydratation forcée selon le design `pre.001`, sans policy worker. + +### `pre.007` — Composition façade + conformance des six capabilities + +Faire implémenter/dispatcher les six traits par `Store`, fermer network mismatch pré-I/O, error mapping, feature mismatch et canaris d'API/dependency. + +### `pre.008` — PostgreSQL integration réelle RawTransaction + +Gate opt-in sur base dédiée : migration V001, write/read, observation, idempotence, conflit, concurrence, pagination multi-page, rétention/tombstone/rehydrate, rollback et close. + +### `pre.009` — Hardening/completeness + +Inputs hostiles, rows corrompues, cursor adversarial, no-secret/no-SQL-leak, exact exports/modules, `ksp-store-api` non régressé, aucun AccountState, aucun worker policy. + +### `pre.010` — Gate technique final + +`cargo clean` si pertinent, workspace complet, tests ciblés, `cargo test --workspace`, graphes/features et replay du live PostgreSQL RawTransaction. Aucun développement fonctionnel nouveau. + +### `pre.011` — Réconciliation documentaire finale + +README/USAGE Store/backend, plan, validation et indexes docs réellement impactés. Ne pas toucher `CHANGELOG.md`, `ROADMAP.md` ni au prompt suivant. + +### `pre.012` — Préparation de publication minimale + +Uniquement : + +```text +Cargo.toml +CHANGELOG.md +ROADMAP.md +prompts/023-V0_3_4_START_PROMPT.md +deltas/0.3.3/pre.012.md +``` + +### `rel.001` — Publication stable + +Version finale + delta uniquement. + +--- + +## 12. Versionnement, deltas, commits et tags + +Respecter `docs/rules/VERSION_WORKFLOW.md`. + +Rappels : + +```text +workspace.package.version prerelease : 0.3.3-pre.N +livraison : 0.3.3-pre.NNN +fix runtime/code : Cargo 0.3.3-pre.N.fix.M +fix doc-only : Cargo inchangé +chaque delta commité +tag stable final : v0.3.3 +``` + +Chaque delta contient : + +```text +base requise +objectif +fichiers ajoutés/modifiés/supprimés +validations exécutées +validations non exécutées +décisions +questions ouvertes +``` + +Une commande non exécutée n'est jamais déclarée PASS. + +--- + +## 13. Procédure d'application et validation opérateur + +Après chaque overlay : + +```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/0.3.3 +cargo check --workspace +cargo clippy --workspace --all-targets +``` + +Tests ciblés typiques : + +```bash +cargo test -p ksp-store-api +cargo test -p ksp-store-postgres-lib +cargo test -p ksp-store-lib +cargo test -p ksp-store-lib --no-default-features +cargo test -p ksp-config-lib +cargo check -p ksp-store-lib --no-default-features +``` + +Lorsque le graphe/features change ou au gate final : + +```bash +cargo tree -p ksp-store-lib --edges normal +cargo tree -p ksp-store-lib -e features +cargo tree -p ksp-store-postgres-lib --edges normal +cargo tree --duplicates +``` + +Le gate technique final inclut : + +```bash +cargo test --workspace +``` + +Ne pas refaire systématiquement les builds Tauri : `0.3.3` n'a aucune raison d'en modifier les resources/configs desktop sauf changement réellement démontré. + +--- + +## 14. Validation PostgreSQL réelle spécifique + +La release doit disposer d'un test PostgreSQL réel opt-in, sûr et non destructif sur une database dédiée. + +Le gate doit couvrir au minimum : + +```text +PostgreSQL >= 15 +V000 + V001 bootstrap +open Store pour un RawNetworkId explicite +persist acquisition nouvelle +read transaction exacte +read observation exacte +re-persist identique -> AlreadyPresent +conflit même identité/contenu divergent -> ERROR_CODE_RAW_CONFLICT +observation supplémentaire +observation idempotente +concurrence identical/divergent +list ascending/descending +slot range +au moins deux pages et cursor continuation +cursor hostile rejeté +retention state +compare-and-transition concurrent +purge/tombstone +normal acquisition après purge -> SkippedPurged +ForceRehydrate conforme +rollback d'une acquisition forcée en échec +health reste Ready après opérations valides +close borné +cleanup uniquement des objets possédés par le test +``` + +Le test ne doit : + +```text +afficher aucune URI/credential +lire aucun env depuis Store/backend +DROP aucune database/schema non créée par lui +utiliser aucune table RawAccountState +exiger aucun endpoint Solana live +``` + +--- + +## 15. Critères de clôture de `0.3.3` + +La release stable est prête seulement si : + +```text +V001+ migrations RawTransaction sont versionnées/checksummées +schema physique conserve tous les invariants API utiles sans narrowing +binding réseau empêche une réinterprétation cross-network +PostgresBackend satisfait les six capabilities RawTransaction +Store satisfait/dispatch les six capabilities +network mismatch est rejeté avant I/O +acquisition canonical+observation est atomique +idempotence identical est stable +conflit divergent retourne ERROR_CODE_RAW_CONFLICT +observations supplémentaires sont idempotentes +get transaction/observation fonctionnent +list est déterministe et cursorisé +aucune policy batch/backlog n'est introduite +rétention compare-and-transition est atomique +purge conserve le tombstone minimal +normal post-purge skippe +ForceRehydrate fonctionne sans écraser un conflit +aucun SQL/type physique n'est exposé par la façade +aucun secret/payload/SQL distant ne fuite dans erreurs/logs +ksp-store-api reste backend-agnostic ou toute modification est justifiée par un gap réel +RawAccountState PostgreSQL reste absent +PostgreSQL live gate est vert +workspace/Clippy/tests/graphes sont verts +README/USAGE/plan/validation sont réconciliés +prompt 0.3.4 réserve RawAccountState + complétude RAW +``` + +--- + +## 16. Release suivante et instruction d'ouverture + +La release suivante envisagée est : + +```text +0.3.4 — Store/PostgreSQL RawAccountState + complétude/conformance RAW +``` + +Elle réutilisera la même fondation `0.3.2` et les patterns physiques/concurrence validés par `0.3.3`, sans recréer une seconde architecture Store. + +### Instruction d'ouverture + +À réception de la base stable `v0.3.2` et de l'archive historique requise : + +1. vérifier la base exacte et les migrations réellement présentes ; +2. lire règles, architecture, plans/validations `0.3.1` et `0.3.2`, puis les sources des trois crates Store ; +3. auditer les six capabilities `RawTransaction` une par une ; +4. réauditer kbot3 uniquement sur son ancienne vertical slice RAW transaction/observation ; +5. figer V001, network binding, représentation u64/u32, idempotence/concurrence, cursor et rétention ; +6. produire threat model, sizing, plan `024` et validation `020` ; +7. **ne pas créer la migration métier ni le repository lourd avant validation cohérente de `pre.001`** ; +8. **ne pas ouvrir `RawAccountState`, STRUCTURAL, jobs/workers ou application d'inspection dans `0.3.3`**.