0.3.15-pre.014-fix.001

This commit is contained in:
2026-09-17 23:09:21 +02:00
parent ad24cb36fa
commit 6d820bf0d7
14 changed files with 648 additions and 67 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/004-COMPONENT_INVENTORY.md -->
<!-- version: 41 -->
<!-- version: 42 -->
# Inventaire initial des composants KSP
@@ -18,46 +18,46 @@ Ce document maintient l'inventaire synthétique des composants retenus ou presse
## Inventaire synthétique
| Domaine | Composant | Type | Statut | Première cible actuelle | Mission |
|-------------------------|-----------------------------------------|-------------|--------------|---------------------------------|---------------------------------------------------------------------------------------------|
| Core | `ksp-core-lib` | lib | Stable | `0.1.1` | Error/Result, Program IDs et primitives fondamentales |
| Logging | `ksp-logging-lib` | lib | Stable | `0.1.2` | façade unique tracing KSP |
| Config | `ksp-config-lib` | lib | Stable | `0.1.3` | documents, profils, env et persistence Config |
| Config Desk | `ksp-app-config-desk` | app | Stable | `0.1.4` | validation/management Config |
| On-chain HTTP | `ksp-onchain-transport-lib` | lib | Stable | `0.2.1``0.2.4` | HTTP standard complet : 52/52 current + 14/14 historical |
| Wallet | `ksp-wallet-lib` | lib | Stable | `0.2.5` | `.kspwallet`, VIEW/OWNER, secrets, signature, import/export |
| Wallet Desk | `ksp-app-wallet-desk` | app | Stable | `0.2.6` | Wallet + Config + balance HTTP + projection SOL/USD auxiliaire |
| Wallet V2 | `ksp-wallet-lib` | lib | Stable | `0.2.6` | wire/runtime V2 + API default/versionnée + migration explicite |
| Standard WS | `ksp-onchain-transport-lib` | lib | Stable | `0.2.7` | WebSocket Solana 18/18, sessions/subscriptions bornées |
| Helius WS | `ksp-onchain-transport-lib` | lib | Stable | `0.2.8` | LaserStream WS : 7 standard + transaction, actor partagé |
| Yellowstone | `ksp-onchain-transport-lib` | lib | Stable | `0.2.9` | client gRPC standard/provider-neutral |
| Off-chain price | `ksp-offchain-transport-lib` | lib | Stable | `0.2.11` | prix SOL/USD multi-provider, limits et availability |
| SOL Prices Desk | `ksp-app-solprices-desk` | app | Stable | `0.2.12` | HID provider-agnostic pour visualisation/refresh prix |
| Interface passive | `ksp-interface-lib` | lib | Stable | `0.2.13` | façade wire + contrats passifs partagés, dont événements acquisition provider-neutral |
| Program API | `ksp-program-api` | API | Stable | `0.2.14` | contrats extensibles Program |
| Program impl. | `ksp-program-lib` | lib | Retenu | vertical slices ultérieurs | implementations Program officielles |
| Program extension | `ksp-program-<name>-lib` | lib externe | À la demande | dès besoin | implementation externe de `ksp-program-api` |
| Store API | `ksp-store-api` | API | Stable | `0.3.1` | RAW transaction/account, observations, queries, outcomes, rétention et capabilities backend |
| Store runtime | `ksp-store-lib` | lib | Stable | `0.3.2``0.3.4` | façade backend-neutral et conformance RAW 10/10 |
| Store PostgreSQL | `ksp-store-postgres-lib` | lib | Stable | `0.3.2``0.3.4` | backend référence : fondation, RawTransaction et RawAccountState |
| Job lifecycle | `ksp-job-api` | API | Implémenté | `0.3.6` | identité/lifecycle/annulation/notifications latest-value runtime-neutral |
| Backfill | `ksp-job-backfill-lib` | lib | Implémenté | `0.3.6`, extension `0.3.16` | première verticale HTTP puis extension multi-source/historique sans changer lidentité RAW |
| Backfill Desk | `ksp-app-backfill-desk` | app | Implémenté | `0.3.7`, extension `0.3.16` | contrôle du backfill RAW ; sélection des stratégies/sources ajoutée après le worker live |
| Store Desk | `ksp-app-store-desk` | app | Implémenté | `0.3.8` | inspection RAW read-only Transaction/Account/Observation via façade Store |
| RAW transaction common | `ksp-raw-transaction-lib` | lib | Implémenté | `0.3.10` | canonicalisation/wire RAW Transaction v1 source-neutral partagé entre producteurs |
| Worker lifecycle | `ksp-worker-api` | API | Implémenté | `0.3.9` | lifecycle/health/progression génériques des services continus |
| RAW transaction worker | `ksp-worker-raw-transaction-ingest-lib` | worker/lib | Implémenté | `0.3.11``0.3.14` | 5 familles live + gaps/coverage/repair run-local, fairness, health et shutdown bornés |
| RAW ingest Desk | `ksp-app-raw-transaction-ingest-desk` | app | Retenu | `0.3.15` | choix/supervision dune ou plusieurs sources/méthodes sans réimplémenter le worker |
| STRUCTURAL job | nom à fixer | job/lib | Retenu | couche STRUCTURAL | normalisation Solana générique RAW -> STRUCTURAL bornée/rejouable |
| STRUCTURAL worker | nom à fixer | worker/lib | Retenu | fin couche STRUCTURAL | backlog RAW -> STRUCTURAL continu |
| Materializer API | `ksp-materializer-api` | API | Retenu | premier groupe DECODED | contrats extensibles matérialisation |
| Materializer impl. | `ksp-materializer-lib` | lib | Retenu | premier groupe DECODED | implementations officielles communes |
| Execution policy | `ksp-execution-policy-api` | API | Retenu | premier vrai besoin execution | décision/safety multi-contexte |
| Execution orchestration | `ksp-execution-lib` | lib | Retenu | premier vrai cycle execution | Program + policy + Wallet + transport |
| Scenarios | `ksp-scenario-<domain>-lib` | lib | Retenu | vertical slices | validation métier/devnet par groupe |
| Scenario API | `ksp-scenario-api` | API | Non retenu | — | norme souple avant trait commun |
| Market Desk | `ksp-app-market-desk` | app | Pressenti | après Meteora/Raydium/Pump/Orca | tokens, pools, trades, liquidity, price, OHLC |
| Trading Intelligence | noms à définir | libs/jobs | Pressenti | après données stables | features/signaux/anomalies/ML |
| Domaine | Composant | Type | Statut | Première cible actuelle | Mission |
|-------------------------|-----------------------------------------|-------------|--------------|---------------------------------|--------------------------------------------------------------------------------------------------|
| Core | `ksp-core-lib` | lib | Stable | `0.1.1` | Error/Result, Program IDs et primitives fondamentales |
| Logging | `ksp-logging-lib` | lib | Stable | `0.1.2` | façade unique tracing KSP |
| Config | `ksp-config-lib` | lib | Stable | `0.1.3` | documents, profils, env et persistence Config |
| Config Desk | `ksp-app-config-desk` | app | Stable | `0.1.4` | validation/management Config |
| On-chain HTTP | `ksp-onchain-transport-lib` | lib | Stable | `0.2.1``0.2.4` | HTTP standard complet : 52/52 current + 14/14 historical |
| Wallet | `ksp-wallet-lib` | lib | Stable | `0.2.5` | `.kspwallet`, VIEW/OWNER, secrets, signature, import/export |
| Wallet Desk | `ksp-app-wallet-desk` | app | Stable | `0.2.6` | Wallet + Config + balance HTTP + projection SOL/USD auxiliaire |
| Wallet V2 | `ksp-wallet-lib` | lib | Stable | `0.2.6` | wire/runtime V2 + API default/versionnée + migration explicite |
| Standard WS | `ksp-onchain-transport-lib` | lib | Stable | `0.2.7` | WebSocket Solana 18/18, sessions/subscriptions bornées |
| Helius WS | `ksp-onchain-transport-lib` | lib | Stable | `0.2.8` | LaserStream WS : 7 standard + transaction, actor partagé |
| Yellowstone | `ksp-onchain-transport-lib` | lib | Stable | `0.2.9` | client gRPC standard/provider-neutral |
| Off-chain price | `ksp-offchain-transport-lib` | lib | Stable | `0.2.11` | prix SOL/USD multi-provider, limits et availability |
| SOL Prices Desk | `ksp-app-solprices-desk` | app | Stable | `0.2.12` | HID provider-agnostic pour visualisation/refresh prix |
| Interface passive | `ksp-interface-lib` | lib | Stable | `0.2.13` | façade wire + contrats passifs partagés, dont événements acquisition provider-neutral |
| Program API | `ksp-program-api` | API | Stable | `0.2.14` | contrats extensibles Program |
| Program impl. | `ksp-program-lib` | lib | Retenu | vertical slices ultérieurs | implementations Program officielles |
| Program extension | `ksp-program-<name>-lib` | lib externe | À la demande | dès besoin | implementation externe de `ksp-program-api` |
| Store API | `ksp-store-api` | API | Stable | `0.3.1`, extension `0.3.16` | RAW transaction/account, observations ; variantes/conflits/résolutions ajoutés sans backend leak |
| Store runtime | `ksp-store-lib` | lib | Stable | `0.3.2``0.3.4`, `0.3.16` | façade backend-neutral ; convergence, retry et résolution RAW partagés entre producteurs |
| Store PostgreSQL | `ksp-store-postgres-lib` | lib | Stable | `0.3.2``0.3.4`, `0.3.16` | backend référence ; variantes conflictuelles et historique de résolution atomiques en `0.3.16` |
| Job lifecycle | `ksp-job-api` | API | Implémenté | `0.3.6` | identité/lifecycle/annulation/notifications latest-value runtime-neutral |
| Backfill | `ksp-job-backfill-lib` | lib | Implémenté | `0.3.6`, extension `0.3.17` | première verticale HTTP puis extension multi-route/historique sur convergence Store partagée |
| Backfill Desk | `ksp-app-backfill-desk` | app | Implémenté | `0.3.7`, extension `0.3.18` | contrôle du backfill RAW ; sélection/supervision multi-route adaptée au Job `0.3.17` |
| Store Desk | `ksp-app-store-desk` | app | Implémenté | `0.3.8`, extension `0.3.16` | inspection RAW + vues conflits/variantes/historique et résolution manuelle réversible |
| RAW transaction common | `ksp-raw-transaction-lib` | lib | Implémenté | `0.3.10` | canonicalisation/wire RAW Transaction v1 source-neutral partagé entre producteurs |
| Worker lifecycle | `ksp-worker-api` | API | Implémenté | `0.3.9` | lifecycle/health/progression génériques des services continus |
| RAW transaction worker | `ksp-worker-raw-transaction-ingest-lib` | worker/lib | Implémenté | `0.3.11``0.3.16` | live multi-route ; `0.3.16` sépare défaut transport et conflits RAW locaux durablement gérés |
| RAW ingest Desk | `ksp-app-raw-transaction-ingest-desk` | app | Retenu | `0.3.15` | choix/supervision dune ou plusieurs sources/méthodes sans réimplémenter le worker |
| STRUCTURAL job | nom à fixer | job/lib | Retenu | couche STRUCTURAL | normalisation Solana générique RAW -> STRUCTURAL bornée/rejouable |
| STRUCTURAL worker | nom à fixer | worker/lib | Retenu | fin couche STRUCTURAL | backlog RAW -> STRUCTURAL continu |
| Materializer API | `ksp-materializer-api` | API | Retenu | premier groupe DECODED | contrats extensibles matérialisation |
| Materializer impl. | `ksp-materializer-lib` | lib | Retenu | premier groupe DECODED | implementations officielles communes |
| Execution policy | `ksp-execution-policy-api` | API | Retenu | premier vrai besoin execution | décision/safety multi-contexte |
| Execution orchestration | `ksp-execution-lib` | lib | Retenu | premier vrai cycle execution | Program + policy + Wallet + transport |
| Scenarios | `ksp-scenario-<domain>-lib` | lib | Retenu | vertical slices | validation métier/devnet par groupe |
| Scenario API | `ksp-scenario-api` | API | Non retenu | — | norme souple avant trait commun |
| Market Desk | `ksp-app-market-desk` | app | Pressenti | après Meteora/Raydium/Pump/Orca | tokens, pools, trades, liquidity, price, OHLC |
| Trading Intelligence | noms à définir | libs/jobs | Pressenti | après données stables | features/signaux/anomalies/ML |
## Contrats séparés retenus

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md -->
<!-- version: 20 -->
<!-- version: 21 -->
# Acquisition, workers, jobs et pipelines spécialisés
@@ -90,7 +90,7 @@ Le job :
Le caller desktop spécialisé actuel est `ksp-app-backfill-desk`. Il compose Config, le pool HTTP et Store, puis remet ces ressources au runtime Backfill. Il peut retenir le checkpoint terminal uniquement en mémoire Rust pour un Resume in-session ; cette rétention applicative ne transforme pas le checkpoint en garantie de reprise durable après redémarrage.
Cette verticale `0.3.6`/`0.3.7` est **la première stratégie de backfill**, pas la définition générale du backfill KSP. Son discovery `getSignaturesForAddress` + hydration `getTransaction` est HTTP parce que cette méthode a été choisie pour le premier vertical slice. Après stabilisation du worker live et de sa Desk, `0.3.16` doit réauditer `ksp-job-backfill-lib` et `ksp-app-backfill-desk` pour intégrer les autres stratégies historiques/catch-up pertinentes identifiées par l'audit RAW Transaction de `0.3.9`.
Cette verticale `0.3.6`/`0.3.7` est **la première stratégie de backfill**, pas la définition générale du backfill KSP. Son discovery `getSignaturesForAddress` + hydration `getTransaction` est HTTP parce que cette méthode a été choisie pour le premier vertical slice. Après stabilisation du worker live et de sa Desk, `0.3.16` ferme d'abord la résilience RAW partagée : divergences compatibles, variantes conflictuelles durables, résolution/restauration canonique, retry Store et reconnexion Transport. `0.3.17` réaudite ensuite `ksp-job-backfill-lib` pour intégrer les autres stratégies historiques/catch-up pertinentes identifiées par l'audit RAW Transaction de `0.3.9`, puis `0.3.18` adapte `ksp-app-backfill-desk` au Job multi-route.
### Worker RAW Transaction live

