287 lines
7.7 KiB
Markdown
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.
|