Files
2026-08-30 09:22:53 +02:00

9.8 KiB

Delta 0.3.3-pre.003 — V001 RawTransaction physique et binding réseau

1. Base requise

0.3.3-pre.002

Le gate opérateur fourni pour pre.002 est entièrement vert :

cargo fmt --all                                         PASS
audit Rust général / exports / workspace                PASS
audit Markdown                                           PASS — 214 tables / 132 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

Le test PostgreSQL foundation reste #[ignore] dans ce gate ordinaire. La preuve live complète de la vertical slice 0.3.3 reste réservée à pre.009.

2. Objectif

Matérialiser le design physique décidé en pre.001 sur le moteur multi-version acquis en pre.002, sans commencer encore les repositories/capabilities métier.

La tranche livre :

V001__raw_transaction.sql
registre embedded réel V000 + V001
binding mono-réseau atomique
contraintes/indexes RAW exacts
checksum/inventory/bounds statiques
code stable PostgreSQL Compacted unsupported

3. Version

Le workspace passe à :

0.3.3-pre.3

4. Migration V001

La migration ajoutée est :

crates/ksp-store-postgres-lib/migrations/V001__raw_transaction.sql

Le registre embedded contient désormais exactement :

V000 bootstrap
V001 raw_transaction

La version courante dérivée du registre vaut donc :

1

V000 reste byte-identique avec son checksum historique :

d29068b8c13b9dc0cc9ef6aaadd0fa12d41e0fe4c56541a1118c4bfc846a1450

Checksum SHA-256 V001 :

6fe57ed0313d2ed295280dd6e49f6d86695d4e4effee2724a25e36db1ea17761

5. Inventaire physique V001

V001 crée exactement les tables métier/identité suivantes :

ksp_store_identity
ksp_raw_transactions
ksp_raw_transaction_observations
ksp_raw_transaction_archive_payloads

et l'index secondaire suivant :

ix_ksp_raw_transactions_slot_signature
    ON ksp_raw_transactions(slot, signature)
    WHERE retention_state <> 'purged'

Les clés physiques restent :

ksp_store_identity(singleton)
ksp_raw_transactions(signature)
ksp_raw_transaction_observations(observation_key)
ksp_raw_transaction_archive_payloads(signature)

Aucun ID SQL auxiliaire n'est ajouté.

6. Bornes et contraintes

Les contraintes SQL matérialisent les invariants backend-agnostiques déjà acquis :

network/code UTF-8 ASCII sûr       1..=128 octets
signature transaction              64 octets
observation key                    32 octets
content/source hash                32 octets
slot                               NUMERIC(20,0), 0..=u64::MAX
format_version                     BIGINT, 1..=u32::MAX
RawTimestamp                       BIGINT, 0..=253402300799999
payload canonical/archive          1..=16 MiB lorsqu'il existe
source payload size                0..=64 MiB
origin                             backfill/import/live/repair/replay
retention physique                 full/archived/purged

slot n'est jamais réduit en BIGINT signé.

La cohérence de rétention physique impose :

full       -> payload hot présent
archived   -> payload hot absent
purged     -> payload hot absent + block_time absent

La relation archive reste séparée du hot path. V001 ne prétend jamais représenter Compacted.

7. Binding mono-réseau atomique

V001 déclare le hook privé :

MigrationHook::StoreIdentity

Le comportement est distinct selon le contexte déjà acquis en pre.002.

AppliedNow

Sous la même transaction et le même advisory lock :

batch_execute(V001)
-> INSERT singleton=1 + network runtime
-> relire exactement l'identité
-> valider singleton + RawNetworkId + égalité réseau
-> INSERT history V001
-> commit final

L'insertion n'utilise aucun upsert : une divergence physique ne peut pas être absorbée silencieusement.

Existing

Une réouverture V001 effectue uniquement :

SELECT singleton, network
-> exactement une ligne
-> singleton = 1
-> network valide RawNetworkId
-> network == backend.network

Une identité absente, multiple, illisible, malformée ou différente devient MigrationMismatch avec une phase statique. La valeur réseau persistée et les erreurs PostgreSQL ne sont jamais retenues/rendues.

Une base V001 dont l'identité a disparu n'est donc jamais réclamée/rebindée automatiquement.

8. Compacted PostgreSQL non supporté

Le code stable suivant est désormais matérialisé par valeur dans le backend et la façade :

store.postgres_retention_compaction_unsupported

Exports :

