Files
2026-09-03 12:32:53 +02:00

6.7 KiB

Delta 0.3.8-pre.004 — inspection PostgreSQL RawTransaction et dispatch Store

Base requise

Base directe attendue :

0.3.8-pre.003-fix.001
workspace.package.version = 0.3.8-pre.3.fix.1

Le gate opérateur fourni sur cette base est entièrement vert : audits Rust/Markdown, cargo check --workspace, cargo clippy --workspace --all-targets, ksp-store-api, ksp-store-lib, ksp-store-lib --no-default-features et ksp-app-store-desk.

La livraison est :

0.3.8-pre.004
workspace.package.version = 0.3.8-pre.4
commit = v0.3.8-pre.004
tag = aucun

Objectif

Implémenter le premier vertical slice physique de la primitive backend-neutral créée en pre.003 :

RawTransactionInspectionRead
  ksp-store-postgres-lib
  -> ksp-store-lib::Store

RawAccountStateInspectionRead reste volontairement non implémenté jusqu'à pre.005. Aucun SQL de migration, aucune UI Store Desk et aucun branchement DataTables serverSide ne sont introduits.

SQL d'inspection

Deux statements privés existent, un par direction canonique. Chaque appel exécute une seule instruction SQL comprenant :

filtered_count
conditional total_count
LATERAL page
ORDER BY slot, signature
LIMIT/OFFSET

Cette forme garantit que counts et page sont issus du même snapshot de statement PostgreSQL.

Lorsque le range slot est absent, filtered_count est réutilisé comme total_count; aucun second COUNT(*) n'est exécuté. Avec un filtre slot, total_items reste le total exact de la famille transaction dans le Store/network et filtered_items représente le sous-ensemble filtré.

Les tombstones Purged sont inclus dans l'inspection afin que l'outil opérateur puisse voir l'état de rétention durable. Le listage cursor/keyset historique reste inchangé et continue d'exclure Purged.

Pas de transfert payload / pas de N+1

Le statement de page ne sélectionne jamais :

transaction_row.payload
archive_row.payload

Il projette seulement :

OCTET_LENGTH(transaction_row.payload)
OCTET_LENGTH(archive_row.payload)
hot_payload_present
archive_payload_present

Le summary final est donc construit en une seule requête, sans chargement individuel par ligne et sans gros bytes IPC/runtime. Les marqueurs de présence permettent en outre de rejeter une forme PostgreSQL incohérente (Full avec archive résiduelle, Archived avec hot payload, Purged avec payload ou block time résiduel).

Limites physiques et offset

RawPageLimit reste sans plafond politique côté API. Le backend convertit avant I/O :

limit -> i64 PostgreSQL
offset -> i64 PostgreSQL

Un limit non représentable renvoie PageLimitUnsupported; un offset non représentable renvoie QueryInvalid. Ces validations sont effectuées avant pool.get().

Une page vide causée par un offset supérieur à filtered_items reste valide et retourne les counts exacts avec items = [].

Façade Store

PostgresBackend et Store implémentent désormais RawTransactionInspectionRead. Le dispatch Store applique d'abord le même guard network que les autres opérations network-scoped.

L'inventaire physique/facade passe donc temporairement de 10 à 11 capabilities RAW implémentées :

10 historiques
+ RawTransactionInspectionRead
= 11

Les deux inventaires restent strictement symétriques et RawAccountStateInspectionRead est explicitement absent jusqu'à pre.005.

Cursor/keyset préservé

Les statements historiques LIST_TRANSACTIONS_ASC_SQL / LIST_TRANSACTIONS_DESC_SQL restent contrôlés séparément :

keyset (slot, signature)
LIMIT + continuation probe
aucun OFFSET
retention_state <> 'purged'

L'exception OFFSET est donc locale au chemin inspection random-access et ne modifie pas le contrat machine/replay/backfill.

Tests et canaris

Le delta ajoute/actualise les preuves suivantes :

  • conversion limit/offset hostile avant I/O ;
  • décodage summary Full / Archived / Purged sans bytes ;
  • rejet des résidus physiques incompatibles avec l'état de rétention ;
  • canari SQL séparant explicitement keyset sans OFFSET et inspection avec OFFSET ;
  • preuve que l'inspection utilise counts, LATERAL page et OCTET_LENGTH sans sélectionner les payloads ;
  • inventaires exacts 11/11 côté backend et façade ;
  • live proof PostgreSQL opt-in : filtre slot, counts, asc/desc, offset et page vide profonde.

Fichiers ajoutés

deltas/0.3.8/pre.004.md

Fichiers modifiés

Cargo.toml
crates/ksp-store-lib/src/store.rs
crates/ksp-store-lib/tests/dependency_boundary.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/raw_transaction.rs
crates/ksp-store-postgres-lib/src/runtime.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_raw_transaction_live.rs
crates/ksp-store-postgres-lib/tests/public_api.rs
crates/ksp-store-postgres-lib/unit_tests/raw_transaction.rs
docs/plans/029-V0_3_8_STORE_DESK_PLAN.md
docs/validation/025-V0_3_8_STORE_DESK.md

Fichiers supprimés

aucun

Validations d'assemblage

Contrôles exécutés avant emballage :

General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
Markdown table audit: clean (314 table(s), 696 file(s))
pre.004 structural contract audit: clean
workspace.package.version: 0.3.8-pre.4
Store Raw capability implementations: 11
PostgreSQL Raw capability implementations: 11
RawAccountStateInspectionRead implementations: 0
RawTransaction keyset OFFSET occurrences: 0
RawTransaction inspection OFFSET occurrences: 2
delta scope: 1 ajout / 16 modifications / 0 suppression

Le sandbox d'assemblage ne dispose pas de cargo/rustfmt; aucun gate Cargo de pre.004 n'est donc revendiqué localement. Le gate opérateur requis est :

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
cargo check --workspace
cargo clippy --workspace --all-targets
cargo test -p ksp-store-postgres-lib
cargo test -p ksp-store-lib
cargo check -p ksp-store-lib --no-default-features
cargo test -p ksp-store-api

Le live proof reste opt-in et doit être exécuté uniquement sur une base PostgreSQL dédiée vide si une preuve réelle est souhaitée :

cargo test -p ksp-store-postgres-lib --test postgres_raw_transaction_live -- --ignored --nocapture