Files
khadhroony-solana-project/docs/plans/028-V0_3_7_BACKFILL_DESK_PLAN.md
2026-09-02 10:05:36 +02:00

22 KiB

Plan v0.3.7 — Backfill Desk

1. But de la version

La v0.3.7 crée ksp-app-backfill-desk, application Tauri spécialisée qui compose Config, Transport, Store et ksp-job-backfill-lib afin de lancer, observer, annuler et reprendre un backfill historique borné.

L'application reste une couche de composition et d'interface. Elle ne possède ni découverte RPC, ni retry/rate-limit, ni persistance, ni frontier/checkpoint, ni navigation Store générale.

Chaîne cible :

Config composite/profile
  -> Logging
  -> Transport HTTP
  -> Store
  -> AppState Rust
       -> BackfillRequest
       -> BackfillJobRuntime
       -> BackfillJobHandle
       -> BackfillSnapshotSource
  -> DTO Tauri sûrs
  -> UI latest-value

2. Base et audits de pre.001

Base autoritaire : archive stable v0.3.6, workspace.package.version = 0.3.6, avec deltas/0.3.6/rel.001.md, ksp-job-api, ksp-job-backfill-lib et les trois Desks existants.

Les deux archives ont été testées intégralement avant utilisation et extraites dans des arbres séparés. kbot3 reste une référence fonctionnelle/UX ; aucun code, DTO, commande Tauri ou algorithme n'en est repris.

Sources internes relues : règles racine et docs/rules/, architectures Layers/Dependencies/Components/Jobs/Apps, clôture complète de v0.3.6, surfaces Rust Job/Backfill/Config/Transport/Store et gabarits des Desks Config, Wallet et SOL Prices.

L'audit externe du 2026-09-02 confirme que le socle Tauri v2, son modèle capabilities/runtime authority et les versions courantes restent compatibles avec les contraintes existantes. Le workspace résout déjà tauri 2.11.5, tauri-build 2.6.3, tauri-plugin-tracing 0.3.4 et ts-rs 12.0.1; les manifests frontend utilisent @tauri-apps/api ^2.11, @tauri-apps/cli ^2.11, TypeScript ^7.0 et Vite ^8.2. Une version plus récente de Vite existe, mais aucun besoin fonctionnel ne justifie une mise à niveau en v0.3.7.

3. Surface Backfill réellement disponible

ksp-job-backfill-lib expose déjà les quatre scopes LatestAddress, BeforeAddress, AfterAddress et ExplicitSignatures, les commitments Confirmed/Finalized, les bornes publiques, BackfillRequest, BackfillCheckpoint, BackfillJobRuntime, BackfillJobHandle et BackfillSnapshotSource.

Le snapshot sûr expose phase, scope kind, boundary, candidats selected/admitted/finished, entities inserted/existing/purged, missing, conflicts, observations inserted/existing, cancelled candidates, holes, maximum in-flight, contiguous completed, présence d'un checkpoint et failure code. L'UI ne fabrique aucun pourcentage global lorsque le dénominateur n'est pas connu.

Bornes backend-owned :

Paramètre Borne publique
page size 1..=1000
max pages 1..=10000
max candidates 1..=10000
hydration concurrency 1..=64
signature Base58 64..=88 octets texte, validation Rust exacte

min_context_slot est admis pour les scopes adresse et rejeté pour ExplicitSignatures par BackfillRequest.

4. Matrice kbot3

Capacité historique Preuve fonctionnelle kbot3 Équivalent KSP v0.3.6 Décision
Formulaire de campagne demo_backfill.html + request TS/Rust BackfillRequest explicite et borné REPRENDRE FONCTIONNELLEMENT
Signatures explicites textarea + mode explicit_signatures BackfillScope::explicit_signatures REPRENDRE FONCTIONNELLEMENT
Adresse + direction address, anchor, before/after Latest/Before/After address distincts REDESSINER POUR KSP
Commitment sélecteur confirmed/finalized BackfillCommitment REPRENDRE FONCTIONNELLEMENT
Rôle logique rôle HTTP sélectionnable HttpRoleName + Transport REDESSINER POUR KSP
Provider/endpoint affichés options et summary Transport possède routage physique REJETER
Retry opérateur maxRetries UI Transport possède retry/pacing REJETER
Page size/max pages/limit inputs bornés constantes Backfill publiques REPRENDRE FONCTIONNELLEMENT
Concurrency input opérateur hydration_concurrency REPRENDRE FONCTIONNELLEMENT
Program/token/pool modes accordéons dédiés scopes génériques adresse/signatures REJETER comme types KSP
Progression live événements textuels + log snapshots latest-value structurés REDESSINER POUR KSP
Annulation bool atomique + commande BackfillJobHandle::cancel() REDESSINER POUR KSP
Résumé terminal payload summary notification/snapshot terminal REPRENDRE FONCTIONNELLEMENT
Compteurs inserted/existing/missing/failed/observations summary compteurs BackfillJobSnapshot REDESSINER POUR KSP
Cursor older-history resume_before_signature BackfillCheckpoint opaque REDESSINER POUR KSP
Reprise durable cursor texte retourné aucun checkpoint sérialisable public REPORTER
Single-run UI flag running runtime single-run + handle REPRENDRE FONCTIONNELLEMENT
Store browsing demo desktop monolithique futur Store Desk v0.3.8 REJETER

