v0.3.1-pre.009

This commit is contained in:
2026-08-29 11:22:29 +02:00
parent 55325ffd32
commit 2f0eb316f5
13 changed files with 412 additions and 244 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/000-README.md -->
<!-- version: 31 -->
<!-- version: 32 -->
# Validations KSP
@@ -24,5 +24,6 @@ Documents :
- [`013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md`](013-V0_2_10_ORBITFLARE_YELLOWSTONE_GRPC.md) — matrice finale de la release stable `0.2.10` : Free Devnet, auth `x-token`, endpoint security, heartbeat standard, Config V3, smoke live `Slot + Ping` et invariant N1/N2 immuable.
- [`014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md`](014-V0_2_11_OFFCHAIN_PRICE_TRANSPORT.md) — matrice historique clôturée de `0.2.11` : SOL/USD multi-provider, numeric safety, rate limiting/availability, Config capability-aware et smoke keyless final `7/7`.
- [`015-V0_2_12_SOL_PRICES_DESK.md`](015-V0_2_12_SOL_PRICES_DESK.md) — matrice historique clôturée de `0.2.12` : screen/features, DTO/commands, Config/composite, frontières provider-neutral, sécurité, Wallet integration, packaging Tauri et gates live/build.
- [`016-V0_2_13_INTERFACE.md`](016-V0_2_13_INTERFACE.md) — matrice candidate finale de `0.2.13` : ownership Interface/Core/Transport/Program, surface passive, bornes/adversarial, façade publique exacte, consumer externe, release completeness, dependency firewall et gate technique `pre.006` intégralement vert.
- [`017-V0_2_14_PROGRAM_API.md`](017-V0_2_14_PROGRAM_API.md) — matrice candidate finale de `0.2.14 — Program API foundation` : façade instruction-only ouverte, Recognition/Outcome, trait externe, Program Pubkey non enregistré, hardening adversarial, release completeness, firewall Core/Interface et gate technique `pre.006` intégralement vert.
- [`016-V0_2_13_INTERFACE.md`](016-V0_2_13_INTERFACE.md) — matrice historique clôturée de la release stable `0.2.13` : ownership Interface/Core/Transport/Program, surface passive, bornes/adversarial, façade publique exacte, consumer externe, release completeness et dependency firewall.
- [`017-V0_2_14_PROGRAM_API.md`](017-V0_2_14_PROGRAM_API.md) — matrice historique clôturée de la release stable `0.2.14 — Program API foundation` : façade instruction-only ouverte, Recognition/Outcome, trait externe, Program Pubkey non enregistré, hardening adversarial, release completeness et firewall Core/Interface.
- [`018-V0_3_1_STORE_RAW.md`](018-V0_3_1_STORE_RAW.md) — matrice candidate finale de `0.3.1 — Store API RAW foundation` : modèles transaction/account, observations, capabilities backend, pagination sans policy executor, outcomes, rétention/tombstone, hardening, gate complet `pre.008` et reports explicites vers `0.3.2+`.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/018-V0_3_1_STORE_RAW.md -->
<!-- version: 8 -->
<!-- version: 9 -->
# Validation `0.3.1` — Store API RAW foundation
@@ -11,6 +11,7 @@ Le scope concret N1 certain est :
```text
RawTransaction + observation
RawAccountState + observation
provenance/références/outcomes/queries communs
contrats/capabilities backend externes
cycle de rétention logique + tombstone
@@ -33,8 +34,8 @@ cycle de rétention logique + tombstone
| `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 |
| account state | PASS | `pre.004` matérialise modèle/observation sous bytes complets + slot |
| transaction status | REPORTÉ | HTTP snapshot, WS transition et Yellowstone update restent distincts |
| 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 |
@@ -52,31 +53,31 @@ cycle de rétention logique + tombstone
## 3. Décisions structurelles à prouver par le code
| 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 | limit caller > 0 ; sans max KSP ; cursor opaque <= 4 KiB | `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` |
| 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 admis si HTTP/WS/gRPC convergent sans perte, matérialisé en `pre.004` | `pre.004` |
| `TransactionStatusObservation` | non matérialisé : surfaces status non équivalentes | report explicite `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 | limit caller > 0 ; sans max KSP ; cursor opaque <= 4 KiB | `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
@@ -307,93 +308,6 @@ Le canari `tests/external_backend.rs` définit un backend mémoire externe qui i
Aucune implémentation de persistence n'est fournie par `ksp-store-api`; les futures concrètes du canari ne servent qu'à vérifier le contrat d'extension.
## 9. Gates de fermeture prévus
### Gate technique final `pre.008`
`0.3.1-pre.008` n'ajoute aucun développement fonctionnel. Le gate opérateur de `pre.007-fix.001` fourni le 29 août 2026 est vert pour fmt, audits Rust/Markdown, workspace check/Clippy et `cargo test -p ksp-store-api` : 15 tests unitaires, 2 dependency-boundary, 1 external-backend, 7 public-api, 5 release-completeness, 4 security-hardening et doc-tests propres.
La tranche `pre.008` doit maintenant fermer le gate technique complet, y compris workspace, ownership Logging et graphes Cargo.
Commandes de référence :
```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
cargo test -p ksp-store-api
cargo test -p ksp-logging-lib --test ownership
cargo test --workspace
cargo tree -p ksp-store-api --edges normal
cargo tree --duplicates
```
### Réconciliation documentaire `pre.009`
Doit fermer :
```text
crates/ksp-store-api/README.md
crates/ksp-store-api/USAGE.md
plan 022
validation 018
indexes/références durables concernées
```
Sans `CHANGELOG.md`, `ROADMAP.md` ni prompt suivant.
### Préparation de publication `pre.010`
Doit rester limitée à :
```text
Cargo.toml
CHANGELOG.md
ROADMAP.md
prompts/021-V0_3_2_START_PROMPT.md
delta pre.010
```
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`
Aucun gate PostgreSQL live n'est demandé à `0.3.1`.
Le prochain prompt devra transformer les invariants API en façade commune + backend de référence et prévoir :
```text
ksp-store-lib
-> façade Store commune
-> réexports utiles de ksp-store-api
-> feature postgres par défaut
-> dispatch backend selon Config
-> erreur backend connu mais non compilé
ksp-store-postgres-lib
-> tokio-postgres
-> pool/TLS audités
-> migrations KSP-owned
-> schema conformance
-> write/read round-trip des modèles API
-> idempotence/race
-> atomic rollback
-> pagination
Config
-> std.store
-> URI/DSN backend lorsque naturel
-> secrets ${KSP_SECRET_*} / .env owned par ksp-config-lib
-> aucun vrai secret versionné
sécurité
-> URI/DSN/credentials redacted
-> aucune lecture directe env/.env par Store ou backend
-> PostgreSQL réel opt-in puis gate final obligatoire
```
### 8.4 Matérialisation `pre.006`
La tranche ajoute les contrats logiques suivants sans backend/runtime :
@@ -458,18 +372,131 @@ aucune fuite PostgreSQL/MySQL/backend runtime
La course de rétention est un état normal de concurrence : si l'état durable ne correspond plus à `expected` et n'est pas déjà `target`, le backend doit retourner `ExpectedStateMismatch`. Cette sémantique évite d'utiliser une erreur de validation pour une course et impose une compare-and-transition atomique à l'implémentation future.
## 11. État initial des tranches
### 8.6 Gate technique `pre.008`
| Tranche | Objet | État |
|-----------|------------------------------------------|-----------------------|
| `pre.001` | audit/design/taxonomie/split | PRÊT après gate local |
| `pre.002` | scaffold + taxonomie Store API | PRÊT après gate local |
| `pre.003` | primitives + RawTransaction | PRÊT après gate local |
| `pre.004` | admission matrix + account/status models | PRÊT après gate local |
| `pre.005` | backend contracts/capabilities | PRÊT après gate local |
| `pre.006` | queries/outcomes/retention/tombstone | PRÊT après gate local |
| `pre.007` | boundary/adversarial/completeness | PRÊT après gate local |
| `pre.008` | gate technique final | PRÊT pour gate local |
| `pre.009` | réconciliation documentaire | À FAIRE |
| `pre.010` | préparation publication | À FAIRE |
| `rel.001` | stable | À FAIRE |
Le gate opérateur final a été exécuté après `cargo clean`, donc sans dépendre du cache incrémental précédent.
Résultat :
```text
audits Rust/Markdown PASS
cargo check --workspace PASS
cargo clippy --workspace --all-targets PASS
tests ciblés Core/Logging/Config/Transport/Off-chain/Wallet/Interface/Store/Desks PASS
cargo test --workspace PASS
cargo tauri build SOL Prices Desk PASS
cargo tauri build Wallet Desk PASS
cargo tauri build Config Desk PASS
cargo tree -p ksp-store-api --edges normal inspecté
cargo tree --duplicates inspecté
```
Le seul incident de commande était le nom inexistant `ksp-program-lib`; il ne correspond à aucune crate publiée. Le test ciblé correct `cargo test -p ksp-program-api` a ensuite été exécuté séparément et passe : 3 unit, 2 dependency-boundary, 2 external-implementation, 4 public-api, 4 release-completeness et 3 security-hardening, plus doc-tests.
Le graphe normal Store API reste strictement `ksp-store-api -> ksp-core-lib` et aucune dépendance backend/runtime n'entre dans la crate.
### 8.7 Réconciliation `pre.009`
La surface finale réellement retenue pour `0.3.1` est :
```text
RawTransaction / RawTransactionObservation
RawAccountState / RawAccountObservation
primitives de provenance/format/hash/timestamps
queries cursorisées sans plafond métier KSP arbitraire
outcomes idempotence/conflit
RawRetentionState + tombstone transactionnel
normal skip après purge + force rehydrate explicite
10 capabilities backend fines/object-safe
```
Sont explicitement reportés plutôt que simulés dans la foundation :
```text
TransactionStatusObservation
logs/slot/vote event-only contracts
StoreHealth/readiness runtime
type canonique dédié de wake-up persisté-data
processing ledger / backlog métier / executor policy
compression/archive physique
backend PostgreSQL et std.store
N2 STRUCTURAL / N3 DECODED / N4 DOMAIN
```
`README.md` ne contient aucune surface Store détaillée devenue fausse et aucun document USAGE Store n'existe encore ; ils ne sont donc pas modifiés artificiellement par cette tranche.
## 9. Gates de fermeture
### Gate technique final `pre.008`
**PASS opérateur complet.** Voir §8.6. Le gate a été reconstruit après `cargo clean` et couvre audits, workspace check/Clippy/tests, builds Tauri des trois Desk et graphes Cargo. Le test ciblé `ksp-program-api` a également été rejoué avec le bon nom de package.
### Réconciliation documentaire `pre.009`
**PRÊT après audits documentaires.** Voir §8.7. Le plan, la validation, les architectures Store réellement concernées et `IDEAS.md` sont réconciliés. Aucun README/USAGE Store n'existe à maintenir actuellement ; `CHANGELOG.md`, `ROADMAP.md` et le prompt suivant restent réservés à `pre.010`.
### Préparation de publication `pre.010`
Doit rester limitée à :
```text
Cargo.toml
CHANGELOG.md
ROADMAP.md
prompts/021-V0_3_2_START_PROMPT.md
delta pre.010
```
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`
Aucun gate PostgreSQL live n'est demandé à `0.3.1`.
Le prochain prompt devra transformer les invariants API en façade commune + backend de référence et prévoir :
```text
ksp-store-lib
-> façade Store commune
-> réexports utiles de ksp-store-api
-> feature postgres par défaut
-> dispatch backend selon Config
-> erreur backend connu mais non compilé
ksp-store-postgres-lib
-> tokio-postgres
-> pool/TLS audités
-> migrations KSP-owned
-> schema conformance
-> write/read round-trip des modèles API
-> idempotence/race
-> atomic rollback
-> pagination
Config
-> std.store
-> URI/DSN backend lorsque naturel
-> secrets ${KSP_SECRET_*} / .env owned par ksp-config-lib
-> aucun vrai secret versionné
sécurité
-> URI/DSN/credentials redacted
-> aucune lecture directe env/.env par Store ou backend
-> PostgreSQL réel opt-in puis gate final obligatoire
```
## 11. État des tranches
| Tranche | Objet | État |
|-----------|------------------------------------------|---------------------------------|
| `pre.001` | audit/design/taxonomie/split | PASS |
| `pre.002` | scaffold + taxonomie Store API | PASS |
| `pre.003` | primitives + RawTransaction | PASS après `fix.001` |
| `pre.004` | admission matrix + account/status models | PASS |
| `pre.005` | backend contracts/capabilities | PASS |
| `pre.006` | queries/outcomes/retention/tombstone | PASS après `fix.001` |
| `pre.007` | boundary/adversarial/completeness | PASS après `fix.001` |
| `pre.008` | gate technique final | PASS opérateur complet |
| `pre.009` | réconciliation documentaire | PRÊT après audits documentaires |
| `pre.010` | préparation publication | À FAIRE |
| `rel.001` | stable | À FAIRE |