v0.3.1-pre.001-fix-002
This commit is contained in:
47
ROADMAP.md
47
ROADMAP.md
@@ -80,34 +80,49 @@ Le roadmap décrit les objectifs à atteindre et les grandes étapes prévues. U
|
||||
|
||||
## Architecture de données — progression canonique
|
||||
|
||||
La chaîne durable cible est :
|
||||
La progression durable cible est :
|
||||
|
||||
```text
|
||||
RAW -> CORE -> DECODE -> SPECIALIZED
|
||||
RAW -> STRUCTURAL -> DECODED -> DOMAIN
|
||||
```
|
||||
|
||||
- **RAW** et **CORE** ne nécessitent aucun décodage Program.
|
||||
- À la fin de chaque couche horizontale RAW/CORE, ajouter les jobs/workers/apps nécessaires pour la rendre réellement exploitable avant d'ouvrir la couche suivante.
|
||||
- À partir de **DECODE**, avancer verticalement groupe par groupe : wire -> decode -> matérialisation -> projection spécialisée si utile -> préparation d'exécution -> policy -> execution -> scénarios Devnet.
|
||||
- **RAW** et **STRUCTURAL** ne nécessitent aucun décodage Program.
|
||||
- La progression n'est pas une chaîne obligatoire pour chaque famille : une donnée event-only peut s'arrêter en N1, et un état de compte pourra aller directement vers un futur decoder si aucune décomposition STRUCTURAL utile n'existe.
|
||||
- À la fin des couches horizontales RAW/STRUCTURAL réellement persistées, ajouter les jobs/workers/apps nécessaires avant d'ouvrir la couche suivante.
|
||||
- À partir de **DECODED**, avancer verticalement groupe par groupe ; **DOMAIN** désigne les projections métier et la matérialisation est le processus qui les produit.
|
||||
|
||||
## 0.3.x — RAW / acquisition persistée
|
||||
|
||||
- [/] `0.3.1` — Introduire `ksp-store-api` uniquement avec le **modèle objet commun et les contrats N1 RAW/observations** : transactions et logs dans la première surface, provenance, identités, outcomes, queries/pagination et contrats backend, sans persistence concrète ni configuration backend.
|
||||
- [/] `0.3.1` — Introduire `ksp-store-api` uniquement avec le **modèle objet commun et les contrats N1 RAW/observations** : `RawTransaction` + observations en premier, inventaire/admission cross-source des futurs account/status models, séparation explicite des events realtime non persistés, lifecycle logique de rétention/tombstone, outcomes, queries/pagination et contrats backend, sans persistence concrète ni configuration backend.
|
||||
- [ ] `0.3.2` — Introduire ensemble `ksp-store-lib` et `ksp-store-postgres-lib` : façade/runtime Store commune, feature `postgres` activée par défaut, implémentation PostgreSQL de référence via `tokio-postgres`, Config `std.store`/secrets et migrations privées au backend. Un backend connu demandé par Config mais absent des features compilées est rejeté explicitement.
|
||||
- [ ] `0.3.3` — Étendre `ksp-interface-lib` avec les wires génériques nécessaires aux acquisitions et à la future normalisation de la couche suivant RAW.
|
||||
- [ ] `0.3.3` — Étendre `ksp-interface-lib` avec les modèles passifs/wires réellement partagés par acquisition/workers, notamment les events realtime non persistés retenus par l'audit `0.3.1`, sans dupliquer les modèles persistants de `ksp-store-api`.
|
||||
- [ ] `0.3.4` — Introduire `ksp-job-api` et un job de backfill historique concret consommant uniquement `ksp-store-lib` côté Store.
|
||||
- [ ] `0.3.5` — Introduire une application spécialisée de backfill/inspection RAW.
|
||||
- [ ] Compléter ensuite la couche RAW avec le worker/service live, son contrôle et les outils d'exploitation réellement nécessaires avant de passer à la couche de normalisation générique suivante.
|
||||
|
||||
## Série CORE suivante
|
||||
### TODO/IDEAS — taxonomie N1, processing et rétention
|
||||
|
||||
- [ ] Définir la persistence CORE canonique Solana générique.
|
||||
- [ ] Implémenter `RAW -> CORE` sans decoder Program : blocs, slots, signatures, transactions/messages, comptes, instructions/CPI brutes, logs/meta et relations structurelles.
|
||||
- [ ] Ajouter replay/backfill RAW -> CORE.
|
||||
- [ ] Ajouter worker/service CORE.
|
||||
- [ ] Ajouter l'application de contrôle/inspection CORE utile.
|
||||
- [ ] **TODO** — maintenir une matrice d'admission HTTP/WS/gRPC/provider pour chaque modèle N1 : plusieurs sources ne convergent vers un même struct que si elles satisfont la même sémantique sans perte.
|
||||
- [ ] **TODO** — `RawAccountState` + observation : auditer les shapes HTTP/WS/Yellowstone, conserver les bytes canoniques et documenter les limites de backfill historique avant de figer la capability de persistence.
|
||||
- [ ] **TODO** — `TransactionStatusObservation` : auditer `signatureSubscribe`, `getSignatureStatuses`, Yellowstone TransactionStatus et extensions provider ; distinguer persistence éventuelle et déclenchement d'event.
|
||||
- [ ] **TODO** — logs realtime : conserver `logMessages` dans `RawTransaction` jusqu'à la décomposition STRUCTURAL ; traiter `logsSubscribe` comme event-only candidat et décider son contrat passif dans `ksp-interface-lib`, sans table Store par défaut. Le format canonique d'un wake-up « donnée persistée disponible » reste distinct et appartient à `ksp-store-api` conformément à `KSP-NOTIFY-*`, tandis que sa publication appartient au worker/runtime.
|
||||
- [ ] **TODO** — slot/root/slotsUpdates et vote : ne créer un modèle passif commun que si un consumer realtime réel et une sémantique cross-ledger/provider justifient le contrat ; aucune persistence Store par défaut.
|
||||
- [ ] **IDEA** — `RawBlock` : ne rouvrir que si une information block-level non reconstructible devient nécessaire ; `getBlock` doit d'abord être traité comme source de `RawTransaction`, pas comme invitation à recopier le ledger en blocs.
|
||||
- [ ] **REJET ACTUEL** — Yellowstone `Entry` : trop bas niveau et aucune destination replay/decomposition/event métier justifiant un modèle KSP n'est identifiée.
|
||||
- [ ] **TODO** — processing ledger : reprendre l'idée kbot2/kbot3 `stage + processor identity/version + input identity/hash + terminal status`, sans faire d'un `processed: bool` la preuve durable unique ; prévoir force replay/version upgrades.
|
||||
- [ ] **TODO** — lifecycle RAW : prévoir `Full -> Compacted -> Archived -> Purged`, policy d'éligibilité hors Store, compression/archive backend futures et tombstone minimal empêchant un backfill normal après purge ; une réhydratation doit être explicitement forcée.
|
||||
- [ ] **TODO** — frontière `ksp-interface-lib` / `ksp-store-api` : documenter chaque type partagé afin que les events passifs non persistés vivent dans Interface et que les modèles persistants/replayables vivent dans Store API, sans doublons quasi équivalents.
|
||||
- [ ] **IDEA** — réauditer la structure de processing/decode/materialization historique kbot2/kbot3 lors de l'ouverture de N2/N3 ; conserver l'isolation instruction/CPI et les statuts terminal/versionnés, sans reprendre automatiquement le schéma SQL historique.
|
||||
|
||||
## Séries DECODE/SPECIALIZED/EXECUTION — progression verticale
|
||||
## Série STRUCTURAL suivante
|
||||
|
||||
- [ ] Définir la persistence STRUCTURAL canonique Solana générique pour les familles réellement décomposables.
|
||||
- [ ] Implémenter en priorité `RawTransaction -> STRUCTURAL` sans decoder Program : transaction/message, comptes/références, instructions top-level, CPI/inner instructions, logs/meta/balances/return data et relations structurelles.
|
||||
- [ ] Vérifier avant extension si d'autres familles N1 possèdent une vraie décomposition STRUCTURAL utile ; ne pas créer de niveau vide par convention.
|
||||
- [ ] Ajouter replay/backfill RAW -> STRUCTURAL avec processing versionné.
|
||||
- [ ] Ajouter worker/service STRUCTURAL et l'application de contrôle/inspection utile.
|
||||
|
||||
## Séries DECODED/DOMAIN/EXECUTION — progression verticale
|
||||
|
||||
### Priorité 1 — Solana Core Programs
|
||||
|
||||
@@ -120,7 +135,7 @@ RAW -> CORE -> DECODE -> SPECIALIZED
|
||||
- [ ] SPL Token.
|
||||
- [ ] Associated Token Account.
|
||||
- [ ] Token-2022 et extensions pertinentes.
|
||||
- [ ] Pour chaque famille : decode -> materialize -> specialized -> prepare -> policy -> execute -> scenarios.
|
||||
- [ ] Pour chaque famille : decode -> materialize -> domain projection -> prepare -> policy -> execute -> scenarios.
|
||||
|
||||
### Priorité 3 — Metadata token
|
||||
|
||||
@@ -144,7 +159,7 @@ RAW -> CORE -> DECODE -> SPECIALIZED
|
||||
|
||||
- [ ] Après les premiers groupes Meteora/Raydium/Pump/Orca, introduire une petite `ksp-app-market-desk` spécialisée.
|
||||
- [ ] Visualiser tokens, pools/markets, liquidité, swaps/trades, prix, volumes, OHLC/candles et activité live/récente lorsque disponible.
|
||||
- [ ] Lire les projections SPECIALIZED KSP ; ne pas reconstruire la logique protocolaire dans l'UI.
|
||||
- [ ] Lire les projections DOMAIN KSP ; ne pas reconstruire la logique protocolaire dans l'UI.
|
||||
|
||||
### Routing
|
||||
|
||||
|
||||
194
deltas/0.3.1/pre.001-fix.002.md
Normal file
194
deltas/0.3.1/pre.001-fix.002.md
Normal file
@@ -0,0 +1,194 @@
|
||||
<!-- file: deltas/0.3.1/pre.001-fix.002.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.3.1-pre.001-fix.002` — taxonomie N1, STRUCTURAL et lifecycle RAW
|
||||
|
||||
## 1. Base
|
||||
|
||||
```text
|
||||
livraison : 0.3.1-pre.001-fix.001
|
||||
Cargo : 0.3.1-pre.1
|
||||
```
|
||||
|
||||
Le gate opérateur post-`fix.001` fourni est vert pour `cargo fmt --all`, audits Rust/Markdown, `cargo check --workspace` et `cargo clippy --workspace --all-targets`. L'opérateur indique également que la validation des tests est OK.
|
||||
|
||||
Ce correctif reste strictement documentaire : aucune crate, API Rust, Config, dependency, migration ou runtime Store n'est créé.
|
||||
|
||||
## 2. Motif
|
||||
|
||||
Le brainstorming avant `pre.002` révèle que la taxonomie précédente était encore trop proche d'un pipeline linéaire et traitait à tort les logs transactionnels et `logsSubscribe` comme une même famille persistante.
|
||||
|
||||
Le correctif doit aussi préserver deux besoins futurs avant qu'une API publique ne les rende difficiles à ajouter :
|
||||
|
||||
```text
|
||||
frontière claire ksp-interface-lib / ksp-store-api
|
||||
processing versionné + retention/compaction/archive/purge du RAW
|
||||
```
|
||||
|
||||
## 3. Taxonomie N1 corrigée
|
||||
|
||||
Règle d'admission : deux réponses HTTP/WS/gRPC/provider convergent vers le même modèle N1 seulement si elles satisfont intégralement la même sémantique KSP sans perte.
|
||||
|
||||
Classification courante :
|
||||
|
||||
```text
|
||||
RawTransaction + observation
|
||||
= N1 persistant certain
|
||||
|
||||
transaction logMessages
|
||||
= partie de RawTransaction ; extraction future en N2 STRUCTURAL
|
||||
|
||||
RawAccountState + observation
|
||||
= modèle N1 à prévoir après matrice de compatibilité
|
||||
|
||||
TransactionStatusObservation
|
||||
= modèle/observation à explorer et prévoir si la sémantique converge
|
||||
|
||||
logsSubscribe / slot / vote
|
||||
= event-only candidats ; pas de persistence Store par défaut
|
||||
|
||||
RawBlock
|
||||
= IDEA seulement ; getBlock sert d'abord de conteneur d'acquisition de transactions
|
||||
|
||||
Yellowstone Entry
|
||||
= examiné et non retenu actuellement
|
||||
```
|
||||
|
||||
## 4. N2 renommé STRUCTURAL
|
||||
|
||||
La chaîne historique :
|
||||
|
||||
```text
|
||||
RAW -> CORE -> DECODE -> SPECIALIZED
|
||||
```
|
||||
|
||||
est remplacée comme vocabulaire cible par :
|
||||
|
||||
```text
|
||||
RAW -> STRUCTURAL -> DECODED -> DOMAIN
|
||||
```
|
||||
|
||||
N2 décrit une décomposition structurelle, pas un « Core » métier. Le premier cas certain est `RawTransaction -> STRUCTURAL` avec transaction/message, account refs, instructions top-level, CPI/inner instructions, logs/meta/balances/return data.
|
||||
|
||||
Toutes les familles N1 ne sont pas obligées de passer par N2.
|
||||
|
||||
## 5. Frontière Interface / Store
|
||||
|
||||
La règle fixée est :
|
||||
|
||||
```text
|
||||
persistant / replayable / queryable
|
||||
-> ksp-store-api
|
||||
|
||||
observation durable d'un fait Store
|
||||
-> ksp-store-api
|
||||
|
||||
event-only passif inter-composants
|
||||
-> ksp-interface-lib de préférence
|
||||
|
||||
format canonique « donnée persistée disponible »
|
||||
-> ksp-store-api, publication par worker/runtime après commit
|
||||
|
||||
shape HTTP/WS/gRPC/provider
|
||||
-> Transport seulement
|
||||
```
|
||||
|
||||
Un modèle event-only n'implique jamais automatiquement une capability Store. Les conversions restent explicites lorsque les sémantiques diffèrent.
|
||||
|
||||
## 6. Processing et lifecycle RAW
|
||||
|
||||
L'audit des documents kbot2 embarqués dans l'archive kbot3 retrouve :
|
||||
|
||||
```text
|
||||
full -> compacted -> archived -> purged
|
||||
```
|
||||
|
||||
et un replay piloté par une identité de processing incluant stage, processor/version et input hash.
|
||||
|
||||
KSP reprend les concepts en les redessinant :
|
||||
|
||||
- aucun `processed: bool` ne constitue la preuve durable unique ;
|
||||
- le futur processing ledger doit être version-aware et input-hash-aware ;
|
||||
- la policy d'éligibilité à la rétention appartient à un worker/job/maintenance layer, pas au Store ;
|
||||
- le Store applique uniquement une transition logique/atomique demandée ;
|
||||
- un tombstone minimal reste après purge afin qu'un backfill normal n'acquière pas de nouveau la même transaction ;
|
||||
- une réhydratation après purge exige un mode explicitement forcé ;
|
||||
- les policies de rétention peuvent différer selon la famille RAW.
|
||||
|
||||
Le payload RAW n'a donc pas vocation à rester éternellement en stockage chaud lorsque les couches dérivées et la policy active permettent sa compaction/archive/purge.
|
||||
|
||||
## 7. ROADMAP
|
||||
|
||||
`ROADMAP.md` est corrigé pour :
|
||||
|
||||
- remplacer CORE par STRUCTURAL dans la progression future ;
|
||||
- rappeler que les niveaux ne sont pas obligatoires pour toutes les familles ;
|
||||
- préciser `0.3.1` avec admission cross-source, events non persistés et lifecycle/tombstone ;
|
||||
- ajouter un bloc TODO/IDEAS N1/processing/rétention ;
|
||||
- conserver `0.3.2 = ksp-store-lib + ksp-store-postgres-lib` inchangé.
|
||||
|
||||
## 8. Version Cargo
|
||||
|
||||
Fix documentaire uniquement. Conformément au workflow, `workspace.package.version` reste :
|
||||
|
||||
```text
|
||||
0.3.1-pre.1
|
||||
```
|
||||
|
||||
## 9. Fichiers modifiés
|
||||
|
||||
```text
|
||||
ROADMAP.md
|
||||
docs/plans/022-V0_3_1_STORE_RAW_PLAN.md
|
||||
docs/validation/018-V0_3_1_STORE_RAW.md
|
||||
```
|
||||
|
||||
## 10. Fichier ajouté
|
||||
|
||||
```text
|
||||
deltas/0.3.1/pre.001-fix.002.md
|
||||
```
|
||||
|
||||
## 11. Fichiers supprimés
|
||||
|
||||
```text
|
||||
aucun
|
||||
```
|
||||
|
||||
## 12. Validations exécutées
|
||||
|
||||
Dans l'environnement de génération du fix :
|
||||
|
||||
```text
|
||||
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.1
|
||||
Markdown table audit: clean (184 table(s), 123 file(s))
|
||||
```
|
||||
|
||||
`cargo` n'est pas disponible dans cet environnement. Le fix est strictement documentaire et la base opérateur post-`fix.001` a déjà passé `cargo fmt`, `cargo check` et Clippy. Après application du présent fix, le gate opérateur reste :
|
||||
|
||||
```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.1
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
```
|
||||
|
||||
Aucun code n'est modifié et aucun test Store ciblé n'existe encore.
|
||||
|
||||
## 13. Suite
|
||||
|
||||
`pre.002` peut ensuite créer le scaffold `ksp-store-api` avec une taxonomie désormais suffisamment contrainte pour éviter de figer :
|
||||
|
||||
```text
|
||||
un faux RawLog persistant
|
||||
un pipeline N1->N2 obligatoire
|
||||
un processed bool irréversible
|
||||
une retention éternelle du RAW
|
||||
une dépendance implicite entre event runtime et Store
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/022-V0_3_1_STORE_RAW_PLAN.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Plan `0.3.1` — Store API RAW foundation
|
||||
|
||||
@@ -66,24 +66,36 @@ et non :
|
||||
|
||||
## 3. Mission recalibrée
|
||||
|
||||
`0.3.1` introduit `ksp-store-api` comme **modèle logique commun et API fonctionnelle backend-agnostic du niveau N1 / D1 RAW**.
|
||||
`0.3.1` introduit `ksp-store-api` comme **modèle logique commun et API fonctionnelle backend-agnostic du niveau N1 RAW/acquisition**.
|
||||
|
||||
La crate doit posséder :
|
||||
|
||||
```text
|
||||
modèles objet/struct persistants communs
|
||||
observations d'acquisition persistantes lorsque leur conservation est utile
|
||||
références durables
|
||||
provenance d'acquisition
|
||||
outcomes d'écriture/idempotence
|
||||
queries et pagination bornées
|
||||
health/readiness communs utiles
|
||||
contrats/capabilities backend extensibles
|
||||
format canonique de notification de disponibilité si la référence RAW est stabilisée
|
||||
référence/format canonique de wake-up pour une donnée déjà persistée, conformément aux règles KSP-NOTIFY
|
||||
cycle de rétention logique du RAW et tombstones anti-rebackfill
|
||||
```
|
||||
|
||||
La release doit aussi auditer les autres données on-chain réellement utiles afin de distinguer explicitement :
|
||||
|
||||
```text
|
||||
modèle N1 persistant/replayable
|
||||
modèle d'observation persistant
|
||||
modèle event-only non persisté
|
||||
DTO Transport seulement
|
||||
```
|
||||
|
||||
La façade runtime concrète `Store`, la sélection d'un backend compilé et l'orchestration commune appartiendront à `ksp-store-lib` en `0.3.2`. Les consumers ordinaires jobs/workers/apps dépendront alors uniquement de `ksp-store-lib`, qui réexportera la surface commune nécessaire de `ksp-store-api`.
|
||||
|
||||
Elle ne possède pas :
|
||||
`ksp-store-api` ne devient pas propriétaire de tous les messages inter-crates. Un modèle passif partagé qui ne représente aucune donnée persistée/rejouable et sert uniquement à transporter un événement entre acquisition et traitement relève préférentiellement de `ksp-interface-lib`. La frontière exacte doit être documentée avant création d'un tel type afin d'éviter deux structs concurrentes représentant le même fait.
|
||||
|
||||
`ksp-store-api` ne possède pas :
|
||||
|
||||
```text
|
||||
schéma physique
|
||||
@@ -95,9 +107,10 @@ transactions SQL
|
||||
backend selection par lecture Config
|
||||
tokio-postgres
|
||||
PostgreSQL/MySQL/SQLite/RocksDB/ClickHouse types
|
||||
Transport
|
||||
Transport runtime
|
||||
Program decoder
|
||||
Materializer
|
||||
scheduler/event bus/notification runtime
|
||||
```
|
||||
|
||||
Le modèle public `ksp-store-api` est volontairement réutilisable par toute implémentation future. Un backend peut choisir une représentation physique radicalement différente sans modifier les DTO/entités et opérations logiques consommés par l'extérieur.
|
||||
@@ -209,7 +222,7 @@ Trois surfaces restent strictement distinctes :
|
||||
|
||||
```text
|
||||
ksp-store-api
|
||||
RawTransaction / RawLog / provenance / queries / outcomes
|
||||
RawTransaction / observations persistantes / provenance / queries / outcomes
|
||||
= modèle objet et contrats communs à toutes les implémentations
|
||||
|
||||
ksp-store-lib
|
||||
@@ -223,6 +236,35 @@ ksp-store-postgres-lib
|
||||
|
||||
Aucun type de row backend, handle de pool, statement préparé, migration ou nom d'objet SQL ne traverse `ksp-store-lib` vers ses consumers.
|
||||
|
||||
### 4.6 Frontière `ksp-interface-lib` / `ksp-store-api`
|
||||
|
||||
Les deux crates ne doivent pas devenir des définitions concurrentes du même modèle.
|
||||
|
||||
Règle de décision :
|
||||
|
||||
```text
|
||||
fait durable/replayable/queryable par Store
|
||||
-> ksp-store-api
|
||||
|
||||
observation durable attachée à un fait Store
|
||||
-> ksp-store-api
|
||||
|
||||
message passif event-only échangé entre composants
|
||||
sans contrat de persistence
|
||||
-> ksp-interface-lib
|
||||
|
||||
signal canonique « donnée Store persistée disponible »
|
||||
qui ne transporte qu'une référence durable
|
||||
-> ksp-store-api pour le format uniquement
|
||||
|
||||
shape spécifique à HTTP/WS/gRPC/provider
|
||||
-> Transport seulement
|
||||
```
|
||||
|
||||
Lorsqu'un type Interface correspond exactement à une partie d'un modèle Store, `ksp-store-api` peut le réutiliser uniquement si cela ne crée ni dépendance de protocole ni sémantique incomplète. Sinon la composition effectue une conversion explicite. Aucun copier-coller de structs quasi identiques n'est accepté pour éviter une dérive silencieuse des deux contrats.
|
||||
|
||||
Cette règle sera réauditée au moment d'introduire les événements realtime (`logsSubscribe`, slot/vote/status) et les futurs types Interface nécessaires à l'acquisition.
|
||||
|
||||
## 5. Sources KSP relues
|
||||
|
||||
Le gate `pre.001` a relu les sources prescrites par le prompt :
|
||||
@@ -282,61 +324,56 @@ notification != backlog
|
||||
at-least-once + persistence idempotente
|
||||
```
|
||||
|
||||
## 6. N1 / D1 RAW : définition retenue
|
||||
## 6. N1 RAW : définition retenue
|
||||
|
||||
### 6.1 Rôle
|
||||
### 6.1 Rôle et critère d'admission
|
||||
|
||||
N1 est la couche **acquisition persistée / RAW replayable**.
|
||||
N1 est la couche **acquisition / RAW replayable**. Toutes les réponses Transport ne deviennent pas automatiquement des modèles Store.
|
||||
|
||||
Elle ne se limite pas à une table `raw_transactions`. Elle regroupe les faits d'acquisition nécessaires pour rejouer ultérieurement la normalisation générique Solana sans redemander arbitrairement la donnée au provider.
|
||||
|
||||
La première surface concrète `0.3.1` retient :
|
||||
Un type n'entre dans la taxonomie N1 que s'il apporte au moins une valeur durable au pipeline :
|
||||
|
||||
```text
|
||||
RawTransaction
|
||||
RawTransactionObservation
|
||||
RawLog
|
||||
RawLogObservation
|
||||
provenance commune
|
||||
références durables communes
|
||||
persistence / replay
|
||||
future décomposition structurelle
|
||||
future interprétation/décodage
|
||||
état durable nécessaire au processing
|
||||
```
|
||||
|
||||
Les familles suivantes sont explicitement prévues mais reportées tant que leur acquisition/replay exact n'est pas suffisamment auditée :
|
||||
Les données utiles uniquement comme déclencheur realtime peuvent avoir un modèle passif commun, mais ce modèle est event-only et ne reçoit pas automatiquement une capability Store.
|
||||
|
||||
Une même entité N1 ne peut agréger plusieurs sources que si chaque source candidate peut être convertie **sans perte de la sémantique exigée par le contrat commun**. Il est interdit de fabriquer un modèle universel rempli de `Option<T>` uniquement pour faire entrer des réponses incompatibles.
|
||||
|
||||
La règle d'admission est donc :
|
||||
|
||||
```text
|
||||
RawAccount / account observation
|
||||
RawBlock
|
||||
RawSlot / slot update si un besoin durable distinct existe
|
||||
autres familles d'acquisition réellement nécessaires
|
||||
HTTP / WS / gRPC / provider response
|
||||
|
|
||||
v
|
||||
satisfait intégralement le contrat canonique KSP ciblé ?
|
||||
| |
|
||||
oui non
|
||||
| |
|
||||
v v
|
||||
même modèle N1 autre modèle / event
|
||||
+ observation ou DTO Transport seulement
|
||||
```
|
||||
|
||||
Aucun enum fermé ne doit empêcher leur ajout.
|
||||
Une matrice de compatibilité source -> modèle doit être produite avant de figer chaque nouvelle famille.
|
||||
|
||||
### 6.2 Transport n'est pas une famille RAW
|
||||
### 6.2 `RawTransaction` et observation
|
||||
|
||||
Les mécanismes suivants sont des **origines d'acquisition**, pas des modèles persistants distincts :
|
||||
`RawTransaction` est la première famille persistante certaine de `0.3.1`.
|
||||
|
||||
Les sources capables de fournir la transaction complète et la meta nécessaire au replay structurel doivent converger vers le même modèle, indépendamment de l'origine :
|
||||
|
||||
```text
|
||||
HTTP JSON-RPC
|
||||
WebSocket JSON-RPC
|
||||
Yellowstone gRPC
|
||||
provider extension
|
||||
import
|
||||
backfill
|
||||
getTransaction
|
||||
getBlock utilisé comme conteneur d'acquisition
|
||||
transactionSubscribe lorsque la forme fournit le contenu complet
|
||||
yellowstone Transaction
|
||||
future source équivalente auditée
|
||||
```
|
||||
|
||||
Interdit :
|
||||
|
||||
```text
|
||||
RawHttpTransaction
|
||||
RawWsTransaction
|
||||
RawGrpcTransaction
|
||||
```
|
||||
|
||||
La même transaction logique acquise par HTTP, WS et gRPC doit converger vers un `RawTransaction` commun, avec plusieurs observations/provenances si nécessaire.
|
||||
|
||||
### 6.3 Transaction canonique et observation
|
||||
|
||||
Le contrat sépare :
|
||||
|
||||
```text
|
||||
@@ -347,7 +384,9 @@ RawTransactionObservation
|
||||
= fait qu'une source donnée a observé/acquis cette transaction
|
||||
```
|
||||
|
||||
Exemple :
|
||||
Une réponse ne contenant qu'une signature, un status ou un sous-ensemble de champs ne produit jamais un `RawTransaction` artificiellement incomplet.
|
||||
|
||||
La même transaction acquise plusieurs fois converge vers une seule identité logique et plusieurs observations :
|
||||
|
||||
```text
|
||||
RawTransaction T
|
||||
@@ -355,51 +394,119 @@ Exemple :
|
||||
|
|
||||
+---------------+---------------+
|
||||
| | |
|
||||
HTTP/Helius obs WS/Helius obs gRPC/PublicNode obs
|
||||
HTTP/provider obs WS/provider obs gRPC/provider obs
|
||||
```
|
||||
|
||||
La duplication d'observation ne duplique pas automatiquement la transaction canonique.
|
||||
### 6.3 Logs de transaction vs notification de logs
|
||||
|
||||
### 6.4 Raw logs
|
||||
Les `logMessages` contenus dans la meta d'une transaction appartiennent au `RawTransaction`. Ils ne constituent pas une seconde entité N1 `RawLog`.
|
||||
|
||||
`RawLog` est une famille N1 distincte et n'est pas confondue avec la future décomposition CORE des logs.
|
||||
|
||||
Elle doit préserver l'observation de logs suffisamment fidèlement pour :
|
||||
Leur extraction individuelle appartient à la future décomposition STRUCTURAL :
|
||||
|
||||
```text
|
||||
conserver l'ordre des lignes
|
||||
conserver slot/signature/identité applicable
|
||||
conserver le statut source nécessaire
|
||||
permettre replay/inspection
|
||||
permettre de relier un log à une transaction lorsqu'elle est connue
|
||||
RawTransaction
|
||||
-> STRUCTURAL
|
||||
-> TransactionLogLine / relation instructionnelle future
|
||||
```
|
||||
|
||||
Une observation `logsSubscribe` peut également servir de déclencheur pour acquérir ensuite la transaction complète. Le modèle de provenance ne doit pas empêcher une lineage future :
|
||||
À l'inverse, `logsSubscribe` fournit un message realtime centré sur :
|
||||
|
||||
```text
|
||||
RawLogObservation
|
||||
-> déclenche acquisition transaction
|
||||
RawTransactionObservation
|
||||
-> RawTransaction
|
||||
slot
|
||||
signature
|
||||
error/status
|
||||
ordered log lines
|
||||
```
|
||||
|
||||
Cette relation causale n'est pas un orchestrateur et n'est pas obligatoirement implémentée dans `0.3.1`.
|
||||
Ce message peut déclencher un traitement ou l'hydratation de la transaction complète, mais il ne doit pas être confondu avec les logs extraits de `RawTransaction`.
|
||||
|
||||
### 6.5 Autres RAW
|
||||
Le candidat de travail est donc un modèle event-only tel que `TransactionLogNotification`/`RawLogNotification`, dont l'ownership sera tranché entre `ksp-interface-lib` et `ksp-store-api` selon la règle §4.6. **Aucune persistence Store de ces notifications n'est requise par défaut.**
|
||||
|
||||
Le design doit permettre d'ajouter plus tard des familles distinctes sans créer un `RawAnything { kind, json }` universel.
|
||||
|
||||
Le partage se fait par composition de primitives communes :
|
||||
Le pipeline realtime futur pourra faire :
|
||||
|
||||
```text
|
||||
RawAcquisitionProvenance
|
||||
RawPayload
|
||||
RawContentHash / idempotence key
|
||||
RawDataReference
|
||||
PageRequest / Page
|
||||
logsSubscribe
|
||||
-> event passif
|
||||
-> worker/analyser
|
||||
-> éventuellement getTransaction(signature)
|
||||
-> persistence RawTransaction
|
||||
```
|
||||
|
||||
et non par effacement des sémantiques propres à chaque famille.
|
||||
Le Store n'envoie lui-même aucun événement.
|
||||
|
||||
### 6.4 `RawAccountState` et observation
|
||||
|
||||
Les réponses account complètes provenant de HTTP, WS ou Yellowstone peuvent potentiellement converger vers un même état canonique :
|
||||
|
||||
```text
|
||||
pubkey
|
||||
slot/context utile
|
||||
lamports
|
||||
owner
|
||||
executable
|
||||
rent_epoch
|
||||
data bytes exacts
|
||||
```
|
||||
|
||||
Les détails propres à l'acquisition (`write_version`, signature source, startup, provider, transport, timing, etc.) appartiennent à `RawAccountObservation` lorsqu'ils sont utiles et disponibles.
|
||||
|
||||
`RawAccountState`/`RawAccountObservation` doivent être **prévus dans `ksp-store-api`** après validation de la matrice de compatibilité. Leur persistence concrète PostgreSQL peut rester non implémentée au début de `0.3.2`.
|
||||
|
||||
Un compte demandé sous une forme déjà interprétée par le provider ne doit pas remplacer arbitrairement les bytes canoniques nécessaires à un futur decoder.
|
||||
|
||||
### 6.5 Transaction status
|
||||
|
||||
Les surfaces signature/status peuvent représenter un fait distinct d'une transaction complète :
|
||||
|
||||
```text
|
||||
signatureSubscribe
|
||||
getSignatureStatuses
|
||||
Yellowstone TransactionStatus
|
||||
provider equivalent
|
||||
```
|
||||
|
||||
Le candidat `TransactionStatusObservation` doit être étudié et, si la sémantique commune est démontrée, prévu dans l'API même si sa persistence n'est pas immédiatement implémentée.
|
||||
|
||||
Il peut plus tard servir à un worker/analyser pour détecter des transitions de commitment/status. Ce déclenchement n'est pas une responsabilité du Store.
|
||||
|
||||
### 6.6 Slot, vote, block et Yellowstone Entry
|
||||
|
||||
Classification actuelle :
|
||||
|
||||
```text
|
||||
slot/root/slotsUpdates
|
||||
-> event-only candidat ; persistence non justifiée actuellement
|
||||
|
||||
vote
|
||||
-> event-only candidat si la forme est suffisamment commune entre les ledgers/providers qui l'exposent
|
||||
|
||||
getBlock / Yellowstone Block
|
||||
-> source/conteneur d'acquisition de RawTransaction par défaut
|
||||
RawBlock persistant seulement si un besoin block-level non reconstructible est démontré
|
||||
|
||||
Yellowstone Entry
|
||||
-> examiné et non retenu actuellement : trop bas niveau et aucune destination replay/decomposition/event métier suffisante identifiée
|
||||
```
|
||||
|
||||
`RawBlock` reste une IDEA, pas un modèle actif. Recréer le ledger bloc par bloc sans besoin supplémentaire irait à l'encontre de l'objectif KSP de transformer la donnée blockchain en unités directement exploitables.
|
||||
|
||||
### 6.7 Modèles et capabilities sont indépendants
|
||||
|
||||
La présence d'un modèle partagé n'implique pas une persistence.
|
||||
|
||||
Exemple :
|
||||
|
||||
```text
|
||||
TransactionLogNotification
|
||||
= peut exister comme contrat passif event-only
|
||||
|
||||
TransactionLogNotificationStore
|
||||
= ne doit pas exister sans besoin durable démontré
|
||||
```
|
||||
|
||||
De même, `RawAccountState` peut être figé comme modèle commun avant que `ksp-store-postgres-lib` n'implémente sa capability.
|
||||
|
||||
Cette séparation permet d'inventorier correctement N1 sans forcer tous les backends à stocker toutes les familles.
|
||||
|
||||
## 7. Payload replayable
|
||||
|
||||
@@ -446,41 +553,50 @@ hashable/idempotent
|
||||
|
||||
Le Store ne prétend pas que des bytes arbitraires sans format connu sont replayables.
|
||||
|
||||
## 8. Future décomposition N1 -> niveau générique Solana
|
||||
## 8. Future décomposition N1 -> niveau STRUCTURAL
|
||||
|
||||
La frontière architecturale actuelle reste nommée :
|
||||
Le nom de travail de N2 devient **STRUCTURAL**. `CORE` est abandonné dans le nouveau plan parce qu'il décrivait mal une opération qui consiste principalement à décomposer des données Solana brutes en sous-composants génériques.
|
||||
|
||||
La progression conceptuelle devient :
|
||||
|
||||
```text
|
||||
RAW -> CORE -> DECODE -> SPECIALIZED
|
||||
N1 RAW
|
||||
-> N2 STRUCTURAL lorsque le type est réellement décomposable
|
||||
-> N3 DECODED ultérieur
|
||||
-> N4 DOMAIN ultérieur
|
||||
```
|
||||
|
||||
Le nom `CORE` n'est pas considéré comme irréversible. Une revue de nomenclature pourra être faite avant l'ouverture effective de D2 sans modifier les responsabilités déjà fixées.
|
||||
Cette progression n'est **pas une chaîne obligatoire pour toutes les familles N1** :
|
||||
|
||||
Le rôle de D2 reste en revanche clair : décomposer/normaliser une transaction RAW en faits Solana génériques indépendants des decoders Program.
|
||||
```text
|
||||
RawTransaction -> STRUCTURAL -> DECODED -> DOMAIN
|
||||
RawAccountState -> peut aller directement vers un decoder futur si aucune décomposition N2 utile n'existe
|
||||
realtime event -> worker/analyser, sans N2 nécessaire
|
||||
status/slot/vote -> peut rester un fait/event terminal
|
||||
```
|
||||
|
||||
Le futur flux doit permettre notamment :
|
||||
Le premier et seul cas N2 certain aujourd'hui est `RawTransaction`.
|
||||
|
||||
Le futur flux transactionnel doit permettre notamment :
|
||||
|
||||
```text
|
||||
RawTransaction
|
||||
-> transaction/message générique
|
||||
-> account keys
|
||||
-> instruction top-level #0
|
||||
-> instruction top-level #1
|
||||
-> CPI/inner instruction #1.0
|
||||
-> CPI/inner instruction #1.1
|
||||
-> logs/meta/balances/return data applicables
|
||||
-> StructuralTransaction/message
|
||||
-> account keys/références
|
||||
-> StructuralInstruction top-level #0
|
||||
-> StructuralInstruction top-level #1
|
||||
-> inner/CPI instruction #1.0
|
||||
-> inner/CPI instruction #1.1
|
||||
-> transaction logs/meta/balances/return data applicables
|
||||
```
|
||||
|
||||
Chaque instruction/CPI doit ensuite pouvoir être traitée indépendamment :
|
||||
Chaque instruction/CPI doit posséder une identité/path stable et être traitable indépendamment. Un decoder absent ou défaillant pour une instruction ne bloque jamais les autres unités structurales de la transaction.
|
||||
|
||||
```text
|
||||
instruction générique
|
||||
-> decoder disponible ?
|
||||
oui -> decode
|
||||
non -> Unsupported/NotApplicable durable sans bloquer le reste
|
||||
```
|
||||
N2 n'est toutefois pas défini comme « transaction split » : si une autre famille N1 démontre plus tard une vraie décomposition structurelle utile, elle peut rejoindre ce niveau sans changer sa responsabilité.
|
||||
|
||||
`0.3.1` ne crée aucun type D2/CORE et ne dépend pas de `ksp-program-api`.
|
||||
N3 DECODED et N4 DOMAIN ne sont pas conçus dans `0.3.1`. Le plan doit seulement garantir que le RAW transactionnel conserve tout ce qui sera nécessaire à une décomposition STRUCTURAL lossless pour les futurs decoders.
|
||||
|
||||
`0.3.1` ne crée aucun type STRUCTURAL et ne dépend pas de `ksp-program-api`.
|
||||
|
||||
## 9. Provenance commune
|
||||
|
||||
@@ -542,9 +658,9 @@ La signature ne doit pas être représentée comme un identifiant SQL `i64` dans
|
||||
|
||||
Chaque observation possède une clé d'idempotence déterministe fournie par le producer/composition selon un contrat documenté. Deux acquisitions légitimes distinctes peuvent donc être conservées même si elles pointent vers le même RAW.
|
||||
|
||||
### 10.4 Logs
|
||||
### 10.4 Événements et autres familles
|
||||
|
||||
L'identité exacte d'un `RawLog` sera stabilisée avec son modèle concret ; elle doit être déterministe et ne doit pas dépendre d'un primary key backend.
|
||||
Les événements realtime non persistés n'ont pas d'identité Store à inventer. Lorsqu'une nouvelle famille persistante est admise (`RawAccountState`, status durable, etc.), son identité d'idempotence doit être définie avec le modèle concret et ne jamais dépendre d'une primary key backend.
|
||||
|
||||
Aucune promesse exactly-once distribuée n'est faite.
|
||||
|
||||
@@ -552,44 +668,52 @@ Aucune promesse exactly-once distribuée n'est faite.
|
||||
|
||||
### 11.1 Contrats communs
|
||||
|
||||
`ksp-store-api` définit le modèle et les opérations backend-agnostic qu'une implémentation doit satisfaire. `0.3.1` ne construit pas de backend, ne sélectionne aucun moteur et n'introduit pas encore la façade runtime concrète `Store`.
|
||||
`ksp-store-api` définit le modèle persistant et les opérations backend-agnostic qu'une implémentation doit satisfaire. `0.3.1` ne construit pas de backend, ne sélectionne aucun moteur et n'introduit pas encore la façade runtime concrète `Store`.
|
||||
|
||||
Le backend concret implémente un contrat public d'extension, mais son modèle interne reste privé. En `0.3.2`, `ksp-store-lib::Store` enveloppera ce contrat et deviendra la seule façade de consommation normale des jobs/workers/apps.
|
||||
Le backend concret implémente des contrats publics d'extension, mais son modèle interne reste privé. En `0.3.2`, `ksp-store-lib::Store` enveloppera ces contrats et deviendra la seule façade de consommation normale des jobs/workers/apps.
|
||||
|
||||
### 11.2 Object-safety et async
|
||||
|
||||
La future sélection runtime impose que le contrat backend puisse être stocké derrière une abstraction dynamique sans connaître le moteur concret.
|
||||
La future sélection runtime impose que les capabilities backend puissent être stockées derrière une abstraction dynamique sans connaître le moteur concret.
|
||||
|
||||
La stratégie candidate est :
|
||||
|
||||
```text
|
||||
StoreBackend: Send + Sync
|
||||
capabilities Send + Sync
|
||||
méthodes object-safe
|
||||
futures boxed KSP-owned via un alias StoreFuture<'a, T>
|
||||
future ksp-store-lib::Store possède Arc<dyn StoreBackend>
|
||||
future ksp-store-lib::Store compose les capabilities disponibles
|
||||
```
|
||||
|
||||
Cette stratégie évite une dépendance `async-trait` uniquement pour masquer la transformation. Le coût d'une box de future est accepté au niveau Store, dominé par l'I/O de persistence, et doit rester mesurable si un chemin futur démontre le contraire.
|
||||
|
||||
### 11.3 Capabilities
|
||||
### 11.3 Capabilities séparées
|
||||
|
||||
Éviter un trait de 150 méthodes. La candidate est une composition de capabilities N1 :
|
||||
Éviter un trait monolithique exigeant tous les types de données à chaque backend.
|
||||
|
||||
La candidate est une composition fine :
|
||||
|
||||
```text
|
||||
StoreHealth
|
||||
RawTransactionStore
|
||||
RawLogStore
|
||||
RawTransactionRead
|
||||
RawTransactionWrite
|
||||
RawTransactionObservationRead
|
||||
RawTransactionObservationWrite
|
||||
|
||||
future RawAccountStateRead
|
||||
future RawAccountStateWrite
|
||||
future TransactionStatus* si persistence réellement retenue
|
||||
```
|
||||
|
||||
Un contrat composite `StoreBackend` peut agréger les capabilities N1 nécessaires à la future façade `ksp-store-lib::Store`.
|
||||
Un modèle event-only ne crée aucune capability Store par défaut.
|
||||
|
||||
Les futures couches D2/D3/D4 ne sont pas ajoutées par anticipation.
|
||||
La future façade `ksp-store-lib::Store` peut exposer seulement les capabilities réellement compilées/supportées et produire une erreur stable lorsqu'une opération demandée n'est pas disponible.
|
||||
|
||||
### 11.4 Opérations atomiques métier
|
||||
|
||||
Aucun handle de transaction SQL/public n'est exposé.
|
||||
|
||||
Les invariants multi-écritures sont exprimés par des opérations logiques communes. Candidate :
|
||||
Les invariants multi-écritures sont exprimés par des opérations logiques communes. Candidate initiale :
|
||||
|
||||
```text
|
||||
persist_transaction_acquisition(transaction, observation)
|
||||
@@ -598,16 +722,13 @@ get_raw_transaction(reference)
|
||||
list_raw_transactions(query, page)
|
||||
list_transaction_observations(query, page)
|
||||
|
||||
persist_log_acquisition(raw_log, observation)
|
||||
record_log_observation(observation)
|
||||
get_raw_log(reference)
|
||||
list_raw_logs(query, page)
|
||||
list_log_observations(query, page)
|
||||
future persist_account_acquisition(state, observation)
|
||||
future account reads/queries
|
||||
|
||||
health()
|
||||
```
|
||||
|
||||
`persist_*_acquisition` signifie au contrat que le RAW et son observation réussissent atomiquement ou échouent ensemble. PostgreSQL réalisera cela avec une transaction privée en `0.3.2`; un autre backend utilisera son mécanisme natif.
|
||||
`persist_transaction_acquisition` signifie au contrat que le RAW et son observation réussissent atomiquement ou échouent ensemble. PostgreSQL réalisera cela avec une transaction privée en `0.3.2`; un autre backend utilisera son mécanisme natif.
|
||||
|
||||
### 11.5 Outcomes
|
||||
|
||||
@@ -637,40 +758,120 @@ ordre déterministe par query
|
||||
|
||||
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.
|
||||
|
||||
## 12. Références durables et notifications
|
||||
## 12. Références, événements et cycle de vie N1
|
||||
|
||||
L'ownership `KSP-NOTIFY-001..006` reste à `ksp-store-api`.
|
||||
### 12.1 Références durables
|
||||
|
||||
Le candidat est une référence compacte :
|
||||
`ksp-store-api` doit posséder les références compactes nécessaires aux lectures, au replay et aux relations entre couches, sans encoder une PK SQL.
|
||||
|
||||
Pour la première famille :
|
||||
|
||||
```text
|
||||
RawDataReference
|
||||
Transaction(RawTransactionReference)
|
||||
Log(RawLogReference)
|
||||
futures variantes non exhaustives
|
||||
RawTransactionReference
|
||||
network
|
||||
signature
|
||||
```
|
||||
|
||||
Puis un signal logique :
|
||||
Les autres références sont ajoutées uniquement avec leur modèle réel.
|
||||
|
||||
### 12.2 Événements : ownership hors Store runtime
|
||||
|
||||
Le Store runtime persiste et lit. Il ne possède ni scheduler, ni event bus, ni mécanisme de publication et ne doit pas s'appuyer sur une notification native de base de données pour piloter le pipeline.
|
||||
|
||||
Les règles `KSP-NOTIFY-001..006` restent applicables : `ksp-store-api` peut posséder **le format canonique** d'un wake-up signifiant qu'une donnée déjà commitée est disponible, sous forme de référence durable compacte. Cela ne signifie pas que la base ou `ksp-store-lib` publie elle-même le signal.
|
||||
|
||||
Le futur ordre d'orchestration est :
|
||||
|
||||
```text
|
||||
RawDataAvailable {
|
||||
reference,
|
||||
}
|
||||
worker/acquisition
|
||||
-> Store.persist(...)
|
||||
-> succès/commit durable
|
||||
-> publisher worker/analyser/runtime
|
||||
-> notification canonique de référence si nécessaire
|
||||
```
|
||||
|
||||
Le mécanisme de diffusion est hors scope.
|
||||
La notification persistée-data reste un wake-up et jamais la source de vérité du backlog. Les messages realtime d'acquisition (`logsSubscribe`, slot/vote, etc.) suivent la frontière §4.6 : `ksp-interface-lib` est le owner préféré lorsqu'ils ne représentent aucune donnée Store persistée.
|
||||
|
||||
Ordre obligatoire :
|
||||
### 12.3 Preuves de processing versionnées
|
||||
|
||||
Un simple champ :
|
||||
|
||||
```text
|
||||
persist
|
||||
commit
|
||||
notify
|
||||
processed = true
|
||||
```
|
||||
|
||||
La notification ne transporte pas le payload RAW et ne remplace jamais `list_*`/backlog Store.
|
||||
n'est pas une preuve durable suffisante.
|
||||
|
||||
Si les références concrètes ne sont pas assez stabilisées lors de leur tranche, le type de notification peut être reporté sans déplacer son ownership.
|
||||
L'audit kbot2/kbot3 confirme l'intérêt d'un ledger version-aware identifié au minimum par :
|
||||
|
||||
```text
|
||||
stage
|
||||
processor identity/name
|
||||
processor version
|
||||
input identity
|
||||
input hash/version
|
||||
terminal status
|
||||
```
|
||||
|
||||
Le contrat concret de processing sera introduit avec les jobs/couches concernés, pas dans la foundation RAW par anticipation. En revanche, les modèles N1 et leur rétention doivent rester compatibles avec ce futur ledger et avec le force replay.
|
||||
|
||||
### 12.4 Rétention, compression, archivage et purge
|
||||
|
||||
N1 ne doit pas imposer la conservation éternelle du payload RAW en stockage chaud.
|
||||
|
||||
Le cycle logique candidat, repris puis redessiné depuis kbot2, est :
|
||||
|
||||
```text
|
||||
Full
|
||||
-> Compacted (optionnel)
|
||||
Full/Compacted
|
||||
-> Archived
|
||||
-> Purged
|
||||
```
|
||||
|
||||
Ces états décrivent **la disponibilité du payload**, pas le succès des processors supérieurs.
|
||||
|
||||
La décision d'éligibilité appartient à un futur worker/job/maintenance policy qui vérifie les preuves de processing nécessaires. Le Store applique une transition bornée/atomique mais ne décide pas lui-même qu'une transaction est suffisamment décodée.
|
||||
|
||||
Une policy typique pourra exiger par exemple :
|
||||
|
||||
```text
|
||||
STRUCTURAL courant réussi pour le hash RAW courant
|
||||
unités structurales dans un état terminal selon la coverage policy active
|
||||
horizon de rétention minimal atteint
|
||||
aucun traitement/replay explicitement en cours
|
||||
archive durable confirmée si la policy exige une archive avant purge
|
||||
```
|
||||
|
||||
L'expression « toutes les instructions sont décodées » ne peut pas être un absolu open-world : un nouveau decoder peut apparaître plus tard. Les états terminaux doivent donc être évalués par rapport à une **coverage/version policy explicite**. Une instruction marquée `no_decoder/unsupported` peut rester redécodable ultérieurement depuis N2 STRUCTURAL sans exiger le RAW si N2 a conservé les faits nécessaires.
|
||||
|
||||
La purge physique du payload ne supprime pas l'identité logique. Un tombstone minimal durable doit rester afin d'empêcher un backfill normal de réacquérir indéfiniment une transaction déjà traitée :
|
||||
|
||||
```text
|
||||
network
|
||||
transaction signature / identité logique
|
||||
slot lorsqu'il est connu
|
||||
canonical format id/version
|
||||
content hash
|
||||
retention state
|
||||
processing/retention provenance minimale nécessaire
|
||||
```
|
||||
|
||||
Comportement attendu :
|
||||
|
||||
```text
|
||||
backfill normal + tombstone
|
||||
-> skip / AlreadyKnownPurged
|
||||
|
||||
backfill explicitement forcé
|
||||
-> réhydratation autorisée selon policy
|
||||
```
|
||||
|
||||
Le tombstone ne doit pas prétendre remplacer le RAW pour replay. Si une nouvelle version STRUCTURAL a réellement besoin du document RAW purgé, une réhydratation forcée depuis une archive ou le réseau est nécessaire.
|
||||
|
||||
La policy est **spécifique à chaque famille**. `RawAccountState`, qui pourrait aller directement vers un decoder futur, ne peut pas réutiliser automatiquement la même politique de purge que `RawTransaction`.
|
||||
|
||||
`0.3.1` doit préparer les contrats logiques de rétention/tombstone sans implémenter compression, stockage d'archive, cron/worker de purge ou maintenance PostgreSQL.
|
||||
|
||||
## 13. Health et diagnostics
|
||||
|
||||
@@ -742,37 +943,41 @@ ks-config/src/store.rs
|
||||
docs/architecture/STORAGE_ARCHITECTURE.md
|
||||
docs/guides/POSTGRES_STORAGE.md
|
||||
docs/plans/V0_5_3_KS_STORE_NORMALIZATION_PLAN.md
|
||||
olddocs/archivekbot2/docs/RAW_STORAGE_LIFECYCLE.md
|
||||
olddocs/archivekbot2/docs/CORE_EXTRACTION_SELECTION_AND_REPLAY.md
|
||||
olddocs/archivekbot2/docs/CORE_EXTRACTION_CONTRACTS.md
|
||||
```
|
||||
|
||||
Le Store historique couvre 16 tables N1-N3, 240 ressources SQL atomiques et 79 index attendus. Cette surface confirme l'intérêt de la séparation façade/backend, de l'idempotence et des observations, mais elle est beaucoup trop large pour `0.3.1`.
|
||||
|
||||
L'archive contient aussi les documents kbot2 historiques. Ils avaient déjà formalisé deux idées utiles : un cycle RAW `full/compacted/archived/purged` et un processing ledger versionné pour décider skip/replay. KSP reprend les concepts mais rejette le couplage à un simple `processing_state` global et redessine la rétention comme une policy externe au Store.
|
||||
|
||||
### 15.2 Matrice d'héritage
|
||||
|
||||
| Concept historique | Observation kbot3 | Décision | Application KSP |
|
||||
|-----------------------------------------|-------------------------------------------------------------------|------------|----------------------------------------------------------------------------------------------------------|
|
||||
| séparation façade Store / PostgreSQL | PostgreSQL et `sqlx::PgPool` privés | REPRENDRE | API commune séparée; façade + backend PostgreSQL reportés à `0.3.2` |
|
||||
| `StoreOpenOptions` / backend selection | backend + `serde_json::Value` opaque dans Store | REDESSINER | Config produit les settings communs; `ksp-store-lib` sélectionne un backend compilé et construit `Store` |
|
||||
| health/readiness | contrat backend-neutral présent | REPRENDRE | health minimal portable dans `ksp-store-api` |
|
||||
| `contracts/dto/raw.rs` | transaction canonique + observations transaction/account | REDESSINER | transaction + logs + provenance commune, sans JSON universel ni lifecycle D2/D3 |
|
||||
| `contracts/entity/raw.rs` | rows exposant `i64`, JSON et timestamps backend-shaped | REDESSINER | entités logiques sans PK SQL ni type physique |
|
||||
| `RawTransactionStore` | `has_*` puis inserts séparés | REDESSINER | write idempotent atomique sans check-then-insert |
|
||||
| repository traits | capabilities async séparées | REPRENDRE | capabilities N1 séparées + façade commune |
|
||||
| pagination | 100 par défaut, 500 max, cursor opaque | REPRENDRE | mêmes bornes candidates, cursor toujours opaque |
|
||||
| replay contracts | filtres mêlés au processing N2/N3 | REPORTER | `0.3.1` fournit seulement lectures RAW nécessaires au futur replay |
|
||||
| error contracts | erreurs Store historiques | REDESSINER | `ksp_core_lib::Error/Result` + codes Store stables |
|
||||
| schema validation / migration bootstrap | validation stricte des objets PostgreSQL | REPORTER | responsabilité `ksp-store-postgres-lib` en `0.3.2` |
|
||||
| migrations atomiques | ressources SQL actives nombreuses | REPORTER | aucune migration dans Store API |
|
||||
| constraints/indexes | 79 index attendus | REPORTER | design physique seulement après stabilisation API |
|
||||
| idempotence / uniqueness | observation keys + canonical identity | REPRENDRE | sémantique publique déterministe; mécanisme backend privé |
|
||||
| raw transaction table | table physique `k_sol_raw_transactions` | REPORTER | `RawTransaction` commun maintenant; table privée à `ksp-store-postgres-lib` en `0.3.2` |
|
||||
| acquisition observations | transaction + account observations | REPRENDRE | concept N1 central; transaction + log initialement |
|
||||
| processing ledger | couvre N2/N3 processing | REPORTER | appartient aux futures couches de processing, pas N1 foundation |
|
||||
| CORE tables | transaction, keys, instructions, CPI, logs, balances, return data | REPORTER | future couche D2, aucune surface en `0.3.1` |
|
||||
| DECODE coverage/events | contrats decoder/materializer | REPORTER | future D3 |
|
||||
| materialization journal | `k_sol_mat_outputs` | REPORTER | future D3 |
|
||||
| maintenance truncate/drop | scripts destructifs dédiés | REJETER | aucune API runtime générique destructive Store |
|
||||
| Config Store | backend + options JSON historiques | REDESSINER | Config reste owner; settings Store/URI secrets adaptés vers `ksp-store-lib` en `0.3.2` |
|
||||
| runtime diagnostics | résumés sanitised mais backend riches | REDESSINER | health portable dans API; détails backend privés |
|
||||
| Concept historique | Observation kbot2/kbot3 | Décision | Application KSP |
|
||||
|------------------------------------------|-------------------------------------------------------------------|------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| séparation façade Store / PostgreSQL | PostgreSQL et driver privés | REPRENDRE | API commune séparée ; façade + backend PostgreSQL reportés à `0.3.2` |
|
||||
| `StoreOpenOptions` / backend selection | backend + options historiques partiellement opaques | REDESSINER | Config produit les settings ; `ksp-store-lib` sélectionne un backend compilé |
|
||||
| health/readiness | contrat backend-neutral présent | REPRENDRE | health minimal portable dans `ksp-store-api` |
|
||||
| transaction canonique source-independent | HTTP/WS/gRPC convergent vers une transaction canonique | REPRENDRE | `RawTransaction` commun seulement si la source satisfait le contrat complet |
|
||||
| acquisition observations | transaction + account observations séparées du RAW | REPRENDRE | concept N1 central ; transaction d'abord, account prévu après matrice de compatibilité |
|
||||
| ancienne raw WS notification | kbot2 l'a supprimée de la baseline persistante | REPRENDRE | `logsSubscribe`/events restent event-only par défaut ; pas de table de notification brute |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| retention lifecycle | `full/compacted/archived/purged` déjà envisagé dans kbot2 | REDESSINER | états logiques backend-agnostic + policy externe + tombstone anti-rebackfill |
|
||||
| CORE tables | transaction, keys, instructions, CPI, logs, balances, return data | REDESSINER | future couche N2 renommée STRUCTURAL ; aucune surface créée en `0.3.1` |
|
||||
| DECODE coverage/events | états `decoded/ignored/unsupported/failed` versionnés | REPORTER | future N3 ; utile à la policy de rétention mais pas défini dans la foundation RAW |
|
||||
| materialization journal | sorties génériques versionnées | REPORTER | future N3/N4 |
|
||||
| raw transaction table | table physique unique par signature | REPORTER | modèle commun maintenant ; table privée à `ksp-store-postgres-lib` en `0.3.2` |
|
||||
| schema validation / migrations / indexes | forte surface PostgreSQL | REPORTER | responsabilité `ksp-store-postgres-lib` |
|
||||
| maintenance truncate/drop | scripts destructifs dédiés | REJETER | aucune API runtime générique destructive ; rétention contrôlée distincte |
|
||||
| Config Store | backend/options historiques | REDESSINER | Config reste owner ; URI/secrets adaptés vers `ksp-store-lib` en `0.3.2` |
|
||||
| modèles partagés hors Store | kbot3 recommandait de ne pas dupliquer les modèles communs | REPRENDRE | frontière explicite `ksp-interface-lib` / `ksp-store-api`, conversion explicite lorsque les sémantiques diffèrent |
|
||||
|
||||
## 16. Audit PostgreSQL et driver de référence futur
|
||||
|
||||
@@ -906,22 +1111,27 @@ La trajectoire roadmap corrigée est :
|
||||
|
||||
## 19. Threat model `0.3.1`
|
||||
|
||||
| Menace | Réponse de design |
|
||||
|------------------------------|-----------------------------------------------------------------------|
|
||||
| payload hostile trop grand | bornes à la construction des contrats RAW avant persistence |
|
||||
| raw payload leak via `Debug` | implémentations Debug manuelles/redacted pour conteneurs sensibles |
|
||||
| secret provider/endpoint | provenance ne contient que des ids/codes sûrs, jamais URL/credential |
|
||||
| duplicate race | write idempotent atomique, jamais `has_*` comme précondition |
|
||||
| même clé / contenu divergent | conflit explicite, pas d'overwrite silencieux |
|
||||
| partial RAW + observation | opération `persist_*_acquisition` atomique au contrat |
|
||||
| cursor hostile | taille/limit bornées; cursor opaque non interprété par consumer |
|
||||
| query non bornée | aucune liste publique sans `PageRequest` borné |
|
||||
| backend leak | aucun type driver/row/table/SQL dans la façade |
|
||||
| backend error leak | mapping vers erreurs KSP sûres; source externe auditée avant chaînage |
|
||||
| closed-world backend | contrat implémentable hors `ksp-store-lib` |
|
||||
| closed-world RAW family | types/familles extensibles sans JSON fourre-tout |
|
||||
| cross-backend mismatch | conformance suite commune sur chaque implémentation |
|
||||
| scope creep D2/D3/D4 | aucun type CORE/DECODE/SPECIALIZED dans `0.3.1` |
|
||||
| Menace | Réponse de design |
|
||||
|--------------------------------|--------------------------------------------------------------------------------------|
|
||||
| payload hostile trop grand | bornes à la construction des contrats RAW avant persistence |
|
||||
| raw payload leak via `Debug` | `Debug` manuel/redacted pour conteneurs sensibles |
|
||||
| secret provider/endpoint | provenance = ids/codes sûrs, jamais URL/credential |
|
||||
| source partielle | ne produit pas un modèle canonique incomplet ; autre model/event ou Transport only |
|
||||
| mismatch HTTP/WS/gRPC | matrice d'admission source -> modèle avant stabilisation de chaque famille |
|
||||
| duplicate race | write idempotent atomique, jamais `has_*` comme précondition |
|
||||
| même clé / contenu divergent | conflit explicite, pas d'overwrite silencieux |
|
||||
| partial RAW + observation | opération `persist_*_acquisition` atomique au contrat |
|
||||
| cursor hostile | taille/limit bornées ; cursor opaque non interprété par consumer |
|
||||
| query non bornée | aucune liste publique sans `PageRequest` borné |
|
||||
| backend leak | aucun type driver/row/table/SQL dans la façade |
|
||||
| event persistence creep | event-only != capability Store ; owner Interface préféré si non persistant |
|
||||
| stale `processed = true` | future preuve stage+processor/version+input hash, pas un bool comme source de vérité |
|
||||
| purge prématurée | policy externe + preuves versionnées + transition atomique |
|
||||
| re-backfill après purge | tombstone minimal durable ; réhydratation uniquement en mode forcé |
|
||||
| purge casse nouveau structural | archive/réseau forcé nécessaire si nouvelle version N2 exige le RAW |
|
||||
| closed-world backend | contrat implémentable hors `ksp-store-lib` |
|
||||
| closed-world RAW family | modèles/capabilities séparés, ajoutables sans JSON fourre-tout |
|
||||
| scope creep N2/N3/N4 | aucun type STRUCTURAL/DECODED/DOMAIN implémenté dans `0.3.1` |
|
||||
|
||||
Les menaces DSN/SQL injection/schema drift/migrations restent documentées pour `0.3.2`, où elles deviennent exécutables. Elles ne justifient pas des types SQL dans l'API.
|
||||
|
||||
@@ -940,10 +1150,16 @@ exact production module inventory
|
||||
bounds payload/provenance/cursor
|
||||
Debug/redaction tests
|
||||
idempotence outcome semantics
|
||||
transaction/log identity validation
|
||||
transaction identity validation
|
||||
source-to-model admission matrix canaries
|
||||
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
|
||||
notification reference contract si introduit
|
||||
retention state/tombstone transition invariants
|
||||
normal backfill skips purged tombstone; forced rehydrate remains explicit
|
||||
processing proof is not represented by a lone boolean
|
||||
release completeness
|
||||
cargo tree -p ksp-store-api --edges normal
|
||||
cargo tree --duplicates
|
||||
@@ -962,28 +1178,30 @@ Aucun PostgreSQL live test n'appartient à `0.3.1` puisque le backend PostgreSQL
|
||||
|
||||
## 21. Ownership
|
||||
|
||||
| Concept | Owner | Visibilité | Introduction | Raison |
|
||||
|------------------------------|----------------------------|---------------------------------|---------------------|-------------------------------------------|
|
||||
| `RawTransaction` | `ksp-store-api` | public | `0.3.1` | modèle persistant commun |
|
||||
| `RawTransactionObservation` | `ksp-store-api` | public | `0.3.1` | provenance/acquisition distincte du RAW |
|
||||
| `RawLog` | `ksp-store-api` | public | `0.3.1` | seconde famille N1 explicitement demandée |
|
||||
| `RawLogObservation` | `ksp-store-api` | public | `0.3.1` | provenance logs |
|
||||
| `RawPayload` | `ksp-store-api` | public | `0.3.1` | contrat persistant replayable versionné |
|
||||
| RAW references | `ksp-store-api` | public | `0.3.1` | reads, notification, 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 |
|
||||
| health portable | `ksp-store-api` | public | `0.3.1` | consumer commun |
|
||||
| backend extension trait | `ksp-store-api` | public | `0.3.1` | implémentation externe réelle |
|
||||
| `Store` facade | `ksp-store-lib` | public | `0.3.2` | point de consommation commun |
|
||||
| backend dispatch/settings | `ksp-store-lib` | public/privé selon contrat | `0.3.2` | features disponibles + sélection Config |
|
||||
| PostgreSQL settings internes | `ksp-store-postgres-lib` | privé ou constructor-boundary | `0.3.2` | construction du backend de référence |
|
||||
| PostgreSQL rows | `ksp-store-postgres-lib` | privé | `0.3.2` | mapping physique |
|
||||
| pool/connection | `ksp-store-postgres-lib` | privé | `0.3.2` | détail runtime |
|
||||
| SQL/statements | `ksp-store-postgres-lib` | privé | `0.3.2` | détail backend |
|
||||
| migrations/schema | `ksp-store-postgres-lib` | privé/opérateur | `0.3.2` | détail backend |
|
||||
| transport -> RAW conversion | composition/pipeline futur | privé/réutilisable selon besoin | release acquisition | `DEP-KSP-003` |
|
||||
| RAW -> D2 normalization | future pipeline générique | hors `0.3.1` | série suivante | aucune dépendance Program |
|
||||
| notification mechanism | futur host/runtime | hors API de diffusion | ultérieur | Store API possède seulement le format |
|
||||
| Concept | Owner candidat/fixé | Visibilité | Introduction | Raison |
|
||||
|--------------------------------------|-------------------------------|-----------------------------|---------------------------------------|-----------------------------------------------------|
|
||||
| `RawTransaction` | `ksp-store-api` | public | `0.3.1` | modèle persistant/replayable commun |
|
||||
| `RawTransactionObservation` | `ksp-store-api` | public | `0.3.1` | acquisition durable distincte du RAW |
|
||||
| transaction log messages RAW | dans `RawTransaction` | public via modèle RAW | `0.3.1` | font partie de la transaction avant décomposition |
|
||||
| structural transaction log lines | future couche N2 | hors `0.3.1` | série STRUCTURAL | unités extraites après décomposition |
|
||||
| `RawAccountState` | `ksp-store-api` | public si audit PASS | prévu `0.3.1`, capability progressive | état canonique commun HTTP/WS/gRPC à confirmer |
|
||||
| `RawAccountObservation` | `ksp-store-api` | public si audit PASS | prévu `0.3.1`, capability progressive | provenance/account acquisition |
|
||||
| `TransactionStatusObservation` | à confirmer `ksp-store-api` | public si persistence utile | exploration `0.3.1` | petit état durable/event potentiel |
|
||||
| log/status/slot/vote event-only | préférer `ksp-interface-lib` | public passif | future tranche Interface si retenue | échange inter-composants sans persistence Store |
|
||||
| `RawRetentionState` / tombstone | `ksp-store-api` | public logique | à stabiliser en `0.3.1` | cycle de vie RAW backend-agnostic |
|
||||
| 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 |
|
||||
| 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 |
|
||||
| backend dispatch/settings | `ksp-store-lib` | public/privé selon contrat | `0.3.2` | features disponibles + sélection Config |
|
||||
| PostgreSQL rows/pool/SQL/migrations | `ksp-store-postgres-lib` | privé/opérateur | `0.3.2` | détails physiques |
|
||||
| transport -> RAW conversion | composition/pipeline futur | privé/réutilisable | release acquisition | conversion explicite, jamais dépendance inverse |
|
||||
| RAW -> STRUCTURAL | future pipeline générique | hors `0.3.1` | série suivante | aucune dépendance Program |
|
||||
| event runtime / scheduler / analyzer | worker/analyser/runtime futur | hors Store | ultérieur | Store ne notifie pas lui-même |
|
||||
| retention policy/maintenance worker | job/worker/opérateur futur | hors Store API décisionnel | ultérieur | décide l'éligibilité ; Store applique la transition |
|
||||
|
||||
## 22. Hors scope strict `0.3.1`
|
||||
|
||||
@@ -997,49 +1215,53 @@ std.store Config
|
||||
backend MySQL/SQLite/Oracle/RocksDB/ClickHouse
|
||||
Transport acquisition runtime
|
||||
conversion Transport -> RAW fonctionnelle
|
||||
D2/CORE structs et persistence
|
||||
RAW -> D2 normalizer
|
||||
Program decode
|
||||
Materializer
|
||||
processing ledger
|
||||
N2 STRUCTURAL structs et persistence
|
||||
RAW -> STRUCTURAL processor
|
||||
N3 DECODED
|
||||
N4 DOMAIN/materialization
|
||||
processing ledger concret
|
||||
worker/job/backfill
|
||||
application Store/RAW
|
||||
notification transport concret
|
||||
retention/archive/purge lifecycle
|
||||
truncate/drop/maintenance API
|
||||
event bus/scheduler/analyser runtime
|
||||
compression algorithm concret
|
||||
archive backend concret
|
||||
retention cron/worker automatique
|
||||
truncate/drop/maintenance API générique
|
||||
```
|
||||
|
||||
Les **contrats logiques** de rétention/tombstone N1 et la compatibilité avec un futur processing ledger peuvent en revanche être définis dans `ksp-store-api` sans implémenter ces mécanismes.
|
||||
|
||||
## 23. Prévision souple recalibrée `0.3.1`
|
||||
|
||||
Chaque tranche vise environ 15–20 minutes de travail effectif.
|
||||
|
||||
### `pre.001` — Audit, modèle N1 et split API/backend
|
||||
### `pre.001` — Audit, taxonomie N1 et split API/backend
|
||||
|
||||
Base, règles, architecture, audit kbot3, audit PostgreSQL/driver futur, RAW transactions/logs, ownership, API candidate, threat model, tests et sizing.
|
||||
Base, règles, architecture, audit kbot2/kbot3, audit PostgreSQL/driver futur, frontière Interface/Store, classification persistence/event/Transport-only, rétention/tombstones, ownership, threat model, tests et sizing.
|
||||
|
||||
### `pre.002` — Scaffold `ksp-store-api`
|
||||
### `pre.002` — Scaffold `ksp-store-api` + taxonomie
|
||||
|
||||
Créer uniquement la crate API, manifest Core-only, façade crate-root et documentation initiale. Aucun modèle fonctionnel lourd.
|
||||
Créer uniquement la crate API, manifest Core-only, façade crate-root et modules de modèle/capability sans dépendance backend. Verrouiller le vocabulaire RAW/STRUCTURAL et la séparation model/capability.
|
||||
|
||||
### `pre.003` — Primitives RAW communes + transaction
|
||||
|
||||
Introduire payload/reference/provenance/idempotence/timestamps bornés puis `RawTransaction` et son observation.
|
||||
Introduire payload/reference/provenance/idempotence/timestamps bornés puis `RawTransaction` et son observation. Les logs inclus restent dans la transaction.
|
||||
|
||||
### `pre.004` — RAW logs + extensibilité N1
|
||||
### `pre.004` — Matrice cross-source + familles N1 prévues
|
||||
|
||||
Introduire `RawLog`/observation, vérifier ordering/identity/bounds et verrouiller l'absence de type RAW fourre-tout.
|
||||
Auditer HTTP/WS/gRPC pour `RawAccountState`/observation et `TransactionStatusObservation`; introduire les modèles communs seulement lorsque la sémantique converge. Classer explicitement logsSubscribe/slot/vote/block/Entry en event, IDEA ou rejet.
|
||||
|
||||
### `pre.005` — Capabilities backend extensibles
|
||||
|
||||
Implémenter les contrats object-safe et l'external backend canary, sans façade runtime `Store` et sans runtime DB. La façade commune appartient à `ksp-store-lib` en `0.3.2`.
|
||||
Implémenter les contracts read/write object-safe et l'external backend canary, sans façade runtime `Store` et sans runtime DB. Un modèle prévu n'oblige pas chaque backend à implémenter sa capability.
|
||||
|
||||
### `pre.006` — Queries, pagination, outcomes et notification reference
|
||||
### `pre.006` — Queries, outcomes et lifecycle RAW
|
||||
|
||||
Finaliser reads/list/backlog bornés, atomic acquisition contract et référence de notification si suffisamment stable.
|
||||
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.
|
||||
|
||||
### `pre.007` — Adversarial/API hardening + completeness
|
||||
### `pre.007` — Boundary/adversarial hardening + completeness
|
||||
|
||||
Payload/cursor/provenance hostile, Debug, external backend, exact exports/modules, dependency firewall et scope négatif D2/D3/D4.
|
||||
Payload/cursor/provenance hostile, Interface/Store ownership canaries, admission matrix, retention races, exact exports/modules, external backend, dependency firewall et scope négatif N2/N3/N4.
|
||||
|
||||
### `pre.008` — Gate technique final
|
||||
|
||||
@@ -1067,22 +1289,24 @@ Le prompt `0.3.2` ouvre ensemble `ksp-store-lib` et `ksp-store-postgres-lib`, av
|
||||
|
||||
Mécanique de publication uniquement.
|
||||
|
||||
La release reste estimée clôturable dans une session si les tranches conservent cette granularité et si aucun codec/normalizer D2 n'est tiré dans le scope.
|
||||
La release reste estimée clôturable dans une session si les tranches conservent cette granularité et si aucun processor STRUCTURAL/decoder n'est tiré dans le scope.
|
||||
|
||||
## 24. Trajectoire `0.3.x` résultante
|
||||
|
||||
La prévision durable devient, sous réserve des gates de chaque release :
|
||||
|
||||
```text
|
||||
0.3.1 ksp-store-api / N1 RAW contract
|
||||
0.3.1 ksp-store-api / N1 RAW + observations + lifecycle logique
|
||||
0.3.2 ksp-store-lib + ksp-store-postgres-lib / PostgreSQL reference via tokio-postgres
|
||||
0.3.3 generic Interface/wire additions nécessaires à acquisition/normalisation
|
||||
0.3.3 ksp-interface-lib additions nécessaires aux événements/acquisitions partagés
|
||||
0.3.4 ksp-job-api + premier backfill RAW concret
|
||||
0.3.5 application backfill/inspection RAW
|
||||
ensuite worker/service live RAW avant ouverture D2
|
||||
ensuite worker/service live RAW avant ouverture N2 STRUCTURAL
|
||||
```
|
||||
|
||||
Cette renumérotation remplace la prévision `0.3.1..0.3.4` de la base `v0.2.14`; `pre.001-fix.001` l'écrit immédiatement dans le `ROADMAP.md` pour éviter de poursuivre avec une trajectoire fausse.
|
||||
Les événements realtime non persistés et les modèles Interface peuvent être avancés ou retardés selon le premier consumer réel ; ils ne doivent pas être artificiellement absorbés par Store.
|
||||
|
||||
La renumérotation `0.3.1..0.3.5` issue de `pre.001-fix.001` reste valide.
|
||||
|
||||
## 25. Critères de fermeture de `0.3.1`
|
||||
|
||||
@@ -1090,10 +1314,16 @@ La stable `0.3.1` est prête seulement si :
|
||||
|
||||
```text
|
||||
ksp-store-api existe seule dans le domaine Store
|
||||
modèle objet RAW commun stable
|
||||
RawTransaction + observations stables
|
||||
RawLog + observations stables
|
||||
future extension N1 non bloquée
|
||||
aucune source partielle ne fabrique un RawTransaction incomplet
|
||||
logs transactionnels restent dans RawTransaction jusqu'à N2 STRUCTURAL
|
||||
RawAccountState/observation audités et modèle prévu si compatibilité cross-source prouvée
|
||||
TransactionStatusObservation classé explicitement
|
||||
logsSubscribe/slot/vote classés event-only/Interface, reportés ou rejetés explicitement
|
||||
RawBlock reste IDEA sans persistence tant qu'un besoin block-level n'est pas démontré
|
||||
Yellowstone Entry reste explicitement hors taxonomie active
|
||||
frontière ksp-interface-lib / ksp-store-api documentée et sans modèles concurrents
|
||||
models et capabilities séparés
|
||||
contrats backend communs stables
|
||||
backend externe implémentable sans ksp-store-lib
|
||||
aucun type backend/SQL public
|
||||
@@ -1101,9 +1331,12 @@ queries/pagination bornées
|
||||
idempotence/conflict semantics explicites
|
||||
atomic acquisition contract explicite
|
||||
références durables stables
|
||||
notification format introduit ou reporté explicitement
|
||||
RawRetentionState/tombstone empêchent le rebackfill normal après purge
|
||||
force rehydrate reste explicitement distinct
|
||||
aucun simple processed bool n'est présenté comme preuve suffisante de traitement
|
||||
future preuve processing versionnée stage/processor/input reste possible
|
||||
aucune dépendance PostgreSQL
|
||||
aucune surface D2/D3/D4
|
||||
aucune surface N2 STRUCTURAL/N3 DECODED/N4 DOMAIN implémentée
|
||||
workspace et graphes entièrement verts
|
||||
prompt `0.3.2` cohérent avec ksp-store-lib + ksp-store-postgres-lib + tokio-postgres
|
||||
prompt 0.3.2 cohérent avec ksp-store-lib + ksp-store-postgres-lib + tokio-postgres
|
||||
```
|
||||
|
||||
@@ -1,83 +1,82 @@
|
||||
<!-- file: docs/validation/018-V0_3_1_STORE_RAW.md -->
|
||||
<!-- version: 2 -->
|
||||
<!-- version: 3 -->
|
||||
|
||||
# Validation `0.3.1` — Store API RAW foundation
|
||||
|
||||
## 1. Objet
|
||||
|
||||
Cette matrice est ouverte par `0.3.1-pre.001` et corrigée par `pre.001-fix.001`. Elle valide **`ksp-store-api` uniquement**. La façade/runtime commune `ksp-store-lib` et l'implémentation PostgreSQL séparée `ksp-store-postgres-lib` sont réunies dans `0.3.2`.
|
||||
Cette matrice est ouverte par `0.3.1-pre.001`, corrigée par `pre.001-fix.001` puis recalibrée par `pre.001-fix.002`. Elle valide **`ksp-store-api` uniquement**. La façade/runtime commune `ksp-store-lib` et l'implémentation PostgreSQL séparée `ksp-store-postgres-lib` sont réunies dans `0.3.2`.
|
||||
|
||||
Le scope concret N1 initial est :
|
||||
Le scope concret N1 certain est :
|
||||
|
||||
```text
|
||||
RawTransaction + observation
|
||||
RawLog + observation
|
||||
provenance/références/outcomes/queries communs
|
||||
contrats/capabilities backend externes
|
||||
cycle de rétention logique + tombstone
|
||||
```
|
||||
|
||||
Les autres familles RAW restent extensibles et reportées jusqu'à audit réel de leur besoin.
|
||||
`RawAccountState`/observation et `TransactionStatusObservation` doivent être audités cross-source et prévus dans l'API lorsque leur sémantique commune est prouvée. Les notifications de logs/slot/vote sont classées séparément comme candidats event-only, avec ownership Interface préféré lorsqu'elles ne sont pas persistées.
|
||||
|
||||
## 2. Gate `pre.001`
|
||||
|
||||
| Critère | Statut | Preuve |
|
||||
|----------------------------|---------|-------------------------------------------------------------------------------|
|
||||
| base stable `0.2.14` | PASS | Cargo `0.2.14`, `rel.001` et prompt 020 présents |
|
||||
| metadata Git/tag | N/A | archive opérateur sans metadata Git exploitable |
|
||||
| baseline opérateur | PASS | audits, check, Clippy et workspace tests fournis verts sur `v0.2.14` |
|
||||
| `ksp-program-api` stable | PASS | façade instruction-only relue |
|
||||
| `ksp-store-api` absent | PASS | aucun répertoire Store API sur la base |
|
||||
| `ksp-store-lib` absent | PASS | aucun répertoire Store lib sur la base |
|
||||
| archive kbot3 disponible | PASS | archive historique extraite et auditée |
|
||||
| règles Store/API relues | PASS | règles KSP/Dependencies/Workflow prescrites relues |
|
||||
| architecture durable relue | PASS | graph/store/acquisition relus, D1/D2 séparés |
|
||||
| matrice héritage kbot3 | PASS | `REPRENDRE / REDESSINER / REPORTER / REJETER` dans le plan 022 |
|
||||
| audit externe PostgreSQL | PASS | PostgreSQL 18.6 courant au 28 août 2026 |
|
||||
| audit driver futur | PASS | `tokio-postgres 0.7.18`, Rust 2024/MSRV 1.85, async/transactions/COPY audités |
|
||||
| split version | PASS | `0.3.1 = Store API`, `0.3.2 = Store lib PostgreSQL` |
|
||||
| dependency graph `0.3.1` | PASS | cible Core-only |
|
||||
| modèle backend commun | PASS | API object/struct commune, rows backend privées |
|
||||
| inventaire RAW initial | PASS | transaction + logs + observations |
|
||||
| autres RAW | REPORTÉ | account/block/slot ajoutés seulement sur besoin audité |
|
||||
| provenance | PASS | provider/protocol/origin/timing sûrs, aucun secret |
|
||||
| idempotence | PASS | atomic put, `Inserted/AlreadyPresent`, divergence = conflict |
|
||||
| API candidate | PASS | capabilities object-safe + external backend; façade runtime reportée à 0.3.2 |
|
||||
| public SQL transaction | ABSENT | invariants atomiques exprimés par opérations métier |
|
||||
| pagination | PASS | 100 par défaut / 500 max / cursor opaque borné |
|
||||
| notification ownership | PASS | référence RAW KSP-owned, mécanisme hors scope |
|
||||
| D2/CORE persistence | ABSENT | explicitement hors `0.3.1` |
|
||||
| DECODE/SPECIALIZED | ABSENT | explicitement hors `0.3.1` |
|
||||
| schema PostgreSQL candidat | REPORTÉ | déplacé intégralement à `0.3.2` par split API/backend |
|
||||
| migration policy | REPORTÉ | responsabilité `ksp-store-postgres-lib` `0.3.2` |
|
||||
| PostgreSQL live gate | REPORTÉ | aucun backend DB dans `0.3.1`; gate obligatoire à définir en `0.3.2` |
|
||||
| threat model | PASS | modèle hostile/API/backend couvert dans plan 022 |
|
||||
| stratégie de tests | PASS | unit/public/external/firewall/completeness, aucun PostgreSQL live |
|
||||
| sizing | PASS | dix prereleases courtes + lanes fermeture séparées |
|
||||
| Critère | Statut | Preuve / décision |
|
||||
|----------------------------------|---------|-----------------------------------------------------------------------------------|
|
||||
| base stable `0.2.14` | PASS | Cargo `0.2.14`, `rel.001` et prompt 020 présents |
|
||||
| baseline opérateur | PASS | audits/check/Clippy fournis verts ; validation tests déclarée OK |
|
||||
| archive kbot3 + kbot2 historique | PASS | kbot3 extraite ; `olddocs/archivekbot2` audité pour lifecycle/replay |
|
||||
| règles Store/API relues | PASS | règles KSP/Dependencies/Workflow prescrites relues |
|
||||
| split version | PASS | `0.3.1 = Store API`, `0.3.2 = Store lib + PostgreSQL lib` |
|
||||
| dependency graph `0.3.1` | PASS | cible Core-only |
|
||||
| modèle backend commun | PASS | API object/struct commune, rows backend privées |
|
||||
| admission multi-source | PASS | même modèle seulement si HTTP/WS/gRPC satisfont intégralement la même sémantique |
|
||||
| `RawTransaction` | PASS | premier modèle persistant certain |
|
||||
| logs dans transaction | PASS | restent dans `RawTransaction`, extraction seulement en N2 STRUCTURAL |
|
||||
| logsSubscribe | REPORTÉ | event-only candidat ; pas de `RawLog` Store persistant par défaut |
|
||||
| account state | PRÉVU | modèle/observation à figer après matrice de compatibilité |
|
||||
| transaction status | PRÉVU | observation/event à figer si sémantique commune prouvée |
|
||||
| slot/vote | TODO | event-only candidats ; ownership Interface à auditer |
|
||||
| RawBlock | IDEA | non persisté par défaut ; `getBlock` sert de conteneur d'acquisition |
|
||||
| Yellowstone Entry | REJETÉ | aucun replay/decomposition/event métier justifiant un modèle Store |
|
||||
| frontière Interface/Store | PASS | persistent/replay -> Store API ; event-only partagé -> Interface préférentiel |
|
||||
| N2 nomenclature | PASS | `CORE` remplacé par nom de travail `STRUCTURAL` |
|
||||
| pipeline non linéaire | PASS | toutes les familles N1 ne sont pas forcées N1->N2->N3->N4 |
|
||||
| processing proof | PASS | futur ledger stage+processor/version+input hash ; `processed: bool` insuffisant |
|
||||
| retention lifecycle | PASS | `Full/Compacted/Archived/Purged` redessiné backend-agnostic |
|
||||
| tombstone anti-rebackfill | PASS | identité/hash/slot minimal conservé après purge ; backfill forcé distinct |
|
||||
| notification ownership runtime | PASS | Store ne possède aucun event bus/scheduler/DB notify |
|
||||
| schema/migrations PostgreSQL | REPORTÉ | responsabilité `ksp-store-postgres-lib` `0.3.2` |
|
||||
| D2/N3/N4 persistence | ABSENT | hors `0.3.1` |
|
||||
| threat model | PASS | source mismatch, purge prématurée, stale processing, backend/event leaks couverts |
|
||||
| sizing | PASS | dix prereleases courtes + lanes fermeture séparées |
|
||||
|
||||
## 3. Décisions structurelles à prouver par le code
|
||||
|
||||
| Contrat | Décision `pre.001` | Gate futur |
|
||||
|-----------------------------|-------------------------------------------------------------------|-------------------------------|
|
||||
| crate `ksp-store-api` | seule crate Store créée en `0.3.1` | `pre.002` |
|
||||
| dépendance normale | `ksp-core-lib` uniquement par défaut | `pre.002` |
|
||||
| backend PostgreSQL | absent de `0.3.1` | completeness `pre.007` |
|
||||
| `RawPayload` | KSP-owned, source-independent, versionné, borné, Debug sans bytes | `pre.003` |
|
||||
| transaction identity | réseau + signature logique, jamais PK SQL | `pre.003` |
|
||||
| `RawTransaction` | objet persistant commun replayable | `pre.003` |
|
||||
| `RawTransactionObservation` | acquisition/provenance séparée du RAW | `pre.003` |
|
||||
| `RawLog` | famille N1 distincte avec ordering préservé | `pre.004` |
|
||||
| `RawLogObservation` | provenance séparée du log canonique | `pre.004` |
|
||||
| future RAW families | extensibles sans JSON universel | `pre.004` / `pre.007` |
|
||||
| `StoreFuture<'a, T>` | future object-safe KSP-owned, sans `async-trait` par défaut | `pre.005` |
|
||||
| backend trait | implémentable hors workspace, `Send + Sync` | `pre.005` |
|
||||
| façade runtime `Store` | reportée à `ksp-store-lib`, hors `0.3.1` | `0.3.2` |
|
||||
| transaction handle | aucun handle SQL/backend public | `pre.005` |
|
||||
| atomic acquisition | méthode métier RAW + observation all-or-nothing | `pre.005` / `pre.006` |
|
||||
| write outcome | `Inserted / AlreadyPresent`; divergence = `Err Conflict` | `pre.006` |
|
||||
| `PageRequest` | borné, default 100, max 500 | `pre.006` |
|
||||
| cursor | opaque, borné, aucun SQL/backend contract visible | `pre.006` |
|
||||
| notification reference | compacte, durable, payload non dupliqué | `pre.006` ou report explicite |
|
||||
| health | portable et sanitisé | `pre.005` / `pre.006` |
|
||||
| Contrat | Décision `pre.001-fix.002` | Gate futur |
|
||||
|--------------------------------|-------------------------------------------------------------------|------------------------------|
|
||||
| crate `ksp-store-api` | seule crate Store créée en `0.3.1` | `pre.002` |
|
||||
| dépendance normale | `ksp-core-lib` uniquement par défaut | `pre.002` |
|
||||
| `RawPayload` | KSP-owned, source-independent, versionné, borné, Debug sans bytes | `pre.003` |
|
||||
| `RawTransaction` | objet persistant commun uniquement depuis une source complète | `pre.003` |
|
||||
| `RawTransactionObservation` | acquisition/provenance séparée du RAW | `pre.003` |
|
||||
| transaction `logMessages` | partie du RAW transactionnel | `pre.003` |
|
||||
| logs structuraux | extraction N2 STRUCTURAL future, jamais `RawLog` N1 distinct | canari négatif `pre.003/007` |
|
||||
| `RawAccountState`/observation | modèle prévu si HTTP/WS/gRPC convergent sans perte | `pre.004` |
|
||||
| `TransactionStatusObservation` | modèle prévu si surfaces status convergent | `pre.004` |
|
||||
| logs/slot/vote event-only | ne créent aucune capability Store par défaut | `pre.004/007` |
|
||||
| Interface vs Store | event-only partagé -> Interface ; persistent/replay -> Store API | `pre.004/007` |
|
||||
| model vs capability | un modèle API n'oblige pas tous les backends à le persister | `pre.005` |
|
||||
| capabilities | read/write fines et object-safe | `pre.005` |
|
||||
| transaction handle | aucun handle SQL/backend public | `pre.005` |
|
||||
| atomic acquisition | méthode métier RAW + observation all-or-nothing | `pre.005/006` |
|
||||
| write outcome | `Inserted / AlreadyPresent`; divergence = `Err Conflict` | `pre.006` |
|
||||
| page/cursor | default 100, max 500, cursor opaque borné | `pre.006` |
|
||||
| `RawRetentionState` | logique `Full/Compacted/Archived/Purged`, sans détail physique | `pre.006` |
|
||||
| tombstone | identité/hash/slot minimal durable après purge | `pre.006` |
|
||||
| backfill normal après purge | skip distinct | `pre.006` |
|
||||
| force rehydrate | chemin explicite distinct, jamais fallback automatique | `pre.006` |
|
||||
| processing evidence | futur ledger version-aware, jamais un bool unique | boundary `pre.006/007` |
|
||||
| façade runtime `Store` | reportée à `ksp-store-lib`, hors `0.3.1` | `0.3.2` |
|
||||
|
||||
## 4. Dependency firewall final attendu
|
||||
|
||||
@@ -115,22 +114,25 @@ Toute divergence exige un usage public réel et une révision du plan.
|
||||
|
||||
## 5. Matrice N1 initiale
|
||||
|
||||
| Famille | `0.3.1` | Identité logique candidate | Replay couvert | Provenance |
|
||||
|-------------|---------|-----------------------------------------------------------|---------------------------------------------------------------------------|-------------------------------|
|
||||
| transaction | IN | network + signature | future décomposition générique Solana complète couverte par le format RAW | observations séparées |
|
||||
| logs | IN | identité transaction/slot + clé déterministe à stabiliser | ordre et contenu log nécessaires à replay/inspection | observations séparées |
|
||||
| account | REPORTÉ | pubkey + context/slot/version à auditer | futur compte RAW replayable | prévu par primitives communes |
|
||||
| block | REPORTÉ | network + slot/block identity | futur backfill/block replay | prévu par primitives communes |
|
||||
| slot/update | REPORTÉ | sémantique exacte à auditer | seulement si un fait durable distinct est utile | prévu par primitives communes |
|
||||
| Famille / fait | Classification actuelle | Persistence Store | N2 attendu | Action `0.3.1` |
|
||||
|--------------------------------|--------------------------|-------------------|----------------|--------------------------------------------------------------------|
|
||||
| transaction complète | N1 RAW | oui | STRUCTURAL oui | implémenter modèle + observation |
|
||||
| logs contenus dans transaction | partie de RawTransaction | via transaction | STRUCTURAL oui | préserver lossless, ne pas dupliquer en `RawLog` |
|
||||
| account state complet | N1 RAW candidat | futur oui | à déterminer | audit HTTP/WS/gRPC puis prévoir modèle/observation |
|
||||
| transaction status | observation candidat | optionnelle | non | audit signature/status sources |
|
||||
| `logsSubscribe` notification | event-only candidat | non par défaut | non | ownership Interface/worker à figer |
|
||||
| slot/root/slotsUpdates | event-only candidat | non | non | TODO use-case + compatibilité |
|
||||
| vote | event-only candidat | non | non | TODO seulement si forme commune utile |
|
||||
| block complet | acquisition container | non par défaut | — | IDEA uniquement ; extraire transactions plutôt que stocker le bloc |
|
||||
| Yellowstone Entry | transport-only | non | — | explicitement non retenu |
|
||||
|
||||
## 6. Frontière N1 -> D2
|
||||
## 6. Frontière N1 -> N2 STRUCTURAL
|
||||
|
||||
`0.3.1` doit préserver sans implémenter :
|
||||
|
||||
```text
|
||||
RawTransaction
|
||||
-> generic Solana normalization
|
||||
-> transaction/message
|
||||
-> StructuralTransaction/message
|
||||
-> account keys
|
||||
-> top-level instructions
|
||||
-> CPI/inner instructions
|
||||
@@ -138,13 +140,17 @@ RawTransaction
|
||||
-> traitement individuel ultérieur
|
||||
```
|
||||
|
||||
Canari négatif durable :
|
||||
N2 est nommé **STRUCTURAL** parce qu'il décrit une décomposition générique Solana, pas un domaine métier « Core ».
|
||||
|
||||
Canaris :
|
||||
|
||||
```text
|
||||
ksp-store-api -X-> ksp-program-api
|
||||
RawTransaction logMessages -X-> entité RawLog persistante séparée
|
||||
une erreur/absence future de decoder -X-> blocage des autres instructions
|
||||
```
|
||||
|
||||
Le terme `CORE` reste le nom architectural actuel de D2 mais peut être renommé avant ouverture de cette couche sans modifier la séparation fonctionnelle.
|
||||
Toutes les familles N1 ne sont pas obligées de posséder un N2. `RawAccountState` peut par exemple aller directement vers une future étape de decode si aucune décomposition structurelle utile n'est identifiée.
|
||||
|
||||
## 7. Extensibilité backend
|
||||
|
||||
@@ -163,24 +169,26 @@ crate/test backend externe
|
||||
|
||||
## 8. Threat/API gates futurs
|
||||
|
||||
| Gate | Attendu | Statut initial |
|
||||
|---------------------------------|-----------------------------------------------------|-----------------------|
|
||||
| oversized RAW payload | rejet avant stockage/copied allocation pathologique | `pre.003` |
|
||||
| payload Debug | aucun bytes brut | `pre.003` |
|
||||
| hostile provenance text | borné/trim/control policy explicite | `pre.003` |
|
||||
| duplicate same content | outcome `AlreadyPresent` | `pre.006` |
|
||||
| duplicate divergent content | erreur Conflict stable | `pre.006` |
|
||||
| check-then-insert | absent de l'API publique | `pre.005` |
|
||||
| partial transaction+observation | interdit par atomic acquisition contract | `pre.005` |
|
||||
| page limit 0/>500 | rejet | `pre.006` |
|
||||
| cursor oversize | rejet | `pre.006` |
|
||||
| SQL/backend cursor leak | absent | `pre.006` / `pre.007` |
|
||||
| provider secret leak | absent du modèle public | `pre.003` / `pre.007` |
|
||||
| backend row/public type | absent | `pre.007` |
|
||||
| async runtime dependency | aucune dependency Tokio dans API par défaut | `pre.005` / `pre.007` |
|
||||
| external backend | implémente API sans dépendre de Store lib | `pre.005` |
|
||||
| closed RAW enum | future family ajoutable | `pre.004` / `pre.007` |
|
||||
| D2/D3/D4 creep | aucune surface | `pre.007` |
|
||||
| Gate | Attendu | Statut initial |
|
||||
|----------------------------------|-------------------------------------------------|----------------|
|
||||
| oversized RAW payload | rejet avant allocation pathologique | `pre.003` |
|
||||
| payload Debug | aucun bytes brut | `pre.003` |
|
||||
| partial source -> RawTransaction | interdit ; contrat complet exigé | `pre.003/004` |
|
||||
| HTTP/WS/gRPC semantic mismatch | détecté par admission matrix | `pre.004` |
|
||||
| duplicate same content | `AlreadyPresent` | `pre.006` |
|
||||
| duplicate divergent content | Conflict stable | `pre.006` |
|
||||
| partial transaction+observation | interdit par atomic acquisition | `pre.005` |
|
||||
| event-only -> Store capability | absent par défaut | `pre.004/007` |
|
||||
| Interface/Store duplicate model | absent | `pre.007` |
|
||||
| page limit 0/>500 | rejet | `pre.006` |
|
||||
| SQL/backend cursor leak | absent | `pre.006/007` |
|
||||
| external backend | implémente API sans Store lib | `pre.005` |
|
||||
| processing `bool` comme vérité | absent ; future preuve version-aware documentée | `pre.006/007` |
|
||||
| purge sans policy/evidence | impossible par contrat | `pre.006/007` |
|
||||
| tombstone supprimé avec payload | interdit | `pre.006` |
|
||||
| rebackfill normal après purge | skip | `pre.006` |
|
||||
| force rehydrate implicite | interdit | `pre.006` |
|
||||
| N2/N3/N4 creep | aucune surface | `pre.007` |
|
||||
|
||||
## 9. Gates de fermeture prévus
|
||||
|
||||
@@ -227,7 +235,7 @@ prompts/021-V0_3_2_START_PROMPT.md
|
||||
delta pre.010
|
||||
```
|
||||
|
||||
Le `ROADMAP.md` est déjà réconcilié par `pre.001-fix.001`; `pre.010` ne doit plus avoir à réparer ce split, seulement refléter l'état final et préparer le prompt `0.3.2`.
|
||||
Le `ROADMAP.md` est réconcilié par `pre.001-fix.001` puis `pre.001-fix.002`; `pre.010` ne doit plus avoir à réparer la taxonomie N1/N2 ni le split backend.
|
||||
|
||||
## 10. PostgreSQL reporté à `0.3.2`
|
||||
|
||||
@@ -267,16 +275,16 @@ sécurité
|
||||
|
||||
## 11. État initial des tranches
|
||||
|
||||
| Tranche | Objet | État |
|
||||
|-----------|--------------------------------|-----------------------|
|
||||
| `pre.001` | audit/design/split API/backend | PRÊT après gate local |
|
||||
| `pre.002` | scaffold Store API | À FAIRE |
|
||||
| `pre.003` | primitives + RawTransaction | À FAIRE |
|
||||
| `pre.004` | RawLog + extensibilité N1 | À FAIRE |
|
||||
| `pre.005` | backend contracts/capabilities | À FAIRE |
|
||||
| `pre.006` | queries/outcomes/notification | À FAIRE |
|
||||
| `pre.007` | adversarial/completeness | À FAIRE |
|
||||
| `pre.008` | gate technique final | À FAIRE |
|
||||
| `pre.009` | réconciliation documentaire | À FAIRE |
|
||||
| `pre.010` | préparation publication | À FAIRE |
|
||||
| `rel.001` | stable | À FAIRE |
|
||||
| Tranche | Objet | État |
|
||||
|-----------|------------------------------------------|-----------------------|
|
||||
| `pre.001` | audit/design/taxonomie/split | PRÊT après gate local |
|
||||
| `pre.002` | scaffold + taxonomie Store API | À FAIRE |
|
||||
| `pre.003` | primitives + RawTransaction | À FAIRE |
|
||||
| `pre.004` | admission matrix + account/status models | À FAIRE |
|
||||
| `pre.005` | backend contracts/capabilities | À FAIRE |
|
||||
| `pre.006` | queries/outcomes/retention/tombstone | À FAIRE |
|
||||
| `pre.007` | boundary/adversarial/completeness | À FAIRE |
|
||||
| `pre.008` | gate technique final | À FAIRE |
|
||||
| `pre.009` | réconciliation documentaire | À FAIRE |
|
||||
| `pre.010` | préparation publication | À FAIRE |
|
||||
| `rel.001` | stable | À FAIRE |
|
||||
|
||||
Reference in New Issue
Block a user