v0.3.1-pre.006

This commit is contained in:
2026-08-29 09:10:07 +02:00
parent c83e3261d0
commit b76baf6835
19 changed files with 1175 additions and 60 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/022-V0_3_1_STORE_RAW_PLAN.md -->
<!-- version: 6 -->
<!-- version: 7 -->
# Plan `0.3.1` — Store API RAW foundation
@@ -75,7 +75,7 @@ modèles objet/struct persistants communs
observations d'acquisition persistantes lorsque leur conservation est utile
références durables
outcomes d'écriture/idempotence
queries et pagination bornées
queries cursorisées sans plafond métier arbitraire
health/readiness communs utiles
contrats/capabilities backend extensibles
référence/format canonique de wake-up pour une donnée déjà persistée, conformément aux règles KSP-NOTIFY
@@ -868,35 +868,58 @@ Les opérations `persist_raw_*_acquisition` signifient au contrat que le RAW et
Les opérations `record_raw_*_observation` supposent que la référence RAW ciblée existe déjà et permettent de retenir une acquisition supplémentaire sans retransmettre la donnée RAW complète.
Les listes, queries, backlog, health commun et outcomes détaillés restent à finaliser dans `pre.006`; aucune transaction backend publique n'est nécessaire pour les exprimer.
Les listes, queries et outcomes détaillés restent à finaliser dans `pre.006`; le backlog métier reste hors Store API et appartiendra au futur processing/job layer. Le health runtime reste une responsabilité de la future façade `ksp-store-lib` en `0.3.2`. Aucune transaction backend publique n'est nécessaire pour exprimer les opérations Store.
### 11.5 Outcomes
Le vocabulaire candidat :
`pre.006` matérialise un vocabulaire commun d'idempotence :
```text
RawWriteOutcome
RawEntityWriteOutcome
Inserted
AlreadyPresent
Rehydrated
SkippedPurged
Conflict
= Error KSP stable, pas un succès silencieux
RawObservationWriteOutcome
Inserted
AlreadyPresent
NotRecorded
RawAcquisitionWriteOutcome
entity + observation
```
Pour une acquisition combinée, l'outcome doit distinguer au minimum l'état du RAW et de l'observation sans révéler de clé backend.
`Inserted` et `AlreadyPresent` sont des succès idempotents. Une même identité logique accompagnée d'un contenu divergent produit `ERROR_CODE_RAW_CONFLICT`; aucun backend ne peut résoudre ce cas par overwrite silencieux.
### 11.6 Pagination
Pour `RawTransaction`, `Normal` et `ForceRehydrate` sont deux modes explicites : un tombstone purgé provoque `SkippedPurged` en mode normal ; seul `ForceRehydrate` autorise une réhydratation compatible. Le mode forcé n'annule pas les règles de conflit de contenu/format.
Le concept historique `PageRequest/PageSlice` est repris avec :
### 11.6 Pagination et queries
Le Store fournit un mécanisme de navigation, **pas une policy d'exécution**. `pre.006` introduit :
```text
default = 100
maximum = 500
cursor opaque et borné
ordre déterministe par query
RawPageLimit
> 0
aucun maximum fonctionnel KSP arbitraire
RawPageCursor
opaque
<= 4 KiB pour borner le token hostile
RawPageRequest
RawPage<T>
RawSlotRange
RawSortDirection
RawTransactionQuery
RawAccountStateQuery
```
Le cursor est un token d'implémentation retourné par la façade et réinjecté tel quel par le consumer. Son contenu ne devient pas API et ne doit pas être utilisé comme transport d'un SQL fragment.
Une requête de `5_000_000` éléments n'est pas ramenée silencieusement à `500`, `1000` ou une autre policy Store. Si un backend ne peut physiquement servir qu'une partie de la demande en une opération, il peut retourner cette partie avec un cursor de continuation ou une erreur backend réellement liée à sa capacité ; `ksp-store-lib` ne doit pas inventer un plafond inférieur par prudence.
Le cursor est un token d'implémentation retourné puis réinjecté tel quel par le consumer. Son contenu ne devient pas API, ne transporte jamais un fragment SQL public et sa borne de 4 KiB protège l'admission du token sans limiter le nombre de résultats.
Les queries `0.3.1` décrivent seulement des critères de données (network, slot range, compte optionnel, ordre, page). Elles ne définissent pas de backlog métier, de taille de batch worker, de priorité ou de policy executor. Le futur processing ledger/job layer décidera quoi traiter et dans quel volume.
## 12. Références, événements et cycle de vie N1
@@ -1105,7 +1128,7 @@ L'archive contient aussi les documents kbot2 historiques. Ils avaient déjà for
| logs transactionnels | conservés puis extraits dans la couche Core historique | REDESSINER | restent dans `RawTransaction`, puis deviennent des unités N2 STRUCTURAL ; pas de `RawLog` persistant séparé |
| account observations/states | N1 account observation + N2 account state existaient | REDESSINER | prévoir `RawAccountState`/observation ; N2 seulement si une décomposition réellement utile est démontrée |
| repository traits | capabilities async séparées | REPRENDRE | capabilities read/write fines, aucune obligation de supporter toutes les familles |
| pagination | 100 par défaut, 500 max, cursor opaque | REPRENDRE | mêmes bornes candidates, cursor toujours opaque |
| pagination | cursor opaque historique | REDESSINER | limite caller > 0 sans plafond métier KSP ; cursor hostile borné uniquement |
| replay contracts | sélection + force replay version-aware | REPRENDRE | futur replay piloté par processor/version/input hash, jamais par simple bool |
| `processing_state` RAW | `received/core_extracted/failed` facilitait la queue | REDESSINER | peut servir d'index de travail futur mais ne constitue jamais la preuve durable unique de traitement |
| processing ledger | stage + processor/version + input/hash + status | REPRENDRE | future preuve durable versionnée ; reportée aux couches/jobs concernés |
@@ -1231,7 +1254,7 @@ Les invariants API qui contraignent déjà ce futur schéma restent fixés maint
identités logiques non dépendantes d'une PK SQL
idempotence Inserted/AlreadyPresent/Conflict
atomicité RAW + observation
pagination bornée
pagination cursorisée sans plafond métier KSP
payload versionné et borné
provenance sans secret
round-trip exact du modèle objet commun
@@ -1296,7 +1319,7 @@ transaction logs remain owned by RawTransaction before STRUCTURAL extraction
account/status model compatibility canaries lorsqu'introduits
event-only model does not imply Store capability
atomic-operation contract fake backend
pagination bounds
pagination cursor/zero-limit admission sans plafond métier arbitraire
retention state/tombstone transition invariants
normal backfill skips purged tombstone; forced rehydrate remains explicit
processing proof is not represented by a lone boolean
@@ -1332,7 +1355,7 @@ Aucun PostgreSQL live test n'appartient à `0.3.1` puisque le backend PostgreSQL
| processing ledger versionné | future contrat Store commun | hors surface initiale RAW | avec jobs/N2/N3 | preuve durable stage/version/input, pas bool |
| RAW references | `ksp-store-api` | public | `0.3.1` | reads/replay/lineage |
| write outcomes | `ksp-store-api` | public | `0.3.1` | sémantique idempotente commune |
| query/page | `ksp-store-api` | public | `0.3.1` | backlog/replay backend-agnostic |
| query/page | `ksp-store-api` | public | `0.3.1` | navigation/replay backend-agnostic |
| health portable | `ksp-store-api` | public | `0.3.1` | consumer commun |
| backend capabilities | `ksp-store-api` | public | `0.3.1` | implémentations externes |
| `Store` facade | `ksp-store-lib` | public | `0.3.2` | point de consommation commun |
@@ -1397,7 +1420,7 @@ Matérialiser les contracts read/write object-safe pour transaction/account et l
### `pre.006` — Queries, outcomes et lifecycle RAW
Finaliser reads/list/backlog bornés, atomic acquisition contract, `RawRetentionState`, tombstone minimal et sémantiques normal-skip/force-rehydrate sans implémenter compression/archive physique.
Finaliser reads/list cursorisés sans plafond métier arbitraire, outcomes idempotents/conflict, atomic acquisition contract, `RawRetentionState`, tombstone minimal et sémantiques normal-skip/force-rehydrate sans implémenter compression/archive physique ni policy executor.
### `pre.007` — Boundary/adversarial hardening + completeness
@@ -1467,7 +1490,7 @@ models et capabilities séparés
contrats backend communs stables
backend externe implémentable sans ksp-store-lib
aucun type backend/SQL public
queries/pagination bornées
queries/pagination cursorisée sans plafond métier KSPs
idempotence/conflict semantics explicites
atomic acquisition contract explicite
références durables stables