v0.3.15-pre.018

This commit is contained in:
2026-09-19 12:40:04 +02:00
parent cd5c79c253
commit d32299ea18
5 changed files with 1032 additions and 5 deletions

View File

@@ -1,8 +1,20 @@
<!-- file: CHANGELOG.md --> <!-- file: CHANGELOG.md -->
<!-- version: 34 --> <!-- version: 35 -->
# Changelog KSP # Changelog KSP
## 0.3.15 — Raw Transaction Ingest Desk multi-route et fermeture live Mainnet — 2026-09-19
`0.3.15` livre `ksp-app-raw-transaction-ingest-desk` comme Desk Tauri KSP de composition et supervision des routes live `RawTransaction`. La Desk raisonne en routes complètes plutôt quen endpoints : une route nest composable que lorsque toutes ses capabilities Config/Transport requises existent sur le même réseau, puis le Start reconstruit les ressources backend et lance une instance `ksp-worker-raw-transaction-ingest-lib` indépendante par route sélectionnée. Plusieurs routes peuvent partager le même Store sans partager implicitement lifecycle, gaps, `TargetCoverage` ou réparation. Lapplication expose inventaire, Start/Stop ciblé, lifecycle, health, activité, backpressure, reconnect/replay, gaps/repair et compteurs sûrs sans déplacer Transport, Store ou logique dingestion dans le frontend.
Les cinq familles live du Worker sont composables selon les capacités réellement déclarées : Yellowstone hydraté, Standard Logs hydraté, Standard Block direct lorsquun `blockSubscribe` compatible existe, Helius Transaction hydraté et HTTP Block Polling. Sur Mainnet, Yellowstone/PublicNode est traité comme capability du réseau canonique `mainnet`, pas comme réseau séparé. Le chemin Yellowstone Block final utilise le stream gRPC comme déclencheur de bloc puis un HTTP `getBlock` `Full/Base64` avec `maxSupportedTransactionVersion = 1`, au lieu dun fan-out `getTransaction` par transaction. La queue dupdates Yellowstone reste bornée mais applique désormais une backpressure asynchrone vers le stream au lieu de transformer une saturation locale prolongée en `grpc_backpressure_overflow`; le Stop explicite accepte aussi comme fermeture coopérative un `Status` provider reçu après le half-close local, sans masquer un `grpc_status` sur session active.
Le live multi-provider a également révélé un cas de convergence RAW où deux acquisitions de la même transaction, du même slot et du même bloc différaient uniquement par `meta.logMessages`, PublicNode renvoyant un marqueur explicite `Log truncated`. Store journalise désormais des diagnostics bornés et sans matériau sensible, puis accepte le cas strictement prouvé **canonique complet déjà stocké + observation entrante tronquée compatible** comme observation supplémentaire sans remplacer le canonique ni arrêter le Worker. Cette exception reste volontairement asymétrique en `0.3.15` : un canonique tronqué nest pas encore promu automatiquement vers une version complète et toute autre divergence non prouvée conserve la sémantique `content_conflict`.
Le gate technique final `pre.016` passe format, audits Rust/Markdown, `cargo check --workspace`, Clippy workspace/all-targets/all-features avec `-D warnings`, les suites Store PostgreSQL, Transport, Worker, Raw Transaction Ingest Desk et le rejeu `cargo test --workspace --all-targets --all-features`, ainsi que les graphes Cargo et `cargo tree --duplicates`. `cargo tauri build` produit les trois bundles Linux `.deb`, `.rpm` et `.AppImage`. Le live de référence immédiatement antérieur fait tourner Yellowstone Mainnet et HTTP Block Polling environ dix-neuf minutes en parallèle sans `grpc_backpressure_overflow`, sans terminal `content_conflict` et sans route `Faulted`; les deux routes terminent ensuite `Stopped/Healthy`. La réconciliation documentaire `pre.017` repasse ensuite format, audits Rust/Markdown et `cargo check --workspace` sans réouvrir le runtime.
`prompts/035-V0_3_16_START_PROMPT.md` ouvre `0.3.16` exclusivement depuis le futur tag stable `v0.3.15`. Cette release est dédiée à la résilience RAW et à la gestion durable des conflits : variantes conservées, comparaison `Exact / CompatibleLessComplete / CompatibleMoreComplete / Conflict`, promotions réversibles, quarantaine non terminale des conflits, historique de résolution, Store retry/backpressure, reconnexion Transport configurable et nouvelles vues de `ksp-app-store-desk`. `0.3.17` reste réservé au Backfill multi-route/multi-stratégie et `0.3.18` à ladaptation de `ksp-app-backfill-desk`.
## 0.3.14 — gap repair et hardening multi-source du Worker RawTransaction — 2026-09-12 ## 0.3.14 — gap repair et hardening multi-source du Worker RawTransaction — 2026-09-12
`0.3.14` ferme `ksp-worker-raw-transaction-ingest-lib` par une continuité run-local explicite au-dessus des cinq familles live de `0.3.13`, sans transformer le Worker en moteur historique. Le Worker distingue désormais reconnect, tentative de replay, delivery de replay et preuve de coverage ; il maintient des gaps bornés avec plage inclusive, `TargetCoverage` conservative et frontier de continuité distincte de la processing frontier. Une reprise live ou l'acceptation d'un `from_slot` ne vaut jamais à elle seule preuve de réparation. `0.3.14` ferme `ksp-worker-raw-transaction-ingest-lib` par une continuité run-local explicite au-dessus des cinq familles live de `0.3.13`, sans transformer le Worker en moteur historique. Le Worker distingue désormais reconnect, tentative de replay, delivery de replay et preuve de coverage ; il maintient des gaps bornés avec plage inclusive, `TargetCoverage` conservative et frontier de continuité distincte de la processing frontier. Une reprise live ou l'acceptation d'un `from_slot` ne vaut jamais à elle seule preuve de réparation.

View File

