v0.5.3-pre.003

This commit is contained in:
2026-08-12 11:00:59 +02:00
parent 8448ad1079
commit 400ced4832
313 changed files with 7773 additions and 2623 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/STORAGE_ARCHITECTURE.md -->
<!-- version: 7 -->
<!-- version: 8 -->
# Architecture du stockage
@@ -9,42 +9,45 @@
- la façade publique backend-agnostique `Store` et ses options d'ouverture ;
- les contrats store-neutral ;
- les DTO et entités persistées ;
- les DTO et entités persistés ;
- la pagination, le replay et les rapports de santé ;
- les traits de repositories ;
- les résumés runtime/init sanitisés ;
- limplémentation PostgreSQL privée ;
- les migrations et requêtes appartenant au backend actif.
- l'implémentation PostgreSQL privée ;
- les ressources de schéma, maintenance et requêtes appartenant au backend actif.
Depuis `0.5.3-pre.002`, les consommateurs ne construisent plus un backend concret. `ks-store` possède la connexion et le dispatch interne ; `PostgresStore`, `PgPool` et SQLx ne traversent plus sa frontière publique.
Depuis `0.5.3-pre.003`, PostgreSQL construit directement le nouveau baseline `k_sol_*` à partir de ressources SQL atomiques ; les migrations historiques `0001` à `0004` ne constituent plus la chaîne active.
## 2. Frontières
### 2.1 Contrats store-neutral
Les contrats ne dépendent pas des détails SQL lorsquune abstraction stable est suffisante. Ils décrivent les entrées, sorties, identifiants, pages, diagnostics et erreurs nécessaires aux consommateurs. `StoreOpenOptions` transporte un code backend et un objet d'options opaque ; seul `ks-store` interprète le moteur sélectionné.
Les contrats ne dépendent pas des détails SQL lorsqu'une abstraction stable est suffisante. Ils décrivent les entrées, sorties, identifiants, pages, diagnostics et erreurs nécessaires aux consommateurs. `StoreOpenOptions` transporte un code backend et un objet d'options opaque ; seul `ks-store` interprète le moteur sélectionné.
Le résumé runtime expose des modèles logiques et des compteurs d'objets par catégorie sans publier les noms physiques. PostgreSQL peut ainsi exposer des compteurs `table`/`index`, tandis qu'un futur backend peut utiliser d'autres catégories sans modifier le desktop.
Le résumé runtime expose des modèles logiques et des compteurs d'objets par catégorie sans publier les noms physiques. PostgreSQL expose actuellement des compteurs `table` et `index`, tandis qu'un futur backend peut utiliser d'autres catégories sans modifier le desktop.
### 2.2 Adaptateur PostgreSQL
Le module PostgreSQL possède :
- la validation de ses options ;
- la connexion et linitialisation ;
- lapplication idempotente des migrations ;
- la connexion et l'initialisation ;
- l'orchestrateur transactionnel global du baseline ;
- les ressources SQL `include_str!` ;
- les requêtes typées ;
- les diagnostics physiques ;
- les opérations de replay et de sélection de candidats ;
- le target de tracing canonique `ks-store`, enrichi des champs `backend="postgres"`, `domain="ks-store.pg"` et `action` pour les opérations PostgreSQL.
- le target de tracing canonique `ks-store`, enrichi des champs `backend="postgres"`, `domain="ks-store.pg"` et `action`.
Les détails physiques restent privés. Les erreurs et résumés traversant la façade ne doivent pas divulguer de DSN, password ou option sensible.
### 2.3 Modèles partagés
Les modèles métier communs restent dans `ks-lib` lorsquils dépassent la seule persistance. `ks-store` ne doit pas créer une seconde définition concurrente dun contrat partagé.
Les modèles métier communs restent dans `ks-lib` lorsqu'ils dépassent la seule persistance. `ks-store` ne doit pas créer une seconde définition concurrente d'un contrat partagé.
## 3. Catégories de données
## 3. Niveaux de persistance
Le stockage distingue quatre niveaux durables :
@@ -53,11 +56,101 @@ Le stockage distingue quatre niveaux durables :
- **N3** — decode/materialization générique et journaux versionnés ;
- **N4** — projections spécialisées/queryables additives.
N1/N2/N3 constituent la fondation fortement gelée après `0.5.3`, sous réserve d'une urgence ou d'une omission structurelle majeure. N4 reste plus évolutif. Les replays N1 -> N2, N2 -> N3 et N3 -> N4 doivent pouvoir être exécutés indépendamment et de manière idempotente.
N1/N2/N3 constituent la fondation candidate au gel de `0.5.3`. Le gel formel n'est déclaré qu'après snapshot et validations de réconciliation ; après clôture, leur évolution normale doit être fortement contrainte. N4 reste volontairement plus évolutif.
Les noms de tables, contrats de replay et APIs publiques sont documentés dans `ks-store/USAGE.md` à partir des exports et migrations actuels.
Les replays N1 -> N2, N2 -> N3 et N3 -> N4 doivent pouvoir être exécutés indépendamment et de manière idempotente.
## 4. Propriétés attendues
## 4. Baseline N1-N3 de `pre.003`
Le baseline PostgreSQL comporte **16 tables**.
### 4.1 N1
- `k_sol_raw_transactions` ;
- `k_sol_obs_transaction_observations` ;
- `k_sol_obs_account_observations`.
`k_sol_raw_transactions` conserve le document canonique source-independent et `block_time` lorsqu'il est fourni par Solana. Les observations d'acquisition restent séparées de ce document canonique.
`k_sol_obs_account_observations` réserve un input générique pour les acquisitions d'état de compte : identité du compte, slot/context, bytes exacts, hash et provenance d'acquisition. Cette structure n'est liée à aucun décodeur ou IDL.
### 4.2 N2 Core
- `k_sol_core_transactions` ;
- `k_sol_core_account_keys` ;
- `k_sol_core_instructions` ;
- `k_sol_core_inner_instructions` ;
- `k_sol_core_logs` ;
- `k_sol_core_balance_changes` ;
- `k_sol_core_return_data` ;
- `k_sol_core_account_states`.
`k_sol_core_transactions` porte l'ancre transactionnelle et `block_time`.
Les instructions top-level et CPI restent physiquement séparées. Les deux portent `stack_height` lorsque disponible ; les CPI conservent leur parent immédiat reconstructible. Elles doivent converger vers des capacités lifecycle/replay équivalentes sans imposer un stockage physique unique.
`k_sol_core_return_data` évite de perdre en N2 la `returnData` déjà présente dans la transaction canonique N1.
`k_sol_core_account_states` fournit le pendant Core des observations de comptes et conserve les bytes exacts ainsi que leur provenance N1.
### 4.3 N3 et transverse
- `k_sol_ops_processing_ledger` ;
- `k_sol_decode_events` ;
- `k_sol_decode_coverage_declarations` ;
- `k_sol_decode_coverage_observations` ;
- `k_sol_mat_outputs`.
`k_sol_mat_outputs` est le journal générique durable des sorties de matérialisation. Les projections métier N4 ne le remplacent pas.
`k_sol_decode_events` réserve une provenance de schéma nullable (`kind/id/version/hash`) pour les mécanismes de décodage pouvant dépendre d'un schéma externe. Les décodeurs compilés actuels la laissent vide.
## 5. Readiness des futurs décodeurs
Le canari future-decoder ne doit pas introduire Anchor dans le schéma. Il vérifie que les faits Solana génériques suffisants sont conservés :
- bytes d'instruction et comptes ordonnés ;
- propriétés signer/writable résolubles ;
- instructions top-level et CPI ;
- `stack_height` et parent CPI ;
- logs ordonnés ;
- `returnData` ;
- observations/états bruts de comptes ;
- temporalité et provenance ;
- identité/version/hash d'un schéma externe lorsqu'un décodeur en utilise un.
La conséquence de `pre.003` est l'ajout de trois contrats génériques au-dessus des 13 tables historiques : observation de compte, état Core de compte et return data Core. Le baseline candidat au gel passe donc à 16 tables.
Les métriques transactionnelles comme fee, rewards, compute units et cost units restent disponibles dans N1. Elles ne sont pas requises pour ce canari et ne justifient pas une extension de l'ancre Core en `pre.003`; une future projection additive pourra les rendre queryables si nécessaire.
## 6. Ressources PostgreSQL
Les ressources actives sont classées sous :
```text
ks-store/migrations/postgres/
schema/
tables/
constraints/
indexes/
maintenance/
truncate/
drop/
```
Principes :
- une instruction SQL par fichier ;
- un `include_str!` privé par ressource ;
- aucun DDL dupliqué dans une chaîne Rust ;
- tables avant contraintes, contraintes avant index ;
- initialisation complète dans une transaction PostgreSQL unique avec advisory lock ;
- `DROP`/`TRUNCATE` séparés de l'auto-init ;
- refus explicite d'un schéma contenant encore des objets `kb_sol_*`.
Le baseline `pre.003` contient **236 ressources SQL atomiques** et **75 index attendus**. Ces nombres décrivent l'implémentation PostgreSQL actuelle, pas une API publique gelée.
## 7. Propriétés attendues
- initialisation idempotente ;
- pagination bornée ;
@@ -65,12 +158,12 @@ Les noms de tables, contrats de replay et APIs publiques sont documentés dans `
- absence de double effet lors des replays ;
- validation stricte des entrées ;
- erreurs explicites ;
- séparation entre données brutes, résultats de décodage et matérialisations.
- séparation entre acquisition/raw, Core, decode/materialization et projections N4 ;
- absence de dépendance de N1/N2 à une technologie de décodeur ;
- conservation des faits nécessaires à un redécodage historique.
La série `0.5.3` normalisera cette fondation avant larrivée des protocoles trading. Elle doit notamment distinguer `slot`, `block_time` et les timestamps dacquisition/persistance, normaliser la structure interne de `ks-store`, vérifier les champs et index manquants et préparer les futures matérialisations trading, routing et multi-pools sans perdre les contrats de provenance et didempotence.
Les index non uniques restent des optimisations physiques évolutives. Les noms/colonnes/types/nullabilités/PK/FK/uniques/checks/sémantiques du baseline N1-N3 seront figés séparément lors de la tranche de gel.
La même migration remplace le préfixe historique des tables Solana `kb_sol_*` par `k_sol_*`. La base peut encore être reconstruite ou migrée proprement avant `0.6.x`, il nest donc pas cessaire de conserver indéfiniment lancien préfixe. Le préfixe `kb_*` est réservé aux éventuelles tables dont la responsabilité appartient réellement au domaine applicatif Bot, pas aux faits Solana simplement consommés par le bot.
## 8. Données de test
## 5. Données de test
Les fixtures privées, bases locales et preuves temporaires ne font pas partie des livraisons. Les matrices contractuelles partagées restent sous `test-fixtures/contract-matrices/` lorsquelles sont nécessaires aux tests.
Les fixtures privées, bases locales et preuves temporaires ne font pas partie des livraisons. Les matrices contractuelles partagées restent sous `test-fixtures/contract-matrices/` lorsqu'elles sont nécessaires aux tests.