View File

@@ -1,5 +1,5 @@
<!-- file: docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md -->
<!-- version: 16 -->
<!-- version: 17 -->
# Acquisition et alimentation `RawTransaction`
@@ -869,7 +869,30 @@ settings techniques nécessaires
Elle peut activer plusieurs providers/endpoints simultanément. Les secrets restent Config-owned, avec réutilisation unique de `KSP_SECRET_HELIUS_API_KEY` pour les surfaces Helius concernées.
## 15. Handoff `0.3.16` : Job Backfill multi-stratégie
## 14.5 Handoff `0.3.16` : résilience RAW et conflits durables
`0.3.16` doit déplacer la résolution des divergences RAW dans le contrat Store partagé, afin que Worker live et futurs Jobs historiques convergent avec la même politique. Une divergence de contenu n'est plus assimilée automatiquement à une panne d'acquisition.
Modèle cible :
```text
RawTransaction identity (network, signature)
-> canonical_variant
-> 1..N variantes de contenu durables
-> observations/provenances rattachées à la variante réellement observée
-> conflict case éventuel
-> historique immutable des promotions/résolutions
```
Classification minimale : `Exact`, `CompatibleLessComplete`, `CompatibleMoreComplete`, `Conflict`. Une représentation prouvée moins complète ne remplace jamais le canonique ; une représentation prouvée plus complète peut le promouvoir atomiquement ; un vrai conflit conserve toutes les variantes sans arrêter l'acquisition. La provenance d'un provider n'établit jamais à elle seule une priorité canonique.
Le Worker doit distinguer les problèmes locaux durablement gérables des pannes externes. Un conflit RAW quarantiné laisse la route active et rend la santé au plus `Degraded`. Une indisponibilité Store impose backpressure/pause et retry sans perte silencieuse. Une indisponibilité Transport déclenche une politique de reconnexion bornée/configurable (`initial_delay`, `max_delay`, backoff, `max_attempts`, reset après stabilité). Un terminal `Faulted` reste réservé aux erreurs irréconciliables ou à l'épuisement explicite d'une politique de retry/reconnect.
`ksp-app-store-desk` doit ajouter des vues de conflits/variantes et d'historique. Une résolution manuelle peut promouvoir une variante, conserver le canonique, ou produire une variante de fusion assistée. Toute ancienne valeur canonique reste une variante durable et peut être restaurée ultérieurement ; aucun `UPDATE` destructif ne doit rendre une décision manuelle irréversible.
Le détail de handoff est fixé dans `docs/plans/037-V0_3_16_RAW_RESILIENCE_CONFLICT_HANDOFF.md`.
## 15. Handoff `0.3.17` : Job Backfill multi-stratégie
Le Job doit conserver son vertical slice existant puis ajouter des stratégies historiques choisies selon requête + capabilities + configuration.
@@ -901,10 +924,10 @@ Ordre conseillé :
0.3.13 P1 : multi-source convergence, dedup, provenance, content conflict, backpressure/fairness
0.3.13 P2 : health source-neutral, shutdown/races, completeness/security et gate live keyless
0.3.14 : trajectoire suivante définie par son prompt dédié ; ne pas réintroduire implicitement un scope reporté
0.3.16 P0 : block scan historique
0.3.16 P0 : replay Yellowstone borné
0.3.16 P1 : provider history/archive
0.3.16 P1 : Old Faithful
0.3.17 P0 : block scan historique
0.3.17 P0 : replay Yellowstone borné
0.3.17 P1 : provider history/archive
0.3.17 P1 : Old Faithful
plus tard : substrats directs et sources vendor-specific sans accès actuel
```
@@ -1026,7 +1049,9 @@ TR-C2 = adapter productif Transport DTO -> common réserv
0.3.11 = fondation Worker source-neutral, persistence et observabilité
0.3.12 = première verticale Yellowstone + hydration/replay continuity
0.3.13 = cinq familles live + convergence/fairness/health/shutdown/completeness
0.3.16 = Job Backfill multi-stratégie historique
0.3.16 = résilience RAW, variantes/conflits/résolutions, retry/reconnect et Store Desk
0.3.17 = Job Backfill multi-route/multi-stratégie historique
0.3.18 = Backfill Desk multi-route
```
`0.3.9` n'implémente aucune nouvelle stratégie d'acquisition. Il ferme l'architecture et l'inventaire nécessaires aux releases suivantes.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/002-FUNCTIONAL_RELEASE_SEQUENCE.md -->
<!-- version: 100 -->
<!-- version: 101 -->
# Séquence des releases fonctionnelles KSP
@@ -587,7 +587,9 @@ La séquence effective a évolué par sizing et validation réels. La référenc
0.3.13 cinq familles live + convergence multi-source/fairness/health/hardening
0.3.14 tranche suivante de la trajectoire RAW selon prompt dédié
0.3.15 ksp-app-raw-transaction-ingest-desk
0.3.16 Backfill multi-source / multi-stratégie
0.3.16 RAW resilience / conflict variants / Store Desk conflict management
0.3.17 ksp-job-backfill-lib multi-route / multi-stratégie
0.3.18 ksp-app-backfill-desk adapté au Backfill multi-route
```
Cette série ferme la couche RAW et ses outils d'exploitation avant l'ouverture fonctionnelle de STRUCTURAL. Le Worker live RAW reste distinct des jobs historiques et ne constitue pas encore une transformation RAW -> STRUCTURAL.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/031-V0_3_10_RAW_TRANSACTION_INGEST_PLAN.md -->
<!-- version: 14 -->
<!-- version: 15 -->
# Plan v0.3.10 — RAW Transaction commune + qualification cross-source
@@ -1084,9 +1084,17 @@ Nouvelle release/session : replay natif, source redondante, scan HTTP blocs, hyd
Ancienne cible `0.3.11`, décalée après finalisation complète du Worker.
### `0.3.16` — Backfill multi-source/multi-stratégie
### `0.3.16` — RAW resilience / conflict management
Ancienne cible `0.3.12`, décalée sans changer la frontière Job historique paramétré / Worker live.
Nouvelle tranche intercalée après le live `0.3.15` : variantes RAW durables, résolution automatique des représentations partielles prouvées, quarantaine des vrais conflits, historique de promotion/résolution, retry Store, reconnexion Transport configurable et vues de gestion dans Store Desk.
### `0.3.17` — Backfill multi-route/multi-stratégie
Ancienne cible Backfill multi-source, décalée sans changer la frontière Job historique paramétré / Worker live.
### `0.3.18` — Backfill Desk multi-route
Adapter `ksp-app-backfill-desk` au Job `0.3.17` en réutilisant les patterns de composition/supervision du Raw Transaction Ingest Desk sans dupliquer la logique Worker.
### Note durable de génération des prompts `0.3.12` à `0.3.15`
@@ -1169,7 +1177,7 @@ Les smokes live restent séparés et opt-in.
```text
ksp-app-raw-transaction-ingest-desk # 0.3.15
nouvelles stratégies historiques Backfill # 0.3.16
nouvelles stratégies historiques Backfill # 0.3.17
paramètres métier historiques dans Worker
Backfill checkpoint dans Worker
RawAccountState ingest worker

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md -->
<!-- version: 22 -->
<!-- version: 23 -->
# Plan v0.3.15 — Raw Transaction Ingest Desk
@@ -956,3 +956,16 @@ La cause est la même pour les deux routes et se situe dans le drain Worker comm
Le fault Yellowstone Devnet observé dans le même gate reste distinct : OrbitFlare répond `onchain_transport.grpc_status` avec refus de permission dès louverture du Subscribe, avant toute demande de Stop. Il nest pas reclassé par ce correctif.
## 23. Handoff durable après `pre.014-fix.001`
Le diagnostic inter-provider de `pre.014` et sa correction minimale `fix.001` ouvrent une évolution Store/Worker qui ne doit pas être absorbée par `0.3.15`. Le cas démontré de `logMessages` tronqués est fermé localement, mais la politique générale de divergence durable est réservée à `0.3.16`.
Trajectoire retenue :
```text
0.3.16 RAW resilience + conflict variants/resolution + Store Desk conflicts
0.3.17 ksp-job-backfill-lib multi-route / multi-stratégie
0.3.18 ksp-app-backfill-desk adapté au Job multi-route
```
Le contrat complet de handoff est enregistré dans `docs/plans/037-V0_3_16_RAW_RESILIENCE_CONFLICT_HANDOFF.md`. La préparation de publication `0.3.15` doit générer le prompt `0.3.16` depuis ce handoff et non depuis l'ancienne cible Backfill historique.