@@ -1,12 +1,12 @@
# file: Cargo.toml # file: Cargo.toml
# version: 635 # version: 636
[workspace] [workspace]
resolver = "3" resolver = "3"
members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"] members = ["crates/ksp-app-backfill-desk", "crates/ksp-app-config-desk", "crates/ksp-app-raw-transaction-ingest-desk", "crates/ksp-app-solprices-desk", "crates/ksp-app-store-desk", "crates/ksp-app-wallet-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-interface-lib", "crates/ksp-job-api", "crates/ksp-job-backfill-lib", "crates/ksp-logging-lib", "crates/ksp-offchain-transport-lib", "crates/ksp-onchain-transport-lib", "crates/ksp-program-api", "crates/ksp-raw-transaction-lib", "crates/ksp-store-api", "crates/ksp-store-lib", "crates/ksp-store-postgres-lib", "crates/ksp-wallet-lib", "crates/ksp-worker-api", "crates/ksp-worker-raw-transaction-ingest-lib"]
[workspace.package] [workspace.package]
version = "0.3.15-pre.17" version = "0.3.15-pre.18"
edition = "2024" edition = "2024"
license = "MIT" license = "MIT"
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project" repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"

View File

@@ -1,5 +1,5 @@
<!-- file: ROADMAP.md --> <!-- file: ROADMAP.md -->
<!-- version: 113 --> <!-- version: 114 -->
# Roadmap KSP # Roadmap KSP
@@ -107,7 +107,7 @@ RAW -> STRUCTURAL -> DECODED -> DOMAIN
- [X] `0.3.12` — Première source live productive du Worker livrée : Yellowstone `Transaction`/`TransactionStatus`/`Block` vers signaux source-neutral, coalescence bornée puis hydration HTTP `getTransaction` observed avant Common RAW/Store ; `BlockMeta`/`Slot` restent continuity-only. Processing frontier run-local, reconnect/from_slot/ReplayInfo Transport-owned, compteurs source-neutral et fault sur gap de rétention prouvé sans Backfill automatique. Hardening duplicate/backpressure/stop/fault et canaris cross-layer fermés ; gate workspace complet vert, smokes live HTTP Devnet + WebSocket Devnet verts, Yellowstone token-gated/Worker end-to-end laissés explicitement non exécutés. - [X] `0.3.12` — Première source live productive du Worker livrée : Yellowstone `Transaction`/`TransactionStatus`/`Block` vers signaux source-neutral, coalescence bornée puis hydration HTTP `getTransaction` observed avant Common RAW/Store ; `BlockMeta`/`Slot` restent continuity-only. Processing frontier run-local, reconnect/from_slot/ReplayInfo Transport-owned, compteurs source-neutral et fault sur gap de rétention prouvé sans Backfill automatique. Hardening duplicate/backpressure/stop/fault et canaris cross-layer fermés ; gate workspace complet vert, smokes live HTTP Devnet + WebSocket Devnet verts, Yellowstone token-gated/Worker end-to-end laissés explicitement non exécutés.
- [X] `0.3.13` — Convergence live multi-source du Worker RAW livrée : composition caller-owned `1..32` sources dun même réseau, cinq familles Yellowstone / Standard Logs / Standard Block / Helius Transaction / HTTP Block Polling, hydration globale des trois voies reference-bearing, RAW-direct Legacy/V0/V1 pour les deux voies blocs, observations multiples, content conflict explicite, coalescence cross-source, fairness/backpressure/health source-neutral et shutdown hardening sans second actor Transport. Gate workspace complet vert (`1 850` PASS / `0` échec / `15` ignored) et smokes keyless HTTP + WebSocket Devnet verts ; les preuves provider/resource-gated non exécutées restent explicitement non revendiquées. - [X] `0.3.13` — Convergence live multi-source du Worker RAW livrée : composition caller-owned `1..32` sources dun même réseau, cinq familles Yellowstone / Standard Logs / Standard Block / Helius Transaction / HTTP Block Polling, hydration globale des trois voies reference-bearing, RAW-direct Legacy/V0/V1 pour les deux voies blocs, observations multiples, content conflict explicite, coalescence cross-source, fairness/backpressure/health source-neutral et shutdown hardening sans second actor Transport. Gate workspace complet vert (`1 850` PASS / `0` échec / `15` ignored) et smokes keyless HTTP + WebSocket Devnet verts ; les preuves provider/resource-gated non exécutées restent explicitement non revendiquées.
- [X] `0.3.14` — Gap repair/hardening multi-source du Worker RAW livré : gaps run-local bornés, distinction reconnect/replay/delivery/coverage, TargetCoverage conservative, coverage redondante prouvée, discovery HTTP bornée, known-reference hydration, réconciliation source-loss, health gap-aware, fairness nominal/repair, snapshots publics source-neutral et shutdown/drain renforcé. Le pipeline Common RAW/Store reste unique, Worker/Backfill restent indépendants, EARLY nest pas ajouté. Gate workspace complet vert (`1 931` PASS / `0` échec / `15` ignored) et smokes keyless HTTP + WebSocket Devnet verts ; preuves provider/resource-gated non provisionnées explicitement non revendiquées. - [X] `0.3.14` — Gap repair/hardening multi-source du Worker RAW livré : gaps run-local bornés, distinction reconnect/replay/delivery/coverage, TargetCoverage conservative, coverage redondante prouvée, discovery HTTP bornée, known-reference hydration, réconciliation source-loss, health gap-aware, fairness nominal/repair, snapshots publics source-neutral et shutdown/drain renforcé. Le pipeline Common RAW/Store reste unique, Worker/Backfill restent indépendants, EARLY nest pas ajouté. Gate workspace complet vert (`1 931` PASS / `0` échec / `15` ignored) et smokes keyless HTTP + WebSocket Devnet verts ; preuves provider/resource-gated non provisionnées explicitement non revendiquées.
- [ ] `0.3.15` Introduire `ksp-app-raw-transaction-ingest-desk`, Desk Tauri KSP de composition/supervision des routes live `RawTransaction`. Une route est une stratégie complète pouvant nécessiter plusieurs capabilities/endpoints (par exemple gRPC + HTTP ou WS + HTTP) et nest sélectionnable que si toutes ses requirements sont composables depuis Config sur le réseau choisi ; la présence dun provider ne vaut jamais capability implicite. Au Start, la Config est revalidée et **une instance Worker est lancée par route sélectionnée** — pas par source physique — afin de valider lopérabilité réelle puis exposer lifecycle, health, backpressure, reconnect/replay, gaps/repair et compteurs sûrs. Plusieurs Workers peuvent partager le même Store, sans coordination implicite de gaps entre routes. La Desk ne réimplémente ni Transport, discovery, hydration, déduplication, repair ni persistence. - [X] `0.3.15``ksp-app-raw-transaction-ingest-desk` livrée comme Desk Tauri KSP multi-route : composition capability-driven par réseau, une instance Worker indépendante par route sélectionnée, Store partagé, Start/Stop ciblé et supervision lifecycle/health/backpressure/reconnect/replay/gaps/repair sans réimplémenter Transport ni persistence. Les cinq familles live sont projetées selon les capacités réellement configurées ; Yellowstone Mainnet utilise le trigger gRPC Block + HTTP `getBlock` et applique une backpressure bornée sans overflow local prolongé. Le Stop Yellowstone post-half-close est coopératif, et Store accepte le cas strict `canonique complet + incoming logMessages explicitement tronqué compatible` sans remplacer le canonique ni arrêter le Worker. Gate workspace/Clippy/tests/graphes/bundles Linux vert et live Mainnet Yellowstone + HTTP polling denviron 19 minutes fermé `Stopped/Healthy`. La généralisation variantes/conflits/promotions/retry/reconnect reste explicitement `0.3.16`.
- [ ] `0.3.16`**RAW resilience / conflict management** : faire converger Store API/façade/PostgreSQL, Worker live et Store Desk autour de variantes RAW durables, résolution automatique `Exact / CompatibleLessComplete / CompatibleMoreComplete / Conflict`, quarantaine des conflits non résolus sans arrêt du Worker, historique réversible des promotions/résolutions, retry Store sans perte silencieuse et reconnexion Transport configurable/bornée. Une provenance provider n'est jamais une priorité canonique en soi ; la représentation prouvée la plus complète gagne. - [ ] `0.3.16`**RAW resilience / conflict management** : faire converger Store API/façade/PostgreSQL, Worker live et Store Desk autour de variantes RAW durables, résolution automatique `Exact / CompatibleLessComplete / CompatibleMoreComplete / Conflict`, quarantaine des conflits non résolus sans arrêt du Worker, historique réversible des promotions/résolutions, retry Store sans perte silencieuse et reconnexion Transport configurable/bornée. Une provenance provider n'est jamais une priorité canonique en soi ; la représentation prouvée la plus complète gagne.
- [ ] `0.3.17` — Étendre `ksp-job-backfill-lib` au **backfill multi-route/multi-stratégie** à partir de la matrice d'acquisition auditée en `0.3.9` et de la convergence Store `0.3.16`. Conserver `getSignaturesForAddress + getTransaction` comme première voie valide puis ajouter les stratégies historiques/catch-up réellement pertinentes sans edge Job ↔ Worker. - [ ] `0.3.17` — Étendre `ksp-job-backfill-lib` au **backfill multi-route/multi-stratégie** à partir de la matrice d'acquisition auditée en `0.3.9` et de la convergence Store `0.3.16`. Conserver `getSignaturesForAddress + getTransaction` comme première voie valide puis ajouter les stratégies historiques/catch-up réellement pertinentes sans edge Job ↔ Worker.
- [ ] `0.3.18` — Adapter `ksp-app-backfill-desk` au Job multi-route `0.3.17` : inventaire/composition de routes, sélection/supervision et progression sur le modèle structurel de `ksp-app-raw-transaction-ingest-desk`, sans réimplémenter la logique du Job. - [ ] `0.3.18` — Adapter `ksp-app-backfill-desk` au Job multi-route `0.3.17` : inventaire/composition de routes, sélection/supervision et progression sur le modèle structurel de `ksp-app-raw-transaction-ingest-desk`, sans réimplémenter la logique du Job.

