v0.5.3-pre.003
This commit is contained in:
@@ -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 ;
|
||||
- l’implé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 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é.
|
||||
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 l’initialisation ;
|
||||
- l’application 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` lorsqu’ils dépassent la seule persistance. `ks-store` ne doit pas créer une seconde définition concurrente d’un 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 l’arrivée des protocoles trading. Elle doit notamment distinguer `slot`, `block_time` et les timestamps d’acquisition/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 d’idempotence.
|
||||
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 n’est donc pas nécessaire de conserver indéfiniment l’ancien 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/` lorsqu’elles 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.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/decisions/KHADHROONY_SOLANA_NAMESPACE_POLICY.md -->
|
||||
<!-- version: 8 -->
|
||||
<!-- version: 9 -->
|
||||
|
||||
# Politique de namespace Khadhroony Solana
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
Cette décision est adoptée pendant la clôture de `0.5.0` et devient la cible normative des migrations de fondation `0.5.1` à `0.5.3`.
|
||||
|
||||
À partir de `0.5.1-pre.002`, les dix crates Solana généralistes sont physiquement nommées `ks-*` et leurs identifiants Rust `ks_*`. `0.5.1-pre.003` migre également les identités techniques `kb-lib.*` vers `ks-lib-*`. `0.5.1-pre.004` migre les variables possédées par Khadhroony Solana vers `KS_*` et réserve explicitement `KB_*` aux composants réellement possédés par Khadhroony Bot. Le namespace SQL `kb_sol_*` reste temporairement présent jusqu'à `0.5.3`.
|
||||
À partir de `0.5.1-pre.002`, les dix crates Solana généralistes sont physiquement nommées `ks-*` et leurs identifiants Rust `ks_*`. `0.5.1-pre.003` migre également les identités techniques `kb-lib.*` vers `ks-lib-*`. `0.5.1-pre.004` migre les variables possédées par Khadhroony Solana vers `KS_*` et réserve explicitement `KB_*` aux composants réellement possédés par Khadhroony Bot. Le namespace SQL historique `kb_sol_*` est remplacé par `k_sol_*` dans le baseline PostgreSQL de `0.5.3-pre.003`.
|
||||
|
||||
Le renommage des bibliothèques internes ne renomme pas le workspace, le dépôt ni le répertoire racine : ils restent `khadhroony-bot3` pendant toute la série pré-`1.0`. Un éventuel renommage du workspace racine est explicitement hors périmètre de `0.5.x` et ne doit intervenir qu'en `1.0` ou ultérieurement sur décision dédiée.
|
||||
|
||||
@@ -108,7 +108,7 @@ Les segments métier internes (`solana`, `spl`, protocoles, surfaces et opérati
|
||||
|
||||
La normalisation SQL appartient à `0.5.3` avec `ks-store`.
|
||||
|
||||
Les tables génériques représentant des faits Solana doivent migrer du préfixe actuel `kb_sol_*` vers :
|
||||
Depuis `0.5.3-pre.003`, le baseline PostgreSQL actif des faits Solana utilise :
|
||||
|
||||
```text
|
||||
k_sol_*
|
||||
@@ -124,7 +124,7 @@ kb_*
|
||||
|
||||
Une table ne reçoit pas `kb_*` simplement parce qu'elle est consommée par le bot. Elle doit contenir des données dont la responsabilité appartient réellement au domaine applicatif Bot et non à la blockchain ou aux bibliothèques Solana généralistes.
|
||||
|
||||
La migration `kb_sol_*` → `k_sol_*` doit être traitée avec les contrats temporels, de provenance, d'idempotence, d'index et de replay de `0.5.3`, et non comme un remplacement textuel isolé.
|
||||
La reconstruction `kb_sol_*` → `k_sol_*` de `0.5.3-pre.003` est traitée avec les contrats temporels, de provenance, d'idempotence, d'index et de replay ; l'ancien namespace reste uniquement un marqueur détecté/refusé et une référence historique.
|
||||
|
||||
## 8. Ordre des migrations
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/guides/POSTGRES_STORAGE.md -->
|
||||
<!-- version: 5 -->
|
||||
<!-- version: 6 -->
|
||||
|
||||
# Guide PostgreSQL et contrats de stockage
|
||||
|
||||
@@ -35,47 +35,114 @@ Le descripteur public éventuellement affiché provient du résumé runtime et e
|
||||
|
||||
## Domaines
|
||||
|
||||
- raw : acquisitions et observations ;
|
||||
- Core : transactions, instructions, comptes et contexte normalisés ;
|
||||
- decode : ledger, observations décodées et matérialisations ;
|
||||
- replay : candidats et résumés bornés.
|
||||
- N1 raw/acquisition : transactions canoniques, observations de transactions et observations génériques de comptes ;
|
||||
- N2 Core : transactions, clés, top-level, CPI, logs, variations de balances, return data et états de comptes ;
|
||||
- N3/transverse : ledger, observations décodées, couverture et `k_sol_mat_outputs` ;
|
||||
- replay/diagnostic : sélections et résumés bornés au-dessus de ces contrats.
|
||||
|
||||
## Migrations
|
||||
## Baseline `0.5.3-pre.003`
|
||||
|
||||
`0.5.3-pre.002` conserve temporairement le schéma PostgreSQL historique `kb_sol_*` et son mécanisme d'initialisation afin de réaliser d'abord la rupture d'API backend. `pre.003` reconstruit le baseline sous `k_sol_*`, range les ressources sous `ks-store/migrations/postgres/` et impose une instruction SQL par fichier exécutée par les fonctions privées du backend.
|
||||
`pre.003` reconstruit directement le schéma sous `k_sol_*`. Les bases Devnet/Mainnet/test historiques sont considérées reconstructibles ; aucune migration in-place depuis `kb_sol_*` n'est fournie.
|
||||
|
||||
Les bases Devnet/Mainnet/test `0.5.2` sont reconstructibles : aucune compatibilité in-place n'est requise pour ce changement de baseline.
|
||||
Le comportement attendu à l'ouverture est :
|
||||
|
||||
1. base vide + auto-init : création du baseline complet ;
|
||||
2. base `k_sol_*` déjà conforme : vérification/idempotence ;
|
||||
3. base contenant encore des objets `kb_sol_*` : refus non destructif et demande de reconstruction explicite ;
|
||||
4. `DROP`/`TRUNCATE` : opérations de maintenance distinctes, jamais déclenchées implicitement par `Store::open()`.
|
||||
|
||||
Le baseline candidat au gel comprend 16 tables N1-N3.
|
||||
|
||||
## Ressources SQL
|
||||
|
||||
Les ressources actives sont sous :
|
||||
|
||||
```text
|
||||
ks-store/migrations/postgres/
|
||||
schema/
|
||||
tables/
|
||||
constraints/
|
||||
indexes/
|
||||
maintenance/
|
||||
truncate/
|
||||
drop/
|
||||
```
|
||||
|
||||
Chaque fichier contient une instruction SQL. Le code PostgreSQL privé utilise `include_str!` et l'orchestrateur global exécute le schéma dans une transaction unique avec advisory lock.
|
||||
|
||||
Il n'existe plus trois initialiseurs raw/Core/decode indépendants : **l'initialisation du schéma est globale**.
|
||||
|
||||
Le corpus `pre.003` contient actuellement :
|
||||
|
||||
- 16 créations de tables ;
|
||||
- 129 ressources de contraintes ;
|
||||
- 59 créations d'index explicites ;
|
||||
- 16 ressources `TRUNCATE` ;
|
||||
- 16 ressources `DROP` ;
|
||||
- soit **236 ressources SQL**.
|
||||
|
||||
PostgreSQL attend **75 index** au total dans son diagnostic : 59 index explicites plus les 16 index de clé primaire créés par PostgreSQL.
|
||||
|
||||
Les index non uniques restent des optimisations physiques et ne font pas partie du gel logique N1-N3.
|
||||
|
||||
## Statut du schéma
|
||||
|
||||
La façade n'utilise plus `_sqlx_migrations` comme preuve du baseline actuel. Le statut est dérivé du contrat réellement observé :
|
||||
|
||||
- aucune ressource connue : non initialisé ;
|
||||
- toutes les ressources attendues : contrat courant ;
|
||||
- présence partielle : drift/partial.
|
||||
|
||||
Le résumé d'initialisation expose des compteurs de modèles, tables et index sans publier leurs noms physiques.
|
||||
|
||||
## Compatibilité des identités de processeurs
|
||||
|
||||
Depuis `0.5.1-pre.003`, les identités techniques produites par `ks-lib` utilisent `ks-lib-decoder.*`, `ks-lib-executor.*` et `ks-lib-materializer.*`. Une base alimentée avant cette migration peut encore contenir des valeurs `kb-lib.*` dans les contrats de provenance/replay.
|
||||
Depuis `0.5.1-pre.003`, les identités techniques produites par `ks-lib` utilisent `ks-lib-decoder.*`, `ks-lib-executor.*` et `ks-lib-materializer.*`.
|
||||
|
||||
Aucune migration SQL automatique de ces valeurs n'est ajoutée en `0.5.1` : avant `0.6.x`, une base conservée doit soit être reconstruite proprement, soit faire l'objet d'une migration de données explicitement contrôlée avant reprise du replay. Il ne faut pas exploiter durablement un même corpus avec les anciennes et nouvelles identités mélangées. Les noms de tables `kb_sol_*` restent inchangés jusqu'au chantier `0.5.3`.
|
||||
Comme les bases `0.5.2` doivent être reconstruites pour le nouveau baseline `0.5.3`, les anciennes identités `kb-lib.*` ne sont pas migrées automatiquement dans ce chantier.
|
||||
|
||||
## Core readiness
|
||||
|
||||
`pre.003` ajoute les éléments génériques nécessaires au futur redécodage :
|
||||
|
||||
- `block_time` sur raw/Core transaction ;
|
||||
- `stack_height` sur top-level/CPI ;
|
||||
- parent CPI immédiat reconstructible ;
|
||||
- `k_sol_core_return_data` ;
|
||||
- `k_sol_obs_account_observations` ;
|
||||
- `k_sol_core_account_states` ;
|
||||
- provenance de schéma optionnelle sur les observations décodées.
|
||||
|
||||
Ces contrats sont indépendants d'Anchor/IDL. Aucun parser Anchor ni table `anchor_*` n'appartient à `0.5.3`.
|
||||
|
||||
## Repositories
|
||||
|
||||
Les traits publics et la façade `Store` décrivent des opérations fonctionnelles indépendantes du moteur. PostgreSQL implémente ces contrats à l’intérieur de `ks-store`; aucune crate consommatrice ne reçoit `PgPool`, un type SQLx ou une requête concrète. Les opérations de lecture utilisent des filtres et paginations bornés.
|
||||
Les traits publics et la façade `Store` décrivent des opérations fonctionnelles indépendantes du moteur. PostgreSQL implémente ces contrats à l'intérieur de `ks-store`; aucune crate consommatrice ne reçoit `PgPool`, un type SQLx ou une requête concrète.
|
||||
|
||||
Le schéma des observations/états de comptes est introduit avant gel en `pre.003`; son ingestion/replay fonctionnel est raccordé dans la tranche repositories/replay suivante.
|
||||
|
||||
## Diagnostics
|
||||
|
||||
La surface publique expose :
|
||||
|
||||
- health snapshot ;
|
||||
- migration snapshot ;
|
||||
- schema/migration snapshot générique ;
|
||||
- backend descriptor masqué ;
|
||||
- résumé de configuration sanitisé ;
|
||||
- résumé d'initialisation/vérification par modèle logique ;
|
||||
- diagnostics de ressources raw/Core/decode/materialization sans nom physique d'objet.
|
||||
- diagnostics de ressources sans nom physique d'objet.
|
||||
|
||||
Les noms de tables, index, contraintes et le SQL restent des détails backend-internes. Les traces PostgreSQL utilisent l’unique `target: crate::TRACING_TARGET` (`ks-store`) avec les champs structurés `backend="postgres"`, `domain="ks-store.pg"` et un `action` précis (`connection`, `migration`, `query`, `health`, `replay`, etc.).
|
||||
Les noms de tables, index, contraintes et le SQL restent des détails backend-internes. Les traces PostgreSQL utilisent l'unique `target: crate::TRACING_TARGET` (`ks-store`) avec les champs structurés `backend="postgres"`, `domain="ks-store.pg"` et un `action` précis.
|
||||
|
||||
## Invariants
|
||||
|
||||
- aucune donnée canonique ne doit être dupliquée sans justification ;
|
||||
- les écritures rejouables doivent être idempotentes ;
|
||||
- la progression de campagne doit rester cohérente avec les lignes effectivement traitées ;
|
||||
- les requêtes dynamiques n’acceptent que des identifiants validés ;
|
||||
- les détails PostgreSQL utiles au diagnostic restent backend-internes ; les erreurs traversant la façade publique ne doivent jamais divulguer DSN, password ou options sensibles.
|
||||
- les requêtes dynamiques n'acceptent que des identifiants validés ;
|
||||
- les détails PostgreSQL utiles au diagnostic restent backend-internes ;
|
||||
- les erreurs traversant la façade publique ne doivent jamais divulguer DSN, password ou options sensibles ;
|
||||
- un nouveau décodeur doit pouvoir exploiter N1/N2/N3 sans remodelage normal de ces niveaux.
|
||||
|
||||
## Références
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/V0_5_3_KS_STORE_NORMALIZATION_PLAN.md -->
|
||||
<!-- version: 7 -->
|
||||
<!-- version: 8 -->
|
||||
|
||||
# Plan `0.5.3` — audit et normalisation de `ks-store`
|
||||
|
||||
@@ -174,7 +174,7 @@ Les fonctions privées PostgreSQL correspondantes sont séparées et utilisent `
|
||||
| `k_sol_decode_events` | `DecodeObservationInsert` | `DecodePipelineStore` | `decode_pipeline_queries` | `ks-pipeline::decode_replay` |
|
||||
| `k_sol_decode_coverage_declarations` | `DecodeCoverageDeclarationInsert` | `DecodePipelineStore` | `decode_pipeline_queries` | `ks-pipeline::decode_replay` |
|
||||
| `k_sol_decode_coverage_observations` | `DecodeCoverageObservationInsert`, `DecodeCoverageSummaryRow` | `DecodePipelineStore` | `decode_pipeline_queries` | pipeline + desktop diagnostics |
|
||||
| `k_sol_mat_outputs` | `MaterializedOutputInsert`, `MaterializedEventQueryRow` | `DecodePipelineStore` | `decode_pipeline_queries` | pipeline, scénarios Devnet, desktop |
|
||||
| `k_sol_mat_outputs` | `MaterializedOutputInsert`, `MaterializedOutputQueryRow` | `DecodePipelineStore` | `decode_pipeline_queries` | pipeline, scénarios Devnet, desktop |
|
||||
|
||||
### 5.1 Contrats publics hérités sans implémentation
|
||||
|
||||
@@ -1079,7 +1079,7 @@ La même règle s'applique à tout autre protocole : une table nommée d'après
|
||||
- réouverture idempotente d'une base déjà initialisée ;
|
||||
- refus propre d'une base contenant encore des objets `kb_sol_*` ;
|
||||
- absence finale de tables, contraintes, index et séquences `kb_sol_*` après reconstruction ;
|
||||
- présence des **13 tables de baseline**, plus des éventuels contrats N1/N2/N3 génériques explicitement retenus après le canari future-decoder ;
|
||||
- présence des **16 tables du baseline candidat au gel** retenu en `pre.003` ;
|
||||
- snapshot exact des colonnes/types/nullabilités/PK/FK/uniques/checks frozen ;
|
||||
- présence et contrat séparé des tables top-level/CPI ;
|
||||
- test de lecture logique combinée top-level+CPI sans perte, doublon ni ordre instable ;
|
||||
@@ -1154,7 +1154,7 @@ Avec `KS_SECRET_POSTGRES_TEST_URL` local :
|
||||
|
||||
## 26. Snapshot de contrat frozen
|
||||
|
||||
Le snapshot `0.5.3` couvre les **13 tables existantes de baseline, plus toute structure N1/N2/N3 générique dont le canari future-decoder démontre la nécessité avant gel**, ainsi que les tables transverses de processing/decode qui assurent leur idempotence et leur journalisation. Les futures projections N4 disposent de contrats/version propres, mais ne sont pas ajoutées à ce snapshot frozen fondamental.
|
||||
Le snapshot `0.5.3` couvre les **16 tables du baseline candidat au gel retenu en `pre.003`**, y compris les trois contrats génériques ajoutés par le canari future-decoder (`account observation`, `account state`, `transaction return data`), ainsi que les tables transverses de processing/decode qui assurent leur idempotence et leur journalisation. Les futures projections N4 disposent de contrats/version propres, mais ne sont pas ajoutées à ce snapshot frozen fondamental.
|
||||
|
||||
Une fixture machine-readable sera créée avant clôture, par exemple :
|
||||
|
||||
@@ -1320,7 +1320,7 @@ cargo tauri dev -c kb-app-demo-desktop/tauri.conf.json
|
||||
La version ne peut être clôturée que si :
|
||||
|
||||
- il n'existe plus d'objet actif `kb_sol_*` ;
|
||||
- les 13 tables de baseline et toute table N1/N2/N3 générique ajoutée après le canari future-decoder correspondent exactement au snapshot frozen documenté ;
|
||||
- les 16 tables du baseline candidat retenu en `pre.003` correspondent exactement au snapshot frozen documenté ;
|
||||
- `block_time` est conservé lorsqu'il existe et reste `NULL` sinon ;
|
||||
- les top-level et CPI restent physiquement séparées mais peuvent être sélectionnées séparément ou comme flux logique commun pour le decode ;
|
||||
- replay et invalidation descendante sont cohérents et transactionnels, avec contrats N1 -> N2, N2 -> N3 et frontière N3 -> N4 documentée/testable ;
|
||||
@@ -1453,3 +1453,159 @@ Le nettoyage fin de l’instrumentation des requêtes (durées, nombres de ligne
|
||||
- n’implémente pas Anchor.
|
||||
|
||||
Ces travaux restent affectés aux tranches `pre.003+` prévues par le présent plan.
|
||||
|
||||
## 33. État réalisé de `0.5.3-pre.003`
|
||||
|
||||
`pre.003` réalise la reconstruction physique PostgreSQL et ferme les principaux manques révélés par le canari future-decoder. Le résultat est un **baseline candidat au gel**, pas encore le snapshot frozen final de `pre.006`.
|
||||
|
||||
### 33.1 Baseline candidat : 16 tables
|
||||
|
||||
Les 13 tables historiques sont conservées conceptuellement sous le namespace `k_sol_*`, sans fusion des instructions top-level/CPI. Trois contrats Solana génériques sont ajoutés avant gel :
|
||||
|
||||
1. `k_sol_obs_account_observations` — observation N1 d'un état de compte avec bytes exacts, hash et provenance d'acquisition ;
|
||||
2. `k_sol_core_account_states` — état N2 canonique dérivé d'une observation de compte ;
|
||||
3. `k_sol_core_return_data` — conservation N2 de la `returnData` transactionnelle déjà présente dans le document canonique N1.
|
||||
|
||||
Le baseline candidat comporte donc :
|
||||
|
||||
```text
|
||||
N1
|
||||
k_sol_raw_transactions
|
||||
k_sol_obs_transaction_observations
|
||||
k_sol_obs_account_observations
|
||||
|
||||
N2
|
||||
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
|
||||
|
||||
N3 / transverse
|
||||
k_sol_ops_processing_ledger
|
||||
k_sol_decode_events
|
||||
k_sol_decode_coverage_declarations
|
||||
k_sol_decode_coverage_observations
|
||||
k_sol_mat_outputs
|
||||
```
|
||||
|
||||
Aucune structure n'est nommée d'après Anchor, une IDL, un DEX ou un protocole.
|
||||
|
||||
### 33.2 Temporalité et Core instructionnel
|
||||
|
||||
`block_time` devient une colonne nullable de premier rang sur `k_sol_raw_transactions` et `k_sol_core_transactions`. La Core extraction vérifie la cohérence entre le document canonique N1 et l'ancre Core lorsqu'ils sont reliés.
|
||||
|
||||
Les instructions top-level et CPI restent physiquement séparées. Les deux contrats portent désormais `stack_height` lorsque Solana la fournit. La Core extraction reconstruit les chemins CPI imbriqués à partir de la pile ; `parent_instruction_path` pointe alors vers le parent immédiat. Lorsque `stackHeight` est absent, la CPI reste rattachée de manière déterministe à la top-level racine sans inventer un niveau de pile.
|
||||
|
||||
Les CPI reçoivent dans le schéma les mêmes champs de lifecycle/processor que les top-level. La sélection autonome et le replay opérationnel CPI restent à finaliser dans `pre.004`.
|
||||
|
||||
### 33.3 Replay Core v3
|
||||
|
||||
`MdCoreInstructionReplayInput` passe à la version 3 et peut transporter :
|
||||
|
||||
- `block_time` ;
|
||||
- `stack_height` ;
|
||||
- `parent_instruction_path` ;
|
||||
- le contexte ordonné des instructions top-level ;
|
||||
- la `returnData` transactionnelle.
|
||||
|
||||
Le champ de contexte nouveau est nommé `top_level_instructions_json`. Les usages historiques du terme `outer` dans des décodeurs existants ne sont pas renommés mécaniquement lorsqu'ils décrivent encore une sémantique propre à ces contrats.
|
||||
|
||||
Le constructeur historique reste disponible pour les tests et sources synthétiques ; les inputs provenant du Core persistant sont enrichis par le store.
|
||||
|
||||
### 33.4 Provenance de schéma N3
|
||||
|
||||
`k_sol_decode_events` réserve des champs nullable de provenance de schéma :
|
||||
|
||||
```text
|
||||
schema_kind
|
||||
schema_id
|
||||
schema_version
|
||||
schema_hash
|
||||
```
|
||||
|
||||
Ils restent vides pour les décodeurs compilés actuels. Un futur mécanisme basé sur un schéma externe/IDL pourra les renseigner sans introduire de colonne Anchor ou modifier N1/N2.
|
||||
|
||||
### 33.5 `k_sol_mat_outputs`
|
||||
|
||||
Le renommage conceptuel est réalisé jusque dans l'API :
|
||||
|
||||
```text
|
||||
MaterializedOutputFilter
|
||||
MaterializedOutputQueryRow
|
||||
DecodePipelineStore::list_materialized_outputs
|
||||
```
|
||||
|
||||
`k_sol_mat_outputs` reste le journal N3 générique versionné et la source de replay vers les futures projections N4.
|
||||
|
||||
### 33.6 Ressources PostgreSQL atomiques
|
||||
|
||||
La chaîne active historique `0001` à `0004` est retirée. Les scripts de maintenance monolithiques sont également retirés.
|
||||
|
||||
La nouvelle arborescence contient :
|
||||
|
||||
```text
|
||||
migrations/postgres/
|
||||
schema/tables/ 16
|
||||
schema/constraints/ 129
|
||||
schema/indexes/ 59
|
||||
maintenance/truncate/16
|
||||
maintenance/drop/ 16
|
||||
```
|
||||
|
||||
Soit **236 ressources SQL**. Chaque ressource contient une seule instruction top-level et est embarquée une seule fois par `include_str!`.
|
||||
|
||||
L'orchestrateur PostgreSQL global :
|
||||
|
||||
- valide les ressources ;
|
||||
- refuse les objets historiques `kb_sol_*` ;
|
||||
- ouvre une transaction ;
|
||||
- prend un advisory lock ;
|
||||
- applique tables, contraintes et index dans l'ordre ;
|
||||
- commit uniquement lorsque le baseline complet est cohérent.
|
||||
|
||||
Les initialiseurs partiels raw/Core/decode sont supprimés, y compris des tests. Une initialisation ne peut donc plus valider accidentellement un sous-schéma comme si le baseline complet était prêt.
|
||||
|
||||
### 33.7 Diagnostics du schéma
|
||||
|
||||
Le diagnostic ne dépend plus de `_sqlx_migrations` pour déterminer si le baseline courant est disponible. Il compare les ressources connues réellement présentes.
|
||||
|
||||
Le résumé backend-agnostique expose :
|
||||
|
||||
- modèles logiques ;
|
||||
- compte de tables ;
|
||||
- compte d'index ;
|
||||
- état ready/partial/not-initialized ;
|
||||
|
||||
sans publier les noms physiques.
|
||||
|
||||
Le backend PostgreSQL attend actuellement **75 index** : 59 index explicites et les 16 index de clés primaires produits par PostgreSQL.
|
||||
|
||||
### 33.8 Conclusion du canari future-decoder
|
||||
|
||||
Le canari a effectivement révélé deux pertes/absences structurelles de la baseline `0.5.2` :
|
||||
|
||||
- `returnData` était conservée en N1 mais perdue en N2 ;
|
||||
- aucun chemin persistant générique d'observation/état de compte n'était réservé.
|
||||
|
||||
Ces deux lacunes sont corrigées avant gel.
|
||||
|
||||
Les autres metadata transactionnelles auditées (`fee`, rewards, compute units, cost units) restent conservées dans le document canonique N1. Elles ne sont pas nécessaires au décodage futur et ne justifient pas de gonfler l'ancre N2 avant gel ; une projection additive reste possible si un besoin queryable stable apparaît.
|
||||
|
||||
### 33.9 Travaux volontairement laissés à `pre.004+`
|
||||
|
||||
`pre.003` ne clôt pas encore :
|
||||
|
||||
- la lecture logique commune top-level+CPI et le replay CPI autonome ;
|
||||
- l'ingestion/replay opérationnel du nouveau flux account observation -> account state ;
|
||||
- l'invalidation descendante N1 -> N2 -> N3 -> N4 ;
|
||||
- la pagination cursorisée ;
|
||||
- la validation des index par plans réels sur dataset représentatif ;
|
||||
- le snapshot machine-readable frozen ;
|
||||
- la refonte fonctionnelle desktop finale ;
|
||||
- les projections N4 metadata/trading.
|
||||
|
||||
Ces points restent dans les tranches suivantes et peuvent décaler le premier candidat de clôture au-delà de `pre.007`.
|
||||
|
||||
Reference in New Issue
Block a user