5. Screen map

Un seul écran principal responsive suffit en V1, en plus du splash commun.

main
├─ header : Backfill Desk + statut runtime/config
├─ readiness : profil composite, réseau, rôle(s) compatibles, Store/Transport ready
├─ campaign form
│  ├─ scope kind
│  ├─ address / anchor / signatures selon scope
│  ├─ commitment + rôle logique
│  └─ page size / max pages / max candidates / concurrency / min_context_slot
├─ active job
│  ├─ lifecycle + phase
│  ├─ boundary/frontier
│  ├─ compteurs structurés
│  ├─ checkpoint présent + contiguous completed
│  └─ Start / Cancel selon état
├─ terminal summary
│  ├─ outcome/lifecycle
│  ├─ failure code sûr
│  └─ Resume / New campaign selon checkpoint et scope
└─ diagnostics sûrs : codes, jamais secrets/URL/RAW

États UI explicites : booting, ready, starting, running, cancelling, completed, cancelled, failed, resume-ready. cancelling ne prétend jamais que la persistance déjà soumise est interrompue.

6. DTO et command map

Les DTOs sont possédés par l'application et dérivés TS-RS uniquement à cette frontière.

Élément Direction Contenu Validation / source de vérité Sensibilité
BackfillDeskOptionsDto Rust -> UI réseau, rôles compatibles, commitments, scopes, bornes, readiness Config + Transport + constantes Backfill sûre
BackfillStartRequestDto UI -> Rust scope inputs, commitment, rôle, bornes, optional min context slot conversion stricte vers types KSP métier borné
BackfillRunStatusDto Rust -> UI job state, phase, compteurs, boundary, checkpoint_present, contiguous_completed, failure code JobNotification<BackfillJobSnapshot> sûre
BackfillCancelResponseDto Rust -> UI accepted + état courant BackfillJobHandle sûre
BackfillResumeResponseDto Rust -> UI accepted/new job status checkpoint Rust détenu par AppState sûre
SafeAppErrorDto Rust -> UI domain/code + message app maîtrisé mapping applicatif sûre

Commandes prévues :

backfill_options() -> BackfillDeskOptionsDto
backfill_status() -> BackfillRunStatusDto
backfill_start(request) -> BackfillRunStatusDto
backfill_cancel() -> BackfillCancelResponseDto
backfill_resume() -> BackfillResumeResponseDto
backfill_reset() -> BackfillRunStatusDto

Le monitoring continu ne dépend pas du parsing de logs. Le backend possède un bridge latest-value qui attend JobSnapshotSource::wait_for_change, projette le snapshot et émet un événement Tauri borné, par exemple backfill-status-changed. backfill_status reste le chemin de resynchronisation initiale/explicite.

Aucun BackfillCheckpoint, Store, HttpTransportPool, sender/receiver Tokio ni payload RAW n'est sérialisé vers le frontend.

7. Config et composition

Le composite cible est config/composite.ksp-app-backfill-desk.json avec trois profils cohérents :

Profil composite Logging Transport Store Réseau
devnet supertrace devnet_public devnet devnet
mainnet console_info mainnet_public mainnet mainnet-beta
testnet console_info publicnode_testnet testnet testnet

Le default V1 est devnet, afin de ne pas lancer implicitement une campagne mainnet. Aucun std.job_backfill.json n'est créé : les paramètres de campagne restent opérationnels et backend-validés.

Au bootstrap, l'application charge le composite, résout Logging/Transport/Store via ksp-config-lib, construit HttpTransportPool et ouvre ksp_store_lib::Store. Elle compare le réseau Store au(x) cluster(s) HTTP activés et refuse le readiness si une composition mélange des réseaux.

Les rôles présentés à l'UI sont dérivés des snapshots/settings Transport, dédupliqués, puis validés côté Rust comme capables de sélectionner à la fois getSignaturesForAddress et getTransaction. Le rôle default est actuellement le seul rôle des profils standard, mais il n'est pas codé en dur comme contrat du Desk.

