v0.3.3-pre.009
This commit is contained in:
184
deltas/0.3.3/pre.009.md
Normal file
184
deltas/0.3.3/pre.009.md
Normal file
@@ -0,0 +1,184 @@
|
||||
<!-- file: deltas/0.3.3/pre.009.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.3-pre.009` — preuve PostgreSQL live complète RawTransaction
|
||||
|
||||
## 1. Base et gate d'entrée
|
||||
|
||||
Base opérateur obligatoire :
|
||||
|
||||
```text
|
||||
0.3.3-pre.8.fix.1
|
||||
```
|
||||
|
||||
Le gate opérateur fourni le 2026-08-30 est entièrement propre : audits Rust/Markdown, `cargo check --workspace`, Clippy all-targets sans warning, tests Store API/façade/PostgreSQL/Config et `ksp-store-lib --no-default-features` passent. `pre.008-fix.001` est donc acquise.
|
||||
|
||||
## 2. Version
|
||||
|
||||
```text
|
||||
workspace.package.version = 0.3.3-pre.9
|
||||
```
|
||||
|
||||
## 3. Nouveau test PostgreSQL réel
|
||||
|
||||
La tranche ajoute :
|
||||
|
||||
```text
|
||||
crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs
|
||||
```
|
||||
|
||||
Le test est `#[ignore]`, lit une URI PostgreSQL dédiée uniquement sur `stdin`, ne l'affiche jamais et refuse de démarrer lorsqu'une table KSP V000/V001 existe déjà. Il ne nettoie que le schéma qu'il a prouvé absent avant son propre bootstrap.
|
||||
|
||||
Il refuse PostgreSQL < 15 comme la preuve fondation existante.
|
||||
|
||||
## 4. Migration, identité réseau et schema update
|
||||
|
||||
La preuve couvre :
|
||||
|
||||
- bootstrap V000 + V001 sur base vide ;
|
||||
- health Ready avec migration 1 ;
|
||||
- refus d'une réouverture sous un autre `RawNetworkId` ;
|
||||
- réouverture idempotente ;
|
||||
- suppression contrôlée de `ix_ksp_raw_transactions_slot_signature` ;
|
||||
- `schema_autoupdate=false` qui bloque le drift ;
|
||||
- `schema_autoupdate=true` qui recrée et revalide l'index manquant.
|
||||
|
||||
Aucune ressource de migration n'est modifiée et aucun historique n'est réécrit.
|
||||
|
||||
## 5. Écriture, idempotence, concurrence et rollback
|
||||
|
||||
Le live couvre :
|
||||
|
||||
- canonical + observation atomiques ;
|
||||
- get canonical exact ;
|
||||
- observation round-trip exact avec provenance complète ;
|
||||
- deux acquisitions identiques en vraies tâches concurrentes : un `Inserted`, un `AlreadyPresent` ;
|
||||
- deux acquisitions divergentes sous la même signature : un gagnant et un `Conflict` ;
|
||||
- vérification qu'une seule observation du duel divergent est durable ;
|
||||
- observation supplémentaire `Inserted` puis `AlreadyPresent` ;
|
||||
- même observation key divergente -> `Conflict` ;
|
||||
- collision observation pendant une nouvelle acquisition -> rollback du canonical nouvellement tenté.
|
||||
|
||||
## 6. Pagination
|
||||
|
||||
Le test insère cinq signatures sur trois slots, dont deux paires ex æquo, et prouve :
|
||||
|
||||
```text
|
||||
Ascending 50, 51, 52, 53, 54
|
||||
Descending 54, 53, 52, 51, 50
|
||||
page size 2
|
||||
```
|
||||
|
||||
Il rejoue ensuite le cursor V1 sous :
|
||||
|
||||
- direction différente ;
|
||||
- range différente.
|
||||
|
||||
Les deux cas doivent être `QueryInvalid`.
|
||||
|
||||
## 7. Rétention et rehydrate
|
||||
|
||||
La preuve couvre :
|
||||
|
||||
- compare mismatch observable ;
|
||||
- `Full -> Archived` et lecture exacte depuis archive ;
|
||||
- idempotence `AlreadyAtTarget` ;
|
||||
- `Archived -> Purged` ;
|
||||
- `get -> None` et tombstone minimal exact ;
|
||||
- acquisition normale sur tombstone -> `SkippedPurged/NotRecorded` ;
|
||||
- ForceRehydrate divergent -> `Conflict` sans mutation ;
|
||||
- ForceRehydrate compatible -> `Rehydrated/Inserted` ;
|
||||
- `Full -> Compacted` rejeté par `RetentionCompactionUnsupported` sans changement d'état ;
|
||||
- deux archives concurrentes puis deux purges concurrentes : un `Applied` et un `AlreadyAtTarget` par race ;
|
||||
- rehydrate après la race purge.
|
||||
|
||||
## 8. Cancellation réelle
|
||||
|
||||
Le test crée une observation durable, la verrouille via une transaction PostgreSQL administrateur, puis démarre une nouvelle acquisition qui :
|
||||
|
||||
1. insère son canonical dans sa transaction non committée ;
|
||||
2. bloque sur la collision de l'observation verrouillée ;
|
||||
3. reste bloquée au-delà du délai canari ;
|
||||
4. est annulée via `JoinHandle::abort()` ;
|
||||
5. libère ensuite le verrou administrateur ;
|
||||
6. prouve que le canonical de l'acquisition annulée n'est pas durable.
|
||||
|
||||
Cette preuve exerce un rollback par cancellation réelle, pas une simulation séquentielle.
|
||||
|
||||
## 9. Réouverture finale
|
||||
|
||||
Après toutes les opérations, le backend est rouvert sur le même réseau. Le test exige :
|
||||
|
||||
- health Ready ;
|
||||
- migration 1 ;
|
||||
- lecture exacte d'un canonical durable antérieur.
|
||||
|
||||
Le cleanup final supprime les cinq tables KSP uniquement parce que leur absence initiale a été prouvée.
|
||||
|
||||
## 10. Migrations
|
||||
|
||||
Aucune ressource V000/V001 n'est modifiée.
|
||||
|
||||
Checksums attendus et recalculés :
|
||||
|
||||
```text
|
||||
V000 d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450
|
||||
V001 31488cda2f08f3f46c4cdbdbb6c18c243662fada02eac4487040c8735d72cc51
|
||||
```
|
||||
|
||||
V001 reste exactement à 40 ressources.
|
||||
|
||||
## 11. Fichiers modifiés
|
||||
|
||||
```text
|
||||
Cargo.toml
|
||||
crates/ksp-store-postgres-lib/README.md
|
||||
crates/ksp-store-postgres-lib/USAGE.md
|
||||
crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
|
||||
crates/ksp-store-postgres-lib/tests/postgres_raw_transaction_live.rs
|
||||
docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md
|
||||
docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md
|
||||
deltas/0.3.3/pre.009.md
|
||||
```
|
||||
|
||||
Aucune suppression de fichier.
|
||||
|
||||
## 12. Validation exécutée dans l'environnement de génération
|
||||
|
||||
```text
|
||||
General Rust rule audit: clean
|
||||
Rust export completeness audit: 0 candidate(s)
|
||||
KSP workspace Rust rule audit: clean
|
||||
Markdown table audit: clean
|
||||
```
|
||||
|
||||
Cargo, rustfmt et PostgreSQL réel ne sont pas disponibles dans l'environnement de génération. Le gate opérateur et le live restent donc à exécuter localement.
|
||||
|
||||
## 13. Gate opérateur standard
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
## 14. Gate PostgreSQL live opt-in
|
||||
|
||||
Sur une base PostgreSQL dédiée et vide de toute table KSP gérée :
|
||||
|
||||
```bash
|
||||
printf '%s\n' '<URI_POSTGRES_DEDIEE>' | cargo test -p ksp-store-postgres-lib --test postgres_raw_transaction_live -- --ignored --nocapture
|
||||
```
|
||||
|
||||
## 15. Suite si les deux gates sont verts
|
||||
|
||||
```text
|
||||
0.3.3-pre.010 — hardening/completeness
|
||||
```
|
||||
Reference in New Issue
Block a user