ksp_store_postgres_lib::ERROR_CODE_POSTGRES_RETENTION_COMPACTION_UNSUPPORTED
ksp_store_lib::ERROR_CODE_POSTGRES_RETENTION_COMPACTION_UNSUPPORTED

Les deux crates construisent le même ErrorCode KSP sans créer de dépendance inverse ksp-store-postgres-lib -> ksp-store-lib.

L'utilisation opérationnelle de ce code par RawTransactionRetentionWrite reste réservée à pre.007.

9. Tests statiques ajoutés/actualisés

Les tests de migration couvrent désormais :

registre réel [V000,V001]
V000 checksum immuable
V001 checksum exact
version courante = 1
V000 seul = préfixe valide / V001 pending
historique complet V000+V001 valide
mismatch/newer toujours terminaux
inventaire exact des quatre tables
index partiel exact
slot u64 max sans narrowing
bornes u32/timestamp/payload/source payload
retention physique sans compacted
hook StoreIdentity réel
contextes AppliedNow / Existing
absence de repository/capability dans la tranche

Les canaris de surface publique sont actualisés :

ksp-store-postgres-lib root pub use : 7 -> 8
ksp-store-lib root pub use          : 84 -> 85

La seule nouvelle surface est le code d'erreur PostgreSQL Compacted explicitement planifié.

Le test live foundation hérité de 0.3.2 est maintenu cohérent avec V001 sans devenir la preuve métier de cette release :

version health attendue              0 -> 1
refus de départ                       toute table Store V000/V001 déjà présente
cleanup                               ensemble des tables Store V000/V001 possédées
preuve de rollback historique         V000 inchangée
statut dans le gate ordinaire         toujours #[ignore]

Il n'est pas exécuté dans cette tranche ; les scénarios V001 spécifiques restent réservés à pre.009.

10. Preuves volontairement différées

Cette tranche ne prétend pas avoir exécuté PostgreSQL réel pour V001.

Restent au gate live pre.009 :

upgrade réel V000 -> V001
rollback réel si hook échoue
réouverture même réseau
réouverture réseau différent
identity supprimée/malformée sur DB réelle
checksum V001 divergent sur DB réelle
concurrence réelle du bootstrap V001

Ces points ne sont donc pas marqués PASS dans la validation pre.003.

11. Fichiers modifiés

Cargo.toml
crates/ksp-store-lib/src/error.rs
crates/ksp-store-lib/src/lib.rs
crates/ksp-store-lib/tests/hardening_completeness.rs
crates/ksp-store-lib/tests/public_api.rs
crates/ksp-store-postgres-lib/src/error.rs
crates/ksp-store-postgres-lib/src/lib.rs
crates/ksp-store-postgres-lib/src/migration.rs
crates/ksp-store-postgres-lib/tests/dependency_boundary.rs
crates/ksp-store-postgres-lib/tests/hardening_completeness.rs
crates/ksp-store-postgres-lib/tests/postgres_foundation_live.rs
crates/ksp-store-postgres-lib/tests/public_api.rs
crates/ksp-store-postgres-lib/unit_tests/migration.rs
docs/plans/024-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION_PLAN.md
docs/validation/020-V0_3_3_STORE_POSTGRES_RAW_TRANSACTION.md

12. Fichiers ajoutés

crates/ksp-store-postgres-lib/migrations/V001__raw_transaction.sql
deltas/0.3.3/pre.003.md

13. Fichiers supprimés

Aucun.

14. Hors scope confirmé

Aucun changement n'implémente encore :

RawTransactionRead
RawTransactionWrite
RawTransactionObservationRead
RawTransactionObservationWrite
RawTransactionRetentionRead
RawTransactionRetentionWrite
row codecs SQL métier
get/list/cursor
canonical+observation writes
archive/purge/rehydrate behavior
ksp-store-lib capability dispatch
RawAccountState PostgreSQL
Config std.store
workers/jobs/apps

15. Validations exécutées dans l'environnement de génération

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 (214 table(s), 133 file(s))

Les commandes Cargo ne sont pas disponibles dans l'environnement de génération. Elles restent NON EXÉCUTÉES ici et doivent être exécutées côté opérateur.

16. Gate opérateur demandé

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

Le test PostgreSQL live demeure hors gate ordinaire jusqu'à la tranche dédiée pre.009.

17. Suite prévue après gate vert

0.3.3-pre.004 — mapping SQL privé + lectures RawTransaction/observation/rétention/tombstone