Le packaging Config suit le contrat atomique déjà détenu par ksp-config-lib::prepare_packaged_runtime() : il traverse l'intégralité de ConfigFileRegistry::defaults(). L'ajout du composite Backfill Desk fait donc passer le registre de 13 à 14 descriptors et impose que les quatre applications Desk qui utilisent ce packaging embarquent les 14 resources Config/schema du registre. Backfill Desk embarque ainsi également les documents Wallet/offchain sans les consommer au runtime ; leur présence satisfait le contrat de packaging partagé et n'ouvre aucune dépendance, permission frontend ou responsabilité métier supplémentaire.

8. Dependency map

Dépendances Rust normales envisagées :

ksp-app-backfill-desk
├─ ksp-core-lib              # erreurs, Pubkey/app DTO si requis
├─ ksp-logging-lib           # façade logging
├─ ksp-config-lib            # composition et packaging Config
├─ ksp-job-api               # JobState/JobSnapshotSource consommés directement
├─ ksp-job-backfill-lib      # request/runtime/handle/snapshot
├─ ksp-onchain-transport-lib # construction HttpTransportPool + role/method readiness
├─ ksp-store-lib             # Store::open et ressource runtime
├─ serde                     # DTO IPC
├─ tauri
├─ tauri-plugin-tracing
├─ tokio                     # spawn/synchronisation app si gabarit Tauri l'exige
└─ ts-rs                     # bindings DTO applicatifs

ksp-job-backfill-lib dépend déjà de Store avec default-features = false. Le Desk devra cependant ouvrir le Store concret ; la feature backend de ksp-store-lib doit donc être explicitement auditée au scaffold. Le pattern cible est une dépendance sur ksp-store-lib uniquement, avec le backend compilé par la feature de façade adéquate, jamais une dépendance directe sur ksp-store-postgres-lib.

Dépendances interdites : ksp-store-api direct, ksp-store-postgres-lib, tokio-postgres, reqwest, tonic, yellowstone-grpc-proto, SDK provider.

9. Single-run lifecycle et races

AppState conserve au plus : ressources runtime stables, un slot de run actif, le dernier snapshot terminal et le dernier checkpoint sûr associé à la requête/backend state nécessaires à une reprise en session.

Règles :

  • start atomique : refus si un run est starting/running/cancelling ;
  • le handle est installé avant spawn afin que Cancel ne perde pas la course au démarrage ;
  • Cancel répété est idempotent au niveau UX, mais le retour expose si la demande a été acceptée ;
  • un terminal publié gagne sur un Cancel tardif ;
  • la source latest-value est conservée jusqu'à projection du terminal ;
  • reset/new campaign n'est autorisé qu'en absence de run actif ;
  • fermeture de l'application déclenche une demande d'annulation coopérative best-effort puis laisse la destruction du process terminer les ressources ; aucune promesse de drain crash-safe n'est faite ;
  • aucun registry multi-job générique n'est introduit.

10. Reprise et checkpoint

V1 conserve le dernier BackfillCheckpoint uniquement dans Rust. L'UI voit checkpoint_present et contiguous_completed, jamais les octets/identité internes du checkpoint.

Resume reconstruit une requête sémantiquement identique avec un nouveau lifecycle contrôlé et réattache le checkpoint via BackfillRequest::with_checkpoint. Le backend doit préserver les éléments participant au scope fingerprint ; toute modification de scope/commitment/bornes sémantiques force une nouvelle campagne et invalide Resume.

Aucun JSON, fichier ou table checkpoint n'est inventé. La reprise après crash/redémarrage est reportée à une évolution explicite du contrat Backfill si un besoin durable est démontré.

11. Threat model

Menace Surface Contrôle v0.3.7
fuite URI Store Config/backend jamais projetée en DTO/log frontend
fuite URL/token provider Transport/Config uniquement rôle/cluster/readiness sûrs ; aucune URL
fuite RAW transaction snapshots/IPC snapshot existant ne contient aucun payload ; aucun Store read général
fuite liste signatures request/logging input transmis au command, non journalisé ; DTO retour n'en contient pas
fuite adresse instrumentation ne pas journaliser la valeur ; seulement scope kind/action code
frontend falsifie bornes IPC validation Rust + BackfillRequest autoritaire
rôle incompatible Config/Transport inventory + select_for_method pour les deux RPC avant Start
réseau incohérent Config rejet bootstrap/readiness avant création de request
double Start AppState admission atomique single-run
Cancel/terminal race AppState/runtime handle installé avant spawn, terminal autoritaire
checkpoint forgé frontend checkpoint jamais traverse IPC
permissions Tauri excessives capabilities core:default + tracing:default, aucune permission fs/dialog/network frontend sans besoin
browser storage de secrets frontend interdit ; aucun secret ne doit atteindre JS

