Files
khadhroony-solana-project/deltas/0.3.3/pre.002.md
2026-08-30 08:41:26 +02:00

287 lines
7.7 KiB
Markdown

<!-- file: deltas/0.3.3/pre.002.md -->
<!-- version: 1 -->
# Delta `0.3.3-pre.002` — moteur de migrations PostgreSQL multi-version
## 1. Base requise
```text
0.3.3-pre.001
```
Le gate opérateur fourni pour `pre.001` est entièrement vert :
```text
cargo fmt --all PASS
audit Rust général / exports / workspace PASS
audit Markdown PASS — 214 tables / 131 files
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-postgres-lib PASS
cargo test -p ksp-config-lib PASS
cargo check -p ksp-store-lib --no-default-features PASS
```
Les tests live `#[ignore]` restent volontairement hors de ce gate ; `pre.001` était documentaire et `pre.002` ne crée encore aucun SQL métier V001.
## 2. Objectif
Généraliser le bootstrap PostgreSQL V000 acquis en `0.3.2` vers un moteur embedded multi-version avant d'introduire la première migration métier.
La tranche doit préserver :
```text
checksum immuable
mismatch terminal
schema newer terminal
aucun down automatique
advisory transaction lock
migration timeout
statement timeout
transaction unique
metadata shape validation
erreurs externes non rendues
```
Elle prépare également la frontière transactionnelle du futur binding `RawNetworkId`, sans créer V001 ni `ksp_store_identity`.
## 3. Version
Le workspace passe à :
```text
0.3.3-pre.2
```
## 4. Registre embedded
Le moteur ne possède plus une série de constantes spécialisées V000. Il utilise désormais :
```text
EMBEDDED_MIGRATIONS: &[EmbeddedMigration]
```
Le registre réel de cette tranche contient exactement :
```text
V000 bootstrap
```
Aucune V001 n'est anticipée dans les migrations physiques.
Chaque entrée possède :
```text
version
name
sql embedded
migration hook
```
Le registre est validé avant I/O :
```text
non vide
commence à 0
versions contiguës strictement ordonnées
name non vide
SQL non vide
```
La version courante est dérivée du dernier élément du registre.
## 5. Validation d'historique multi-version
L'historique PostgreSQL est maintenant validé comme **préfixe exact** du registre embedded.
Cas :
```text
historique exact complet -> prêt
préfixe exact -> migrations pending
nom divergent -> MigrationMismatch
checksum divergent -> MigrationMismatch
version/trou inattendu connu -> MigrationMismatch
version > runtime courant -> SchemaNewer
metadata existante sans V000 -> MigrationMismatch
```
Un préfixe exact n'est donc plus confondu avec une divergence : il représente précisément le cas normal d'upgrade V000 -> V001 attendu en `pre.003`.
## 6. Application des migrations pending
Sous la transaction PostgreSQL et l'advisory lock déjà acquis :
```text
load/validate history
-> déterminer next_index
-> refuser si pending && auto_migrate=false
-> appliquer chaque migration dans l'ordre
-> vérifier metadata shape
-> exécuter migration hook
-> insérer checksum/name/version dans history
-> migration suivante
-> commit unique
```
Une erreur à n'importe quelle étape provoque le rollback transactionnel normal ; aucune migration partiellement enregistrée n'est considérée appliquée.
## 7. Hook atomique de binding réseau
`bootstrap` reçoit désormais le `RawNetworkId` du backend et le transmet jusqu'à chaque migration.
Le moteur distingue deux contextes privés :
```text
Existing migration déjà présente dans history à la réouverture
AppliedNow migration exécutée pendant le bootstrap courant
```
Pour les migrations déjà appliquées, le hook est rejoué sous la transaction/advisory lock avant que le backend puisse être déclaré prêt. Pour une migration nouvellement appliquée, l'ordre est :
```text
batch_execute(migration.sql)
-> metadata shape check
-> migration hook AppliedNow
-> INSERT history
-> commit final
```
V000 utilise :
```text
MigrationHook::None
```
`pre.003` pourra donc ajouter le hook V001 `ksp_store_identity` avec deux comportements sûrs : création/validation en `AppliedNow`, validation stricte sans recréation en `Existing`. La frontière reste transactionnelle et ne crée aucune seconde phase de bootstrap race-prone.
Aucune identité réseau n'est écrite dans cette tranche.
## 8. Compatibilité V000
Le fichier reste inchangé :
```text
crates/ksp-store-postgres-lib/migrations/V000__bootstrap.sql
```
Checksum conservé :
```text
d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450
```
La metadata historique reste :
```text
ksp_store_schema_migrations
version BIGINT PRIMARY KEY
name TEXT NOT NULL
checksum TEXT NOT NULL
applied_at TIMESTAMPTZ NOT NULL
```
## 9. Tests du moteur
Les unit tests `migration.rs` couvrent maintenant :
```text
registre réel V000 immutable
checksum V000 stable
current version dérivée du registre
registre synthétique V000/V001 ordonné
historique V000 comme préfixe pending valide
historique synthétique V000/V001 complet
registre vide/non-zero/gap/name vide/SQL vide rejeté
nom/checksum/history missing/gap rejetés
version future -> SchemaNewer
```
Un canari d'intégration source vérifie aussi :
```text
registre embedded présent
hook de migration + contextes `AppliedNow`/`Existing` présents
RawNetworkId transmis au hook
validation préfixe utilisée
application pending utilisée
aucun V001__raw_transaction.sql
aucun ksp_store_identity
```
## 10. Fichiers modifiés
```text
Cargo.toml
crates/ksp-store-postgres-lib/src/migration.rs
crates/ksp-store-postgres-lib/src/runtime.rs
crates/ksp-store-postgres-lib/unit_tests/migration.rs
crates/ksp-store-postgres-lib/tests/dependency_boundary.rs
docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md
docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md
```
## 11. Fichier ajouté
```text
deltas/0.3.3/pre.002.md
```
## 12. Fichiers supprimés
Aucun.
## 13. Hors scope confirmé
Aucun changement n'est apporté à :
```text
V001 physique
ksp_store_identity
tables/indexes RawTransaction
mapping Row/SQL métier
six capabilities RawTransaction
ksp-store-lib dispatch
RawAccountState
Config std.store
workers/jobs/apps
codecs wire
```
## 14. Validations exécutées dans l'environnement de génération
```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.3
Markdown table audit: clean
```
`cargo`, `rustc` et `rustfmt` ne sont pas disponibles dans l'environnement d'assemblage. Les validations Cargo ci-dessous restent donc opérateur et ne sont jamais déclarées PASS ici.
## 15. Gate opérateur demandé
```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
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
```
Aucun test PostgreSQL live n'est requis : le SQL physique reste strictement V000 et aucun schéma métier n'est introduit.
## 16. Suite
Après gate vert, `0.3.3-pre.003` créera la vraie migration V001, les tables/constraints/indexes décidés en `pre.001` et le binding atomique `ksp_store_identity` via le hook préparé ici.