244 lines
6.5 KiB
Markdown
244 lines
6.5 KiB
Markdown
<!-- file: deltas/0.3.1/pre.006.md -->
|
|
<!-- version: 1 -->
|
|
|
|
# Delta `0.3.1-pre.006` — queries, outcomes et lifecycle RAW
|
|
|
|
## Base requise
|
|
|
|
```text
|
|
0.3.1-pre.5
|
|
```
|
|
|
|
Le gate opérateur de `pre.005` est intégralement vert : audits Rust/Markdown, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo test -p ksp-store-api` passent.
|
|
|
|
## Recalibrage pagination
|
|
|
|
Le brainstorming opérateur précise une règle durable : Store fournit une primitive de query/pagination, **pas une policy d'exécution**.
|
|
|
|
Une limitation physique réelle d'un backend peut contraindre ce qu'il sert en une opération. En revanche `ksp-store-api`, `ksp-store-lib` et les crates backend ne doivent pas inventer un plafond métier inférieur (`100`, `500`, etc.) simplement pour gouverner le travail d'un futur executor.
|
|
|
|
`pre.006` matérialise donc :
|
|
|
|
```text
|
|
RawPageLimit > 0
|
|
aucun maximum fonctionnel KSP arbitraire
|
|
RawPageCursor opaque <= 4 KiB
|
|
```
|
|
|
|
La borne du cursor protège un token d'entrée hostile ; elle ne limite pas le nombre de résultats. Le futur job/worker choisira sa taille de travail et son backlog via ses propres policies/processing contracts.
|
|
|
|
## Objectif
|
|
|
|
Finaliser les contrats N1 encore nécessaires avant le hardening de release :
|
|
|
|
```text
|
|
queries/list cursorisés
|
|
outcomes idempotents
|
|
conflit stable
|
|
atomic acquisition finalisée
|
|
rétention logique transactionnelle
|
|
tombstone anti-rebackfill
|
|
normal skip / force rehydrate explicite
|
|
```
|
|
|
|
Aucune compression, archive physique, base de données, policy de purge ou executor n'est implémenté.
|
|
|
|
## Fichiers ajoutés
|
|
|
|
```text
|
|
crates/ksp-store-api/src/capability/raw_retention.rs
|
|
crates/ksp-store-api/src/model/raw_outcome.rs
|
|
crates/ksp-store-api/src/model/raw_pagination.rs
|
|
crates/ksp-store-api/src/model/raw_retention.rs
|
|
crates/ksp-store-api/unit_tests/model/raw_pagination.rs
|
|
crates/ksp-store-api/unit_tests/model/raw_retention.rs
|
|
deltas/0.3.1/pre.006.md
|
|
```
|
|
|
|
## Fichiers modifiés
|
|
|
|
```text
|
|
Cargo.toml
|
|
crates/ksp-store-api/src/capability.rs
|
|
crates/ksp-store-api/src/capability/raw_account.rs
|
|
crates/ksp-store-api/src/capability/raw_transaction.rs
|
|
crates/ksp-store-api/src/error.rs
|
|
crates/ksp-store-api/src/lib.rs
|
|
crates/ksp-store-api/src/model.rs
|
|
crates/ksp-store-api/tests/dependency_boundary.rs
|
|
crates/ksp-store-api/tests/external_backend.rs
|
|
crates/ksp-store-api/tests/public_api.rs
|
|
docs/plans/022-V0_3_1_STORE_RAW_PLAN.md
|
|
docs/validation/018-V0_3_1_STORE_RAW.md
|
|
```
|
|
|
|
## Fichiers supprimés
|
|
|
|
```text
|
|
aucun
|
|
```
|
|
|
|
## Version
|
|
|
|
```text
|
|
workspace.package.version = 0.3.1-pre.6
|
|
```
|
|
|
|
## Queries et pagination
|
|
|
|
Surface ajoutée :
|
|
|
|
```text
|
|
RawPageCursor
|
|
RawPageLimit
|
|
RawPageRequest
|
|
RawPage<T>
|
|
RawSlotRange
|
|
RawSortDirection
|
|
RawTransactionQuery
|
|
RawAccountStateQuery
|
|
```
|
|
|
|
`RawPageLimit::new(0)` est invalide. Aucun maximum KSP n'est imposé ; `u64::MAX` reste représentable par le contrat. Les queries sont network-scoped et peuvent borner les slots ; les account queries peuvent en plus sélectionner un pubkey.
|
|
|
|
Les capabilities read gagnent :
|
|
|
|
```text
|
|
list_raw_transactions(query)
|
|
list_raw_account_states(query)
|
|
```
|
|
|
|
Les pages retournent des références compactes et un cursor opaque, pas des rows/PK/SQL backend.
|
|
|
|
## Outcomes et conflits
|
|
|
|
Surface ajoutée :
|
|
|
|
```text
|
|
RawEntityWriteOutcome
|
|
Inserted
|
|
AlreadyPresent
|
|
Rehydrated
|
|
SkippedPurged
|
|
|
|
RawObservationWriteOutcome
|
|
Inserted
|
|
AlreadyPresent
|
|
NotRecorded
|
|
|
|
RawAcquisitionWriteOutcome
|
|
entity + observation
|
|
```
|
|
|
|
Les opérations `persist_raw_*_acquisition` retournent désormais l'outcome combiné et conservent le contrat all-or-nothing RAW + observation.
|
|
|
|
Une même identité avec un contenu divergent doit produire :
|
|
|
|
```text
|
|
ERROR_CODE_RAW_CONFLICT
|
|
```
|
|
|
|
et jamais un overwrite silencieux.
|
|
|
|
Les écritures d'observation seules retournent `RawObservationWriteOutcome`.
|
|
|
|
## Lifecycle RAW transaction
|
|
|
|
Surface ajoutée :
|
|
|
|
```text
|
|
RawRetentionState
|
|
Full
|
|
Compacted
|
|
Archived
|
|
Purged
|
|
|
|
RawTransactionTombstone
|
|
RawTransactionRetentionTransition
|
|
RawRetentionWriteOutcome
|
|
RawTransactionAcquisitionMode
|
|
Normal
|
|
ForceRehydrate
|
|
|
|
RawTransactionRetentionRead
|
|
RawTransactionRetentionWrite
|
|
```
|
|
|
|
Transitions génériques admises :
|
|
|
|
```text
|
|
Full -> Compacted
|
|
Full -> Archived
|
|
Compacted -> Archived
|
|
Archived -> Purged
|
|
```
|
|
|
|
Interdits :
|
|
|
|
```text
|
|
Full -> Purged direct
|
|
Purged -> Full via transition générique
|
|
```
|
|
|
|
La réhydratation est un mode d'acquisition explicitement forcé. En mode normal, un tombstone purgé doit rester connu et produire `SkippedPurged` sans rebackfill automatique.
|
|
|
|
Le tombstone conserve uniquement l'identité transactionnelle, slot, format/version et hash canonique nécessaires au contrat anti-rebackfill ; aucun payload RAW n'y subsiste.
|
|
|
|
## Ownership rétention
|
|
|
|
Le Store applique la transition demandée mais ne décide jamais que les couches supérieures sont terminées. L'éligibilité compression/archive/purge appartient à un futur worker/job/maintenance policy fondé sur les preuves de processing versionnées.
|
|
|
|
La policy reste family-specific ; `RawAccountState` ne reçoit donc aucun lifecycle de purge copié artificiellement depuis `RawTransaction` dans cette tranche.
|
|
|
|
## Canari backend externe
|
|
|
|
Le backend externe de test est mis à jour pour :
|
|
|
|
```text
|
|
queries/pages
|
|
outcomes détaillés
|
|
mode Normal/ForceRehydrate
|
|
retention read/write
|
|
```
|
|
|
|
Il reste implémentable sans `ksp-store-lib`, PostgreSQL, runtime DB ou dépendance async supplémentaire.
|
|
|
|
## Hors scope confirmé
|
|
|
|
```text
|
|
ksp-store-lib
|
|
ksp-store-postgres-lib
|
|
PostgreSQL/tokio-postgres
|
|
Config/std.store
|
|
policy executor/backlog métier
|
|
processing ledger concret
|
|
compression/archive/purge physique
|
|
health runtime
|
|
TransactionStatusObservation commun
|
|
models event-only logs/slot/vote
|
|
RawBlock persistence
|
|
Yellowstone Entry persistence
|
|
N2 STRUCTURAL
|
|
N3 DECODED
|
|
N4 DOMAIN
|
|
```
|
|
|
|
## Validations opérateur de la base
|
|
|
|
```text
|
|
cargo fmt --all PASS
|
|
python3 scripts/audit_rust_workspace_rules.py PASS
|
|
python3 scripts/audit_markdown_tables.py ... PASS
|
|
cargo check --workspace PASS
|
|
cargo clippy --workspace --all-targets PASS
|
|
cargo test -p ksp-store-api PASS
|
|
```
|
|
|
|
## Validations de génération
|
|
|
|
Les audits structurels/Markdown sont rejoués sur l'overlay `pre.006`. `cargo`, `rustc` et `rustfmt` ne sont pas installés dans l'environnement de génération ; le gate Cargo final reste donc opérateur.
|
|
|
|
## Suite
|
|
|
|
`0.3.1-pre.007` effectue le hardening adversarial/completeness : cursor/provenance hostile, races de rétention, exact exports/modules, frontière Interface/Store, dependency firewall et scope négatif N2/N3/N4.
|