View File

@@ -0,0 +1,178 @@
<!-- file: docs/plans/037-V0_3_16_RAW_RESILIENCE_CONFLICT_HANDOFF.md -->
<!-- version: 1 -->
# Handoff v0.3.16 — RAW resilience, variantes et gestion des conflits
## 1. Origine de la version
Le live `0.3.15-pre.014` a démontré qu'une même transaction du même bloc peut être renvoyée avec une qualité de représentation différente selon le nœud RPC. Le cas observé n'était pas un fork : même slot, même identité de bloc, même transaction et mêmes métadonnées hors `logMessages`. Une acquisition contenait les logs complets ; l'autre contenait un marqueur `Log truncated`.
`0.3.15-pre.014-fix.001` ferme uniquement le cas où la version complète est déjà canonique et où une version tronquée strictement compatible arrive ensuite. La généralisation ci-dessous appartient à `0.3.16`.
## 2. Principe directeur
```text
une divergence de données != une panne d'acquisition
```
Le pipeline ne doit plus arrêter un Worker simplement parce qu'un N-ième RAW d'identité `(network, signature)` diffère du canonique. Store doit d'abord classifier la divergence, préserver les données et seulement exposer un conflit durable lorsqu'aucune convergence automatique sûre n'est démontrée.
Un provider n'est jamais déclaré « toujours correct ». La préférence porte sur la qualité prouvée de la représentation, indépendamment de l'ordre d'arrivée et de la provenance.
## 3. Classification de convergence
Le comparateur partagé vise au minimum :
```text
Exact
CompatibleLessComplete
CompatibleMoreComplete
Conflict
```
Règles :
- `Exact` : contenu canonique identique ; observation idempotente/nouvelle ;
- `CompatibleLessComplete` : conserver le canonique plus complet et l'observation entrante ;
- `CompatibleMoreComplete` : promotion atomique vers la représentation plus complète, sans détruire l'ancienne variante ;
- `Conflict` : conserver le canonique courant, conserver intégralement la variante entrante et ouvrir/compléter un dossier de conflit.
La comparaison est champ-spécifique. Il est interdit d'utiliser une règle générique « valeur la plus longue gagne ». `logMessages` peut utiliser une relation de troncature explicitement prouvée ; les autres champs ne deviennent enrichissables que lorsque leur contrat permet de distinguer absence informationnelle et contradiction.
## 4. Modèle Store cible
Le modèle conceptuel devient :
```text
RawTransaction identity (network, signature)
|
+-- Variant A <- canonical current
| +-- observations/provenances
|
+-- Variant B
| +-- observations/provenances
|
+-- Variant C
+-- observations/provenances
Conflict case
+-- status
+-- canonical variant
+-- classification
+-- resolution history
```
Les noms physiques exacts restent à décider en `0.3.16-pre.001`, mais les responsabilités doivent couvrir : identité canonique, variantes de contenu, observations rattachées à la variante réellement reçue, dossier de conflit et historique de résolution/promotion.
Une résolution ou promotion n'efface jamais l'ancienne valeur canonique. Un `A -> B` doit pouvoir être suivi plus tard d'un `B -> A` sans reconstruire les bytes depuis une source externe.
## 5. Résolution automatique
Le cas `logMessages` sert de première preuve :
```text
FULL + TRUNCATED compatible
-> garder FULL
TRUNCATED + FULL compatible
-> promouvoir FULL
TRUNCATED A + TRUNCATED B compatibles
-> promouvoir uniquement si la relation de qualité est formellement démontrée
```
Les champs scalaires présents avec des valeurs différentes restent des conflits. Les listes ne sont jamais fusionnées par longueur seule. Une absence peut devenir enrichissable uniquement si le contrat RPC/source prouve que l'absence signifie « non fourni » et non une valeur métier différente.
## 6. Conflit durable et santé Worker
Un conflit durablement quarantiné n'est pas terminal :
```text
content conflict
-> variant persisted
-> conflict case unresolved
-> Worker Running
-> health Degraded
```
Les snapshots doivent pouvoir exposer au minimum des compteurs source-neutral et sans identité métier, par exemple `unresolved_content_conflict_count`, `auto_resolved_conflict_count` et `canonical_promotion_count`. Les signatures, payloads et variantes restent Store-owned.
La complétude doit distinguer :
```text
acquisition_complete
= toute donnée attendue est durablement capturée, variantes comprises
canonical_complete
= aucune obligation de réconciliation canonique n'est ouverte
```
Un conflit non résolu ne doit pas bloquer l'acquisition des autres transactions. Le passage RAW -> STRUCTURAL décidera séparément comment traiter une identité encore conflictuelle.
## 7. Store indisponible, retry et backpressure
Un Store temporairement indisponible est différent d'un content conflict. Le Worker ne doit ni perdre silencieusement les données ni continuer à consommer indéfiniment sans durabilité.
Le contrat `0.3.16` doit prévoir une politique Store bornée : pause/backpressure des admissions, retry, délais/backoff configurables dans la couche propriétaire appropriée, observabilité `Degraded/Blocked`, puis terminal seulement si la politique explicite est épuisée ou si l'erreur est structurellement irréconciliable.
## 8. Reconnexion Transport
La reconnexion Transport doit être explicitement configurable et distincte de la politique Store. Paramètres conceptuels à auditer en `pre.001` :
```text
initial_delay
max_delay
backoff_multiplier
max_attempts
reset_after_stable_duration
jitter borné si retenu
```
Une perte de connexion ne doit pas provoquer un arrêt immédiat tant que la politique de reconnexion n'est pas épuisée. Les gaps éventuels continuent à utiliser les mécanismes de continuité/repair du Worker ; aucune reconnexion ne vaut preuve de couverture.
## 9. `ksp-app-store-desk`
`0.3.16` étend Store Desk avec une ou plusieurs vues dédiées, au minimum autour de deux responsabilités : conflits ouverts et historique de résolution.
Pour une identité, l'UI doit pouvoir présenter le canonique, les variantes, leurs différences structurées et leurs provenances sans charger arbitrairement tout le RAW dans les tables. Actions visées : promouvoir une variante, conserver le canonique et résoudre, fusion assistée uniquement pour des champs dont la compatibilité est définie, rouvrir/restaurer une résolution antérieure.
Une fusion manuelle produit une nouvelle variante explicitement marquée comme synthétique/manuelle avec ses parents ; elle ne prétend jamais être une observation provider native. Aucune action utilisateur ne doit rendre les anciennes variantes irrécupérables.
## 10. Frontières de crates
```text
ksp-store-api
-> DTO/contrats backend-neutral variantes, conflits, résolutions
ksp-store-lib
-> façade unique et moteur de convergence exposé aux producteurs
ksp-store-postgres-lib
-> atomicité physique, schema/migrations, variantes et historique
ksp-worker-raw-transaction-ingest-lib
-> continue sur conflits locaux durables, retry/reconnect selon contrats existants
ksp-app-store-desk
-> inspection/résolution via ksp-store-lib uniquement
```
Aucun Worker ou Job ne dépend directement du backend PostgreSQL. Le moteur de convergence est partagé afin que les futurs producteurs n'implémentent pas chacun leur propre arbitrage.
## 11. Versions suivantes
La trajectoire retenue est désormais :
```text
0.3.16 RAW resilience / conflict variants / Store Desk conflict management
0.3.17 ksp-job-backfill-lib multi-route / multi-stratégie
0.3.18 ksp-app-backfill-desk adapté au Job multi-route
```
`0.3.17` conserve le Job borné et paramétré, mais lui permet de composer plusieurs routes/stratégies d'acquisition sur la même convergence Store `0.3.16`. Il ne dépend pas du Worker.
`0.3.18` adapte le Desk Backfill à ce Job : inventaire/composition de routes, sélection, supervision, progression et résultats, en réutilisant les patterns applicatifs prouvés par `ksp-app-raw-transaction-ingest-desk` sans dupliquer la logique métier du Job.
## 12. Hors périmètre de `0.3.15-pre.014-fix.001`
Le fix courant ne crée aucune table de variante, ne promeut pas un canonique tronqué vers une version plus complète, ne modifie pas le health model Worker, n'ajoute pas de retry Store et ne change pas la politique de reconnexion Transport. Il ferme seulement le cas live démontré où une observation entrante tronquée et strictement compatible arrive après un canonique complet.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
<!-- version: 28 -->
<!-- version: 29 -->
# Validation v0.3.15 — Raw Transaction Ingest Desk
@@ -960,3 +960,29 @@ incoming_prefix_of_stored=true ou stored_prefix_of_incoming=true
```
Non-claims : `pre.014` ne retire pas `logMessages` du contenu canonique, ne choisit aucun provider comme vérité, ne transforme pas `content_conflict` en succès, ne modifie pas le schema Store et n'expose aucun nouveau type public Worker/Store.
### `pre.014-fix.001` — observation `logMessages` tronquée compatible non terminale
Le live `pre.014` ferme le diagnostic du conflit Mainnet observé au slot `447781296`. HTTP Block Polling et Yellowstone Block Hydration ont produit la même identité de bloc (`parent_slot=447781295`, `block_height=425822496`, même fingerprint), la même transaction, le même index et les mêmes autres métadonnées. La seule divergence est `meta.logMessages`.
Le canonique déjà stocké contient `176` lignes sans marqueur de troncature. L'acquisition entrante contient `118` lignes et un marqueur exact `Log truncated` au premier point divergent. Le diagnostic prouve que toutes les lignes antérieures à ce marqueur sont identiques. Le défaut n'est donc ni un fork ni un changement de transaction : c'est une représentation RPC explicitement tronquée du même résultat d'exécution.
`fix.001` ajoute une compatibilité volontairement asymétrique et étroite dans le backend PostgreSQL :
```text
canonique déjà complet
+ entrant explicitement tronqué et moins complet au-delà du marqueur
+ mêmes network/signature/slot/block_time/format
+ mêmes transaction/version/transactionIndex
+ mêmes champs meta hors logMessages
+ un seul marqueur exact "Log truncated" côté entrant
+ préfixe avant marqueur identique
+ préfixe exact jusquau marqueur ; le matériel après le marqueur nest pas utilisé pour prouver la complétude
=> AlreadyPresent + observation persistée
=> aucun content_conflict
=> Worker continue
```
Le canonical RAW n'est jamais remplacé par la version tronquée. Les cas suivants restent des `content_conflict` en `0.3.15` : préfixe différent avant le marqueur, autre champ `meta` différent, marqueur non exact ou multiple, canonique déjà tronqué puis version plus complète entrante. Ce dernier cas nécessite une promotion canonique atomique et appartient explicitement à `0.3.16`, avec variantes durables et historique de résolution ; il n'est pas simulé par un overwrite opportuniste dans ce fix.
Le correctif ne change aucune API publique Store/Worker, aucun schema SQL et aucun outcome public. `RawEntityWriteOutcome::AlreadyPresent` reste l'outcome canonique, l'observation entrante est conservée normalement et le Worker ne reçoit plus d'erreur pour le cas compatible démontré.