217
deltas/0.3.15/pre.018.md Normal file
View File

@@ -0,0 +1,217 @@
<!-- file: deltas/0.3.15/pre.018.md -->
<!-- version: 1 -->
# Delta `0.3.15-pre.018` — préparation de publication
## 1. Base requise
```text
0.3.15-pre.017
workspace.package.version = 0.3.15-pre.17
```
Le gate opérateur communiqué le **19 septembre 2026 à 08:05** sur `pre.017` est propre :
```text
cargo fmt --all -- --check : PASS
General Rust rule audit : clean
Rust export completeness audit : 0 candidate(s)
KSP workspace Rust rule audit : clean
Markdown table audit : clean, 318 tables / 230 files
cargo check --workspace : PASS
```
Le gate `pre.016` avait déjà fermé la validation technique/live complète, les graphes Cargo et le build Tauri ; `pre.017` n'a modifié aucun runtime.
## 2. Objectif
`pre.018` est la dernière prerelease de préparation de publication de `0.3.15`.
Conformément à `VER-LIFECYCLE-003` et `PROMPT_STRUCTURE.md`, elle modifie fonctionnellement uniquement :
```text
prompts/035-V0_3_16_START_PROMPT.md
CHANGELOG.md
ROADMAP.md
```
Les seuls fichiers mécaniques supplémentaires sont :
```text
Cargo.toml racine
deltas/0.3.15/pre.018.md
```
Aucun README, USAGE, plan, validation, architecture, code, test, Config, schema, migration, dépendance, feature ou manifest de crate n'est rouvert.
## 3. Version workspace
La prerelease non-fix synchronise Cargo :
```text
0.3.15-pre.17
->
0.3.15-pre.18
```
Le header de `Cargo.toml` passe de `635` à `636`.
## 4. CHANGELOG
`CHANGELOG.md` reçoit l'entrée `0.3.15` synthétisant l'état réellement validé :
```text
Raw Transaction Ingest Desk multi-route capability-driven
1 Worker indépendant par route sélectionnée
Store partagé same-network
cinq familles live
Yellowstone Block gRPC trigger + HTTP getBlock
backpressure Yellowstone bornée sans overflow local terminal
Stop post-half-close coopératif
convergence étroite canonique complet + incoming logMessages tronqué compatible
gate technique final workspace/Clippy/tests/graphes/bundles Linux vert
live Mainnet Yellowstone + HTTP Block Polling ~19 min sans Faulted/overflow
handoff 0.3.16 variants/conflicts/retry/reconnect/Store Desk
```
La limitation de `0.3.15` reste explicite : aucune promotion automatique `TRUNCATED -> FULL`, aucune table durable de variantes/conflits, aucun historique de résolution général, aucun retry Store généralisé et aucune nouvelle politique configurable de reconnexion Transport ne sont revendiqués.
## 5. ROADMAP
L'entrée `0.3.15` passe de `[ ]` à `[X]` et décrit l'état réellement livré, y compris :
```text
Desk multi-route
Yellowstone Mainnet block trigger + getBlock
backpressure/shutdown corrigés
compatibilité logMessages tronqués strictement prouvée
live final Stopped/Healthy
```
Les entrées suivantes restent ouvertes et ordonnées :
```text
0.3.16 RAW resilience / conflict management
0.3.17 Backfill multi-route / multi-stratégie
0.3.18 Backfill Desk adapté
```
## 6. Prompt suivant
Le nouveau prompt :
```text
prompts/035-V0_3_16_START_PROMPT.md
```
ouvre `0.3.16` exclusivement depuis le futur stable/tag :
```text
v0.3.15
```
Il fixe notamment :
```text
divergence de données != panne d'acquisition
provider != autorité canonique
Exact / CompatibleLessComplete / CompatibleMoreComplete / Conflict
qualité comme ordre partiel, pas "longer wins"
variantes RAW durables
ancien canonique toujours récupérable
promotion atomique et historique réversible
conflit durable quarantiné non terminal
Worker Running + health Degraded sur conflit durable correctement persisté
acquisition_complete distinct de canonical_complete
Store retry/backpressure sans perte silencieuse
Transport reconnect configurable distinct du Store retry
Store Desk : conflicts/history/promote/keep/restore/reopen/merge assisté
fusion manuelle = nouvelle variante synthétique avec parents
aucun edge Job <-> Worker
0.3.17 et 0.3.18 restent hors périmètre
```
Le `pre.001` de `0.3.16` est obligatoirement un audit/sizing avant toute migration ou UI lourde. Il doit réauditer les sémantiques officielles `TransactionStatusMeta` et distinguer `absent`, `null`, `[]`, valeur présente, indisponibilité historique et contradiction avant de généraliser la complétude au-delà de `logMessages`.
## 7. Fichiers ajoutés
```text
prompts/035-V0_3_16_START_PROMPT.md
deltas/0.3.15/pre.018.md
```
## 8. Fichiers modifiés
```text
Cargo.toml
CHANGELOG.md
ROADMAP.md
```
## 9. Fichiers supprimés
```text
aucun
```
## 10. Surfaces explicitement inchangées
```text
README.md
RULES.md
docs/**
crates/**
config/**
prompts/001-* à prompts/034-*
deltas/0.3.15/pre.001.md à pre.017.md et leurs fixes
```
Aucun delta publié antérieur n'est modifié.
## 11. Validations exécutées localement
Sur l'état exact `pre.018` avant packaging :
```text
General Rust rule audit : clean
Rust export completeness audit : 0 candidate(s)
KSP workspace Rust rule audit : clean
Markdown table audit : clean, 318 tables / 232 files
prompt 035 : 18 sections numérotées présentes
scope pre.018 : exactement 2 fichiers ajoutés + 3 fichiers modifiés + 0 supprimé
Cargo.toml : hors header, seule workspace.package.version change
aucun README/USAGE/plan/validation/architecture/code/test/config/schema/dependency/feature modifié
```
La reconstruction byte-for-byte et `ZIP testzip` sont exécutés après ce contrôle et consignés dans la livraison.
Le toolchain Cargo/Rustfmt n'est pas disponible dans l'environnement d'assemblage. Aucun PASS Cargo post-bump n'est revendiqué localement ; le PASS Cargo d'entrée provient du gate opérateur `pre.017`.
## 12. Gate opérateur avant `rel.001`
Après application :
```bash
cargo fmt --all -- --check
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.15
cargo check --workspace
```
Aucun nouveau live ni build Tauri n'est requis par cette tranche de publication minimale. Un défaut découvert dans un couloir antérieur ne doit pas être absorbé dans `rel.001`.
## 13. Décisions prises
- `0.3.15` est techniquement et documentairement fermé avant publication ;
- `pre.018` ne rouvre aucun comportement ;
- `0.3.16` commence uniquement après `0.3.15-rel.001` validée et le tag stable `v0.3.15` ;
- la résilience `0.3.16` doit conserver les divergences au lieu d'arrêter l'acquisition lorsqu'elles sont durablement représentables ;
- une décision canonique repose sur la qualité prouvée, jamais sur le provider ;
- le Backfill multi-route reste `0.3.17` et le Backfill Desk adapté reste `0.3.18`.
## 14. Questions ouvertes
```text
aucune question bloquante pour la préparation de publication 0.3.15
les choix physiques exacts de schema/variants/conflicts appartiennent à 0.3.16-pre.001
```