Tauri capabilities restent le mécanisme de frontière IPC. La capability par défaut doit cibler seulement splash et main et ne pas ajouter de plugin filesystem/dialog/network sans besoin réel.

12. Gate fonctionnel/live

Obligatoire pendant la release : tests déterministes Rust/desktop/security/composition, gates workspace et cargo tauri build final lancé depuis crates/ksp-app-backfill-desk.

Un smoke Config -> Transport -> Store -> Backfill peut exister comme test ignoré/opt-in uniquement si l'opérateur dispose d'un PostgreSQL de test et d'un endpoint public sûr. Aucun compte payant, secret fournisseur ou ressource non reproductible n'est requis pour clôturer la release.

13. Prévision recalibrée

pre.001 — audit et planification

Archives/règles/surfaces, matrice kbot3, screen map, DTO/commands, Config/composition, dépendances, threat model, lifecycle single-run, role/network/resume et sizing. Aucun scaffold lourd.

pre.002 — scaffold desktop minimal

Créer package lib+bin, shell/splash/tracing/capability, frontend minimal, ports Vite/HMR 1436/1437 stricts et tests desktop de structure. Le scaffold réutilise strictement le gabarit des Desk existantes : mêmes assets splash/logo/font, mêmes familles SASS/Bootstrap/SimpleBar, mêmes dépendances frontend minimales et mêmes devDependencies. Le bridge Logging frontend trace dès cette tranche les clics/onglets/transitions significatives ; le bootstrap Logging standard reste transitoire jusqu'au composite Backfill Desk de pre.003.

pre.003 — Config composite et packaging

Ajouter le composite Backfill Desk et l'enregistrer dans Config, mettre à jour atomiquement les quatre bundles Desk vers les 14 resources du registre, puis brancher le bootstrap Config/Logging et ses canaries sans encore ouvrir Transport/Store réel. Pendant le développement de l'application, devnet sélectionne le profil Logging supertrace et le fallback local Backfill Desk reste au niveau trace; ce choix est local au Desk et devra être resserré avant publication stable.

pre.004 — Transport readiness

Construire HttpTransportPool, dériver réseau/role inventory sûr, vérifier support des deux RPC et produire options DTO sans provider/URL.

pre.005 — Store readiness

Ouvrir ksp-store-lib::Store, vérifier réseau Store/Transport avant run, lifecycle de fermeture et erreurs sûres. Scinder ici plutôt que mélanger Transport + Store dans une seule tranche large.

pre.006 — DTO/request mapping

DTO TS-RS app-owned, quatre scopes, commitments, min context slot, bornes backend-owned, signatures hostiles et validation de rôle/réseau.

pre.007 — runtime + Start

Single-active-run state, construction BackfillJobRuntime, spawn non bloquant, handle installé avant exécution et snapshot initial/terminal.

pre.008 — monitoring latest-value

Bridge de snapshots, status DTO, événements coalescés, compteurs complets, resynchronisation et absence de log parsing.

pre.009 — Cancel et races terminales

Cancel, état cancelling, idempotence UX, concurrence Start/Cancel/terminal, sémantique de drain Store et fermeture app.

pre.010 — checkpoint/frontier et Resume

Projection sûre, conservation Rust-only du checkpoint, reprise in-session et invariants par scope.

pre.011 — frontend fonctionnel et polish

Formulaire complet, états responsive, instrumentation sûre, summary terminal, erreurs, boutons contextuels, aucun secret/browser storage.

pre.012 — hardening et complétude

Tests desktop/security/dependency/composition/release completeness, canaries DTO et scan des dépendances/interdictions.

pre.013 — gate technique final

cargo fmt, audits, check/clippy/tests workspace, arbres Cargo utiles, cargo tauri build, smoke opt-in si environnement sûr disponible.

pre.014 — réconciliation documentaire

README/USAGE/plan/validation et architecture seulement si la surface finale l'exige. Aucun nouveau runtime.

pre.015 — préparation publication

Prompt 0.3.8, CHANGELOG et ROADMAP uniquement avec le bump prerelease/delta requis.

rel.001 — publication stable

Mécanique de publication v0.3.7, sans rattrapage.

14. Hors périmètre

Store Desk/navigation RAW, Worker API/service daemon, scheduler/registry générique Job, checkpoint durable, retry Job, sélection provider physique, nouveau protocole Transport, migration Store, decoding/materialization, application globale/control desk.