View File

@@ -0,0 +1,798 @@
<!-- file: prompts/035-V0_3_16_START_PROMPT.md -->
<!-- version: 1 -->
# Prompt de démarrage `0.3.16` — RAW resilience, variantes, conflits et récupération
## 1. Identité de la release et base exacte requise
Ouvrir **uniquement** `0.3.16` depuis la release stable/taggée :
```text
v0.3.15
```
Ne pas démarrer depuis une prerelease intermédiaire `0.3.15-pre.*` ou depuis une archive de travail non taggée.
La première livraison attendue est :
```text
0.3.16-pre.001
```
`pre.001` est obligatoirement un gate de **lecture + audit Store/Worker/Transport/Config/Store Desk + audit des sémantiques RPC de complétude + brainstorming + sizing + planification**. Il est interdit de commencer directement par une migration PostgreSQL, par de nouvelles tables de conflit ou par l'UI Store Desk avant fermeture de ce gate.
## 2. Mission et résultat attendu
Faire évoluer KSP afin qu'une divergence RAW ou une indisponibilité locale récupérable ne soit plus confondue avec une panne irréversible d'acquisition.
Le résultat cible doit permettre :
```text
plusieurs producteurs/routes observent la même identité RAW
-> Store compare les représentations
-> Exact
ou CompatibleLessComplete
ou CompatibleMoreComplete
ou Conflict
Exact
-> idempotence / observation supplémentaire
CompatibleLessComplete
-> canonique plus complet conservé
-> observation conservée
-> acquisition continue
CompatibleMoreComplete
-> promotion atomique vers la variante plus complète
-> ancienne variante conservée
-> historique réversible
-> acquisition continue
Conflict
-> canonique courant conservé
-> variante entrante conservée intégralement
-> dossier de conflit durable ouvert/complété
-> Worker continue en état dégradé plutôt que Faulted
```
La release doit également introduire une politique explicite et bornée pour :
```text
Store temporairement indisponible
Transport temporairement indisponible / reconnexion
```
et étendre `ksp-app-store-desk` avec les vues et actions nécessaires à l'inspection/résolution/restauration des conflits RAW.
## 3. Principe directeur acquis
La règle centrale est :
```text
une divergence de données != une panne d'acquisition
```
Une provenance provider n'est jamais une autorité canonique en soi.
La décision canonique porte sur une **qualité de représentation prouvée**, indépendamment :
```text
de l'ordre d'arrivée
du provider
de la route productrice
du fait qu'une représentation est arrivée en premier
```
Aucune règle `first-provider-wins`, majorité provider, liste de providers prioritaires ou « Solana public a toujours raison » n'est admise.
## 4. Sources de vérité internes obligatoires — ordre de lecture
### 4.1 Gouvernance générale
Lire intégralement, dans cet ordre :
```text
RULES.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/rules/RULES_GENERAL.md
docs/rules/RULES_KSP.md
docs/rules/RULES_RUST.md
docs/rules/RULES_DEPENDENCIES.md
docs/rules/RULES_DOCUMENTATION.md
docs/rules/FILE_CONTRACTS.md
docs/rules/VERSION_WORKFLOW.md
docs/rules/PROMPT_STRUCTURE.md
```
Le présent prompt complète ces règles ; il ne les remplace pas.
Rappels bloquants :
```text
Rust 2024
unsafe interdit
unwrap / expect / panic interdits selon les règles KSP
retours explicites ; clippy::implicit_return deny
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
pas de pub mod
pub/pub(crate) partagés reexportés via crate root
accès partagés via crate::Item, y compris intra-crate
unit tests sous unit_tests/
integration tests sous tests/
```
### 4.2 Handoff stable `0.3.15`
Lire intégralement :
```text
prompts/034-V0_3_15_START_PROMPT.md
docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md
docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md
docs/plans/037-V0_3_16_RAW_RESILIENCE_CONFLICT_HANDOFF.md
deltas/0.3.15/pre.014.md
deltas/0.3.15/pre.014-fix.001.md
deltas/0.3.15/pre.015.md
deltas/0.3.15/pre.015-fix.001.md
deltas/0.3.15/pre.016.md
deltas/0.3.15/pre.017.md
deltas/0.3.15/pre.018.md
deltas/0.3.15/rel.001.md
```
Lorsque `rel.001.md` n'est pas encore présent dans l'archive fournie à l'ouverture de la session, **ne pas l'inventer** : vérifier d'abord que la base est bien le tag stable `v0.3.15` et utiliser le commit/tag comme autorité.
### 4.3 Store RAW
Lire et auditer réellement :
```text
crates/ksp-store-api/README.md
crates/ksp-store-api/USAGE.md
crates/ksp-store-api/src/
crates/ksp-store-api/tests/
crates/ksp-store-lib/README.md
crates/ksp-store-lib/USAGE.md
crates/ksp-store-lib/src/
crates/ksp-store-lib/tests/
crates/ksp-store-postgres-lib/README.md
crates/ksp-store-postgres-lib/USAGE.md
crates/ksp-store-postgres-lib/src/
crates/ksp-store-postgres-lib/tests/
crates/ksp-store-postgres-lib/unit_tests/
crates/ksp-store-postgres-lib/resources/
```
Auditer en particulier :
```text
RawTransaction / RawTransactionObservation
identité (network, signature)
content_hash et payload canonique
atomic insert canonical + observation
additional observation
content_conflict actuel
rétention Full / Archived / Purged / ForceRehydrate
inspection random-access Store Desk
migration registry V000/V001/V002 et règles de checksum
verrous / transactions / concurrence / cancellation
projection des erreurs backend vers store-lib/store-api
```
Ne pas casser les checksums des migrations stables existantes. Toute évolution physique est additive via une nouvelle migration/resource versionnée.
### 4.4 Common RAW et sémantique de comparaison
Lire :
```text
crates/ksp-raw-transaction-lib/README.md
crates/ksp-raw-transaction-lib/USAGE.md
crates/ksp-raw-transaction-lib/src/
crates/ksp-raw-transaction-lib/tests/
```
Le RAW v1 canonique et ses golden bytes/hash restent des contrats acquis. `0.3.16` ne doit pas redéfinir arbitrairement la canonicalisation pour faire disparaître les conflits.
Le moteur de qualité doit comparer des représentations réelles et conserver leurs variantes. Il ne doit pas masquer une contradiction en normalisant deux payloads réellement distincts vers une valeur artificielle.
### 4.5 Worker live et acquisition
Lire :
```text
crates/ksp-worker-api/
crates/ksp-worker-raw-transaction-ingest-lib/README.md
crates/ksp-worker-raw-transaction-ingest-lib/USAGE.md
crates/ksp-worker-raw-transaction-ingest-lib/src/
crates/ksp-worker-raw-transaction-ingest-lib/tests/
crates/ksp-worker-raw-transaction-ingest-lib/unit_tests/
docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md
docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md
```
Préserver les cinq familles live et le pipeline unique :
```text
Yellowstone hydrated
Standard Logs hydrated
Standard Block direct
Helius Transaction hydrated
HTTP Block Polling direct
Transport
-> Worker
-> ksp-raw-transaction-lib
-> ksp-store-lib
```
Le Worker et le Job Backfill restent des producteurs indépendants. `0.3.16` ne crée aucun edge `Worker -> Job` ni `Job -> Worker`.
### 4.6 Transport et Config
Lire :
```text
crates/ksp-onchain-transport-lib/README.md
crates/ksp-onchain-transport-lib/USAGE.md
crates/ksp-onchain-transport-lib/src/
crates/ksp-onchain-transport-lib/tests/
crates/ksp-config-lib/README.md
crates/ksp-config-lib/USAGE.md
crates/ksp-config-lib/src/
config/std.transport.json
config/examples/std.transport.example.json
config/schemas/std.transport.schema.json
```
Auditer les politiques de retry/reconnect déjà existantes avant d'ajouter de nouveaux réglages. Ne pas introduire une seconde politique concurrente si un contrat Transport peut être étendu proprement.
### 4.7 Store Desk
Lire :
```text
crates/ksp-app-store-desk/README.md
crates/ksp-app-store-desk/USAGE.md
crates/ksp-app-store-desk/src/
crates/ksp-app-store-desk/src/frontend/
crates/ksp-app-store-desk/tests/
crates/ksp-app-store-desk/package.json
```
Préserver les règles du gabarit Desk KSP :
```text
même architecture lib.rs exports-only / tauri.rs bridge / modules spécialisés
frontend Vite + TypeScript
tracing frontend des actions sans valeurs sensibles
DataTables serverSide lorsque pertinent
aucun SQL / backend PostgreSQL / endpoint / secret dans l'application
ksp-store-lib = seule façade Store consommée par la Desk
pas de npm run build comme gate manuel ; utiliser le workflow Tauri/Vite du projet
```
## 5. Sources externes normatives à réauditer en `pre.001`
La fraîcheur et la sémantique exacte importent. Réauditer les sources officielles actuelles avant de généraliser les règles de complétude :
```text
Solana / Agave RPC getTransaction et getBlock
TransactionStatusMeta / UiTransactionStatusMeta
sémantique de logMessages et du marqueur Log truncated
innerInstructions
loadedAddresses
returnData
computeUnitsConsumed
costUnits
preTokenBalances / postTokenBalances
rewards
champ absent vs null vs liste vide vs valeur présente
maxSupportedTransactionVersion
```
Lorsque nécessaire, vérifier aussi la source Agave/runtime responsable de la troncature des logs afin de prouver la relation exacte au lieu de déduire une règle à partir d'un seul provider.
Pour PostgreSQL, réauditer la documentation officielle des mécanismes réellement retenus pour :
```text
transactions
SELECT ... FOR UPDATE
UPSERT / ON CONFLICT
contraintes d'unicité
indexation
isolation / concurrence
DDL/migrations additives
```
Toute conclusion externe doit être traduite en canari KSP et documentée. Une hypothèse non prouvée reste fail-closed.
## 6. État validé de `0.3.15` à préserver
`0.3.15` fournit déjà :
```text
Raw Transaction Ingest Desk multi-route
1 Worker indépendant par route sélectionnée
Store partagé par plusieurs routes du même réseau
inventaire capability-driven
Start/Stop ciblé
monitoring lifecycle/health/activity/backpressure/reconnect/replay/gaps/repair
cinq familles live
```
Le live Mainnet de référence a validé Yellowstone + HTTP Block Polling environ dix-neuf minutes en parallèle, sans `grpc_backpressure_overflow`, sans route `Faulted`, puis avec Stop propre `Stopped/Healthy` pour les deux routes.
Yellowstone Block final :
```text
gRPC Block = trigger
include_transactions = false
HTTP getBlock = Full/Base64
maxSupportedTransactionVersion = 1
rewards = false
```
La saturation de la queue d'updates Yellowstone applique une backpressure bornée/asynchrone vers le stream au lieu d'un overflow local terminal. Un `Status` reçu après half-close local pendant un Stop explicite est traité comme fermeture coopérative ; le même `grpc_status` observé pendant une session active reste une vraie faute/reconnexion.
Store sait déjà accepter le cas étroit :
```text
canonique complet déjà stocké
+
incoming dont seule la liste logMessages est explicitement tronquée
+
relation de troncature strictement prouvée
=> observation acceptée
=> canonique inchangé
=> pas de content_conflict terminal
```
Le sens inverse n'est pas encore implémenté.
## 7. Décisions acquises pour les variantes RAW
Le modèle conceptuel cible est :
```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 sont à décider après audit `pre.001`, pas avant.
Une variante doit représenter une représentation effectivement reçue ou une variante synthétique explicitement marquée comme telle. Une promotion ne détruit jamais la variante précédemment canonique.
Exemple :
```text
A canonical
B alternate
promote B
=> A conservé
=> B devient canonical
=> historique A -> B
restore A plus tard
=> historique B -> A
=> aucune reconstruction externe nécessaire
```
## 8. Classification de convergence cible
Le comparateur partagé vise au minimum :
```text
Exact
CompatibleLessComplete
CompatibleMoreComplete
Conflict
```
Règles :
```text
Exact
-> contenu équivalent
-> observation idempotente ou supplémentaire
CompatibleLessComplete
-> incoming prouvé moins complet
-> canonique conservé
-> incoming/observation conservés selon le modèle retenu
CompatibleMoreComplete
-> incoming domine le canonique sans contradiction
-> promotion atomique
-> ancien canonique conservé comme variante
Conflict
-> aucun ordre de qualité sûr
-> canonique courant conservé
-> incoming conservé comme variante
-> dossier conflict durable
```
La qualité est une **relation partielle**, pas nécessairement un ordre total.
Si une représentation est plus complète sur un champ mais moins complète sur un autre, elle peut être `Incomparable` conceptuellement et doit rester fail-closed tant qu'aucune règle de fusion sûre n'existe.
Il est interdit de fabriquer automatiquement une représentation « best-of-fields » qui n'a été retournée par aucune source, sauf mécanisme de fusion explicitement défini, audité et marqué comme synthétique.
## 9. Politique champ par champ — prudence obligatoire
`logMessages` est le seul premier cas déjà démontré en live.
Pour tout autre champ, `pre.001` doit distinguer :
```text
absence informationnelle
absence structurelle / mode de sérialisation
null métier
liste vide métier
champ non disponible historiquement
champ dépendant de la version transaction/node
contradiction réelle
```
Ne jamais considérer automatiquement :
```text
absent == null
null == []
[] == valeur tronquée
valeur la plus longue == meilleure
provider X == vérité
```
Les scalaires présents avec deux valeurs différentes restent `Conflict` sauf contrat normatif contraire explicitement prouvé.
Les listes différentes restent `Conflict` sans relation formelle de préfixe/troncature/complétude propre à ce champ.
## 10. Conflits durables et santé Worker
Un conflit durablement stocké ne doit plus arrêter le Worker :
```text
content conflict
-> variant persisted
-> conflict case unresolved
-> acquisition continue
-> Worker Running
-> health Degraded
```
Le health model et les snapshots doivent rester source-neutral et redacted. Évaluer au minimum les compteurs conceptuels :
```text
unresolved_content_conflict_count
auto_resolved_conflict_count
canonical_promotion_count
```
Le nom final de chaque compteur appartient à l'audit/API design `pre.001`.
La complétude doit pouvoir distinguer :
```text
acquisition_complete
= les données attendues ont été durablement capturées, variantes comprises
canonical_complete
= aucune obligation de réconciliation canonique n'est ouverte
```
Un conflit sur une identité ne doit pas bloquer l'acquisition des autres identités.
Le futur RAW -> STRUCTURAL décidera séparément si une identité `canonical_complete=false` peut être matérialisée ; ne pas implémenter STRUCTURAL dans `0.3.16`.
## 11. Store retry et backpressure
Un Store indisponible n'est pas équivalent à un content conflict.
Le Worker ne doit jamais :
```text
continuer à consommer indéfiniment sans durabilité
jeter silencieusement les RAW
présenter une persistence échouée comme acquisition réussie
```
Auditer puis définir une politique Store bornée :
```text
classification transient / terminale
pause ou backpressure admission
retry borné ou illimité seulement si explicitement configuré
délai initial
backoff
max delay
budget/tentatives
reset après stabilité si pertinent
observabilité Degraded / Blocked
terminal uniquement sur politique épuisée ou erreur structurelle
```
La propriété essentielle est :
```text
pas de perte silencieuse
```
Si le Store bloque suffisamment longtemps pour saturer l'acquisition, la pression doit remonter de manière bornée/cohérente au lieu de créer une queue non bornée.
## 12. Reconnexion Transport configurable
La politique Transport est distincte de la politique Store.
Auditer les réglages existants pour HTTP, WebSocket et Yellowstone avant d'ajouter une surface commune ou spécialisée.
Paramètres conceptuels à étudier :
```text
initial_delay
max_delay
backoff_multiplier
max_attempts
reset_after_stable_duration
jitter borné
```
Une perte de connexion ne doit pas rendre le Worker terminal immédiatement tant que la politique de reconnexion autorise une reprise.
Inversement, une reconnexion n'est jamais une preuve de coverage : les gaps/replay/repair `0.3.14` restent responsables de la continuité.
## 13. `ksp-app-store-desk` — conflits et historique
Étendre Store Desk via `ksp-store-lib` uniquement.
Prévoir au minimum des surfaces autour de :
```text
RAW Conflicts
RAW Conflict History / Resolution History
```
Pour une identité conflictuelle, l'UI doit pouvoir présenter de manière bornée :
```text
variante canonique actuelle
variantes alternatives
différences structurées
provenances/observations
statut du conflit
historique des promotions/résolutions
origine native ou synthétique d'une variante
```
Actions visées, après audit des contrats :
```text
Promote variant
Keep current canonical + Resolve
Restore previous canonical
Reopen conflict
Assisted merge pour champs explicitement compatibles
```
Une fusion manuelle doit créer une nouvelle variante explicitement `manual/synthetic` avec ses parents. Elle ne modifie pas silencieusement une variante provider existante et ne prétend pas être une observation provider native.
Éviter un éditeur JSON libre comme mécanisme principal de résolution. Les actions doivent être structurées et typées autant que possible.
## 14. Frontières de crates et sécurité
Responsabilités cibles :
```text
ksp-store-api
DTO/contrats backend-neutral variantes, conflits, résolution, inspection
ksp-store-lib
façade unique consommée par Worker/Job/Desk
moteur de convergence backend-neutral seulement si cela respecte l'ownership audité
ksp-store-postgres-lib
schema/migrations/SQL/transactions/verrous/indexes
atomicité physique variantes/promotions/résolutions
ksp-worker-raw-transaction-ingest-lib
pipeline live
ne fault plus sur conflit durable correctement persisté
health/compteurs/retry orchestration selon ownership réel
ksp-onchain-transport-lib
reconnexion réseau et backpressure Transport
ksp-config-lib
configuration typée des politiques retenues
ksp-app-store-desk
inspection/résolution via ksp-store-lib uniquement
```
Interdictions :
```text
aucun SQL dans Worker/Desk
aucun backend PostgreSQL direct dans Worker/Job/Desk
aucune dépendance Job <-> Worker
aucun endpoint/token/signature/payload dans logs sûrs
aucune queue non bornée
aucun overwrite destructif d'une ancienne variante
aucune décision canonique par nom de provider
aucune baisse de qualité canonique automatique
```
Les opérations manuelles doivent être auditables. Une résolution doit conserver l'identité de l'action et son résultat sans exiger d'exposer de secret ou de payload arbitraire dans les logs.
## 15. Première mission `pre.001` — audit, brainstorming et sizing
Avant toute implémentation :
1. reconstruire/auditer la base stable `v0.3.15` et confirmer les gates de fermeture ;
2. inventorier exactement les APIs Store RawTransaction actuelles et les outcomes d'écriture ;
3. inventorier les tables/migrations PostgreSQL actuelles, clés, FK, index, contraintes, rétention et transactions ;
4. tracer le chemin actuel `Worker -> Store` lorsqu'un `content_conflict` survient ;
5. tracer les chemins d'erreur Store temporaire/terminal et la façon dont ils affectent admission/drain/health ;
6. inventorier toutes les politiques retry/reconnect Transport existantes et leurs propriétaires ;
7. inventorier les DTOs/queries Store Desk disponibles pour ajouter conflits/variantes sans bypass ;
8. réauditer les sémantiques officielles des champs `TransactionStatusMeta` avant toute règle de complétude hors `logMessages` ;
9. proposer au moins deux modèles physiques raisonnables pour variantes/conflits/résolutions, avec analyse atomicité/rétention/concurrence ;
10. décider si l'identité physique d'une variante repose sur `content_hash`, un id surrogate, ou une combinaison, sans confondre hash et preuve d'égalité ;
11. décider comment les observations se rattachent à la variante réellement reçue ;
12. décider comment `Full/Archived/Purged/ForceRehydrate` interagit avec les variantes et conflits ;
13. définir la machine d'état d'un conflict case et l'historique de résolution ;
14. définir le modèle de dominance/qualité et les cas `Exact/Less/More/Conflict/Incomparable` internes nécessaires ;
15. définir les métriques/health source-neutral ;
16. définir la politique Store retry et la politique Transport reconnect sans les mélanger ;
17. découper la release en prereleases réellement tenables dans le budget KSP ;
18. créer/réviser un plan dédié `0.3.16` et un document de validation avant l'implémentation lourde.
Le gate `pre.001` ne doit pas créer une migration finale « pour avancer ». Il peut créer des documents, tests de caractérisation et POC strictement nécessaires au choix architectural, conformément aux règles de la base.
Critères de sortie `pre.001` :
```text
modèle conceptuel validé
frontières de crates validées
migration strategy validée sans casser V000/V001/V002
sémantique de qualité logMessages prouvée
politique pour les autres champs explicitement conservative
Store retry ownership décidé
Transport reconnect ownership décidé
Store Desk scope décidé
risques/races/rétention identifiés
prévision souple des prereleases publiée
hors-périmètre explicite
```
## 16. Prévision souple initiale des prereleases
Cette prévision est un point de départ, à recalibrer en `pre.001`. Ne jamais fusionner artificiellement des tranches pour respecter ces numéros.
```text
pre.001 audit complet, sémantiques externes, modèles physiques, sizing et plan
pre.002 contrats Store API backend-neutral pour variantes/conflits/résolutions
pre.003 migration PostgreSQL additive + mapping backend des variantes/conflits
pre.004 moteur de comparaison/dominance, logMessages bidirectionnel et atomicité promotion
pre.005 persistence Conflict : quarantine durable, observations par variante, races/concurrence
pre.006 inspection Store API/lib des variants/conflicts/history + rétention/rehydration hardening
pre.007 Worker : conflit durable non terminal, health Degraded et compteurs source-neutral
pre.008 Store transient failure : retry/backpressure/blocked health sans perte silencieuse
pre.009 Transport reconnect configurable et Config associée, sans inventer de coverage
pre.010 Store Desk backend : queries/actions de conflits et résolutions
pre.011 Store Desk frontend : vues conflicts/history, promote/keep/restore/reopen
pre.012 fusion assistée/synthétique strictement bornée si les règles prouvées la permettent
pre.013 hardening cross-layer : concurrence, cancellation, retention, rollback, security/redaction
pre.014 preuves live PostgreSQL/Store + routes Worker sous conflits/retry/reconnect réellement testables
pre.015 gate technique/live final : workspace, graphes, bundles/smokes pertinents
pre.016 réconciliation documentaire finale
pre.017 préparation de publication : CHANGELOG + ROADMAP + prompt 0.3.17
rel.001 publication stable mécanique
```
Si `pre.001` démontre qu'une tranche intermédiaire dépasse le budget d'environ 1520 minutes de travail effectif, elle doit être scindée et les numéros suivants décalés. Les trois responsabilités finales restent dans l'ordre : technique/live -> documentation -> publication.
## 17. Hors périmètre de `0.3.16`
Ne pas inclure :
```text
0.3.17 : transformation de ksp-job-backfill-lib en moteur multi-route/multi-stratégie
0.3.18 : adaptation de ksp-app-backfill-desk au Backfill multi-route
RAW -> STRUCTURAL / persistence STRUCTURAL
DECODED / DOMAIN
majority voting provider
priorité canonique codée par provider
fusion libre de JSON arbitraire
reconstruction d'une variante perdue depuis Internet comme mécanisme normal de rollback
nouveau second pipeline d'acquisition
nouvelle dépendance Worker <-> Backfill
```
Le Job Backfill continue cependant à utiliser les contrats Store communs existants. Si la migration de schéma `0.3.16` exige une compatibilité mécanique pour que le Job actuel continue de fonctionner, cette compatibilité appartient naturellement à `0.3.16`; elle ne doit pas être confondue avec le multi-route `0.3.17`.
## 18. Versionnement, deltas, validation et instruction d'ouverture
Respecter strictement `docs/rules/VERSION_WORKFLOW.md`.
Chaque changement code/build/runtime/config bump la version workspace. Les deltas sont livrés comme archives minimales :
```text
ksp-general-0.3.16-pre.NNN.zip
ksp-general-0.3.16-pre.NNN-fix.NNN.zip
```
Les commandes de validation doivent être choisies selon la tranche et enregistrées dans son delta. Après toute modification Rust :
```bash
cargo fmt --all
cargo fmt --all -- --check
python3 scripts/audit_rust_workspace_rules.py
cargo check --workspace
cargo clippy --workspace --all-targets --all-features -- -D warnings
```
Pour tout Markdown touché :
```bash
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
```
Les tests ciblés doivent être préférés pendant le développement ; le workspace complet appartient aux gates appropriés. Les smokes/live PostgreSQL/provider sont uniquement revendiqués lorsqu'ils sont réellement exécutés avec les ressources correspondantes.
Pour les applications Desk, ne pas utiliser `npm run build` comme gate manuel. Le workflow Tauri/Vite du projet reste l'autorité, par exemple :
```bash
(cd crates/ksp-app-store-desk && cargo tauri dev)
(cd crates/ksp-app-store-desk && cargo tauri build)
```
Une commande non exécutée n'est jamais déclarée PASS.
### Instruction d'ouverture de la prochaine session
Commencer par :
```text
1. vérifier que la base est exactement le tag stable v0.3.15 ;
2. lire toutes les sources internes de la section 4 dans l'ordre ;
3. réauditer les sources externes de la section 5 ;
4. exécuter la mission pre.001 de la section 15 ;
5. publier le plan/sizing avant toute migration ou développement lourd.
```
Ne pas commencer par créer les tables `conflicts/variants`, modifier le Worker ou dessiner l'UI Store Desk avant d'avoir fermé le gate `pre.001`.
La release suivante envisagée après fermeture stable de `0.3.16` est :
```text
0.3.17 — ksp-job-backfill-lib multi-route / multi-stratégie
```