From 2460162243f575af2b51fc707f60935bff361046 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Mon, 31 Aug 2026 14:27:15 +0200 Subject: [PATCH] v0.3.5-pre.008-fix.001 --- CHANGELOG.md | 4 +- ROADMAP.md | 10 +- deltas/0.3.5/pre.008-fix.001.md | 177 ++++ prompts/025-V0_3_6_START_PROMPT.md | 1521 +++++++++++++++++++++++----- 4 files changed, 1466 insertions(+), 246 deletions(-) create mode 100644 deltas/0.3.5/pre.008-fix.001.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 18a67a1..0d2c038 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ - + # Changelog KSP @@ -13,7 +13,7 @@ La frontière d'ownership reste stricte : les DTOs wire/provider demeurent dans Les gates de clôture passent audits Rust/Markdown, `cargo check --workspace`, Clippy all-targets, tests ciblés Interface/Program API, `cargo test --workspace` et graphes Cargo. `cargo tree -p ksp-interface-lib --edges normal` confirme le chemin `ksp-interface-lib -> ksp-core-lib -> solana-pubkey -> solana-address`; le graphe features ne montre aucune feature propre Interface et les doublons éventuels restent ceux du workspace global. La documentation durable a été réconciliée et `TransactionLogEvent` est conservé comme idée différée soumise à un nouveau gate consumer/bornes. -`prompts/025-V0_3_6_START_PROMPT.md` ouvre `0.3.6` sur `ksp-job-api` et un premier backfill historique RAW concret. Le job doit consommer `ksp-store-lib`, conserver policy/batch-size/progression/checkpoint hors de Store et auditer en `pre.001` le premier parcours `RawTransaction` historique, avec `getSignaturesForAddress` + `getTransaction` comme candidat prioritaire plutôt que comme décision irrévocable. +`prompts/025-V0_3_6_START_PROMPT.md` ouvre `0.3.6` sur le développement parallèle de `ksp-job-api` et `ksp-job-backfill-lib`. La release doit reprendre fonctionnellement le backfill historique kbot3 sans en copier le code : audit obligatoire de l'archive historique, `RawTransaction` par adresse via `getSignaturesForAddress` + `getTransaction`, directions/anchors et déduplication, hydratation/persistence via les façades KSP, frontier/checkpoint/reprise, cancellation/concurrency bornées, idempotence et distinctions missing/conflit. `ksp-job-api` doit en parallèle stabiliser lifecycle/progress/outcome et un contrat de notifications/listeners borné pour qu'une couche supérieure puisse visualiser l'état sans parser les logs. Le ROADMAP enchaîne ensuite l'app de backfill/inspection `0.3.7`, `ksp-worker-api` `0.3.8`, `ksp-worker-live-transactions-retriever-lib` `0.3.9` puis une application de monitoring/visualisation Jobs + Workers `0.3.10`, avec reprise du même pattern d'observabilité côté Worker sans fusionner les sémantiques Job/Worker/Store. ## 0.3.4 — Store/PostgreSQL RawAccountState + complétude RAW — 2026-08-31 diff --git a/ROADMAP.md b/ROADMAP.md index ca14c66..007b3ac 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,5 +1,5 @@ - + # Roadmap KSP @@ -98,9 +98,11 @@ RAW -> STRUCTURAL -> DECODED -> DOMAIN - [X] `0.3.3` — Vertical slice PostgreSQL `RawTransaction` complète sur `ksp-store-lib` + `ksp-store-postgres-lib` : six capabilities transaction/observation/rétention, V001 physique liée à un réseau, acquisition canonical+observation atomique, idempotence/conflit, get/list keyset cursorisé, archive/purge/tombstone/ForceRehydrate, hardening des erreurs et du schéma, concurrence et rollback validés sur PostgreSQL 17. - [X] `0.3.4` — Vertical slice PostgreSQL `RawAccountState` complète sur `ksp-store-lib` + `ksp-store-postgres-lib` : quatre capabilities account ajoutées aux six transaction pour une conformance RAW 10/10, V002 additive de 32 ressources au-dessus de V000/V001 immuables, state+observation atomiques, idempotence/conflit exacts, metadata Yellowstone observation-only, get/list keyset `(slot,pubkey,state_hash)` avec cursor KSPA anti-replay, hardening cross-family et live validé sur PostgreSQL 17 sans rétention destructive account. - [X] `0.3.5` — `ksp-interface-lib` étendu avec deux familles passives réellement partagées : `SlotLifecycleEvent` (`Processed`, `FirstShredReceived`, `Completed`, `CreatedBank`, `Dead`, `OptimisticallyConfirmed`, `Rooted`) et `TransactionExecutionEvent` (`slot + TransactionSignature[64] + Succeeded/Failed`). Interface reste Core-only, provider-neutral, sans serde/codec/runtime/event bus et sans duplication de `RawTransaction`/`RawAccountState`; les DTOs riches restent Transport-owned et les candidats non convergents restent différés. -- [ ] `0.3.6` — Introduire `ksp-job-api` et un premier job de backfill historique RAW concret consommant `ksp-store-lib`; auditer en priorité un backfill `RawTransaction` par adresse via pagination Transport, avec policy/batch-size/progression/checkpoint/cancellation possédés par le job et jamais par Store. -- [ ] `0.3.7` — Introduire une application spécialisée de backfill/inspection RAW. -- [ ] Compléter ensuite la couche RAW avec le worker/service live, son contrôle et les outils d’exploitation réellement nécessaires avant de passer à la couche de normalisation générique suivante. +- [ ] `0.3.6` — Introduire en parallèle `ksp-job-api` et `ksp-job-backfill-lib` : reprendre fonctionnellement le backfill historique kbot3 sur les abstractions KSP actuelles (`ksp-onchain-transport-lib` + `ksp-store-lib`), fermer une première verticale `RawTransaction` historique par adresse avec directions/anchors, déduplication, hydratation, idempotence, frontier/checkpoint/reprise, cancellation et concurrency bornées, et stabiliser un lifecycle/progress/outcome avec notifications/listeners sûrs pour les couches supérieures. +- [ ] `0.3.7` — Introduire une application spécialisée de backfill/inspection RAW consommant `ksp-job-api` : lancement/annulation contrôlés, état et progression live, compteurs, checkpoint/frontière, outcome terminal et inspection RAW sans parser les logs ni connaître les providers/backends physiques. +- [ ] `0.3.8` — Introduire `ksp-worker-api` comme API générique de lifecycle/health/progression pour services continus, en reprenant le pattern de notifications/listeners stabilisé par Job tout en gardant les sémantiques Worker distinctes des jobs terminables et des wake-ups Store post-commit. +- [ ] `0.3.9` — Introduire `ksp-worker-live-transactions-retriever-lib` pour l'acquisition continue `RawTransaction` via les surfaces live de `ksp-onchain-transport-lib`, persistence par `ksp-store-lib`, reprise/backpressure/idempotence et notifications `ksp-worker-api`, sans decode Program ni dépendance backend/provider directe. +- [ ] `0.3.10` — Introduire une application de monitoring/visualisation Jobs + Workers : vue graphique des lifecycles, health/progression, rates/backpressure/retries sûrs, checkpoints et outcomes ; l'application consomme les APIs publiques Job/Worker et ne devient ni scheduler caché ni source de vérité du backlog. ### TODO/IDEAS — taxonomie N1, processing et rétention diff --git a/deltas/0.3.5/pre.008-fix.001.md b/deltas/0.3.5/pre.008-fix.001.md new file mode 100644 index 0000000..743b0d5 --- /dev/null +++ b/deltas/0.3.5/pre.008-fix.001.md @@ -0,0 +1,177 @@ + + + +# Delta `0.3.5-pre.008-fix.001` — enrichissement du prompt `0.3.6` et trajectoire Job/Worker + +## Base requise + +```text +0.3.5-pre.008 +workspace.package.version = 0.3.5-pre.8 +``` + +Ce fix est **strictement documentaire**. Il ne modifie aucun fichier Rust/build/runtime/config et ne change donc pas `workspace.package.version`. + +`Cargo.toml` reste exactement celui de `pre.008` : + +```text +workspace.package.version = 0.3.5-pre.8 +``` + +## Motif du fix + +Le prompt `025` de `pre.008` était insuffisamment détaillé par rapport : + +- aux règles de construction des prompts KSP ; +- à la portée réelle attendue de `0.3.6` ; +- aux fonctionnalités de backfill déjà présentes historiquement dans kbot3 ; +- au besoin d'observabilité par une couche supérieure ; +- à la trajectoire Worker qui doit reprendre le même pattern de notifications. + +Il laissait également le nom de la crate concrète à décider alors que la direction est désormais fixée : + +```text +ksp-job-backfill-lib +``` + +## Corrections du prompt `0.3.6` + +Le prompt version 2 ouvre désormais explicitement : + +```text +ksp-job-api ++ +ksp-job-backfill-lib ++ +backfill RawTransaction historique fonctionnel ++ +lifecycle/progression/outcome ++ +notifications/listeners sûrs pour UI/composition +``` + +### Archive kbot3 + +L'archive : + +```text +khadhroony-bot3_v0.5.3-pre.005-fix010.zip +``` + +redevient **obligatoire en `0.3.6-pre.001`**, mais uniquement comme inventaire fonctionnel historique. + +Le plan doit construire une matrice : + +```text +REPRENDRE FONCTIONNELLEMENT +REDESSINER POUR KSP +REPORTER +REJETER +``` + +Le code, les anciennes crates, DTOs, SQL, retries et choix runtime kbot3 ne sont pas à copier. + +### Parité fonctionnelle minimale à réauditer + +Le prompt rend explicites les invariants historiquement démontrés : + +- scans latest/before/after/explicit selon audit ; +- anchors et directions ; +- candidats/pages dédupliqués ; +- nearest-newer/gap-fill si conservé ; +- frontier de complétion contiguë ; +- reprise après cancellation sans saut ; +- cancellation coopérative pendant RPC long et wait/backoff ; +- ownership séparé du retry Transport et du retry Job ; +- compteurs de campagne distinguant sélection, complétion, insert/idempotence/existing, missing et observations. + +### Notifications Job + +Le prompt exige désormais un vrai contrat d'observabilité `ksp-job-api` : + +```text +identity +state/phase +progress/snapshot +checkpoint/frontier +sequence ou ordre observable +terminal outcome +safe error code +listener isolation/backpressure +resynchronisation après perte/coalescing +``` + +Ces notifications sont explicitement distinctes : + +```text +Interface acquisition events +Store KSP-NOTIFY-* post-commit wake-ups +logging/tracing +``` + +Aucune dépendance Tokio/channel précise n'est imposée dans `ksp-job-api` avant l'audit `pre.001`. + +### Alignement Worker futur + +Le même pattern conceptuel devra être repris par `ksp-worker-api`, sans créer dès `0.3.6` une crate générique spéculative supplémentaire. + +## Corrections du ROADMAP + +La trajectoire RAW opérationnelle devient explicitement : + +```text +0.3.6 ksp-job-api + ksp-job-backfill-lib + notifications +0.3.7 application backfill/inspection RAW +0.3.8 ksp-worker-api +0.3.9 ksp-worker-live-transactions-retriever-lib +0.3.10 application monitoring/visualisation Jobs + Workers +``` + +L'ancien placeholder générique « worker/service live ensuite » est supprimé au profit de releases nommées et ordonnées. + +## Correction du CHANGELOG + +Le paragraphe ouvrant `0.3.6` est aligné sur la portée réelle du prompt version 2 et sur la nouvelle trajectoire ROADMAP. + +Aucune information sur le contenu fonctionnel déjà stabilisé de `0.3.5` n'est changée. + +## Versions d'en-tête + +```text +CHANGELOG.md 24 -> 25 +ROADMAP.md 99 -> 100 +prompts/025-V0_3_6_START_PROMPT.md 1 -> 2 +deltas/0.3.5/pre.008-fix.001.md nouveau -> 1 +``` + +## Fichiers modifiés + +Exactement : + +```text +CHANGELOG.md +ROADMAP.md +prompts/025-V0_3_6_START_PROMPT.md +deltas/0.3.5/pre.008-fix.001.md +``` + +Explicitement inchangés : + +```text +Cargo.toml +crates/** +docs/architecture/** +docs/plans/026-V0_3_5_INTERFACE_ACQUISITION_EVENTS_PLAN.md +docs/validation/022-V0_3_5_INTERFACE_ACQUISITION_EVENTS.md +``` + +## Gate demandé + +Le fix ne modifie aucun Rust. Le gate minimal est : + +```bash +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.5 +``` + +Aucun rerun Cargo n'est requis par ce fix documentaire lui-même. diff --git a/prompts/025-V0_3_6_START_PROMPT.md b/prompts/025-V0_3_6_START_PROMPT.md index 57925dc..2e48952 100644 --- a/prompts/025-V0_3_6_START_PROMPT.md +++ b/prompts/025-V0_3_6_START_PROMPT.md @@ -1,7 +1,7 @@ - + -# Prompt de démarrage `0.3.6` — Job API + premier backfill historique RAW +# Prompt de démarrage `0.3.6` — Job API + backfill RAW observable ## 1. Contexte de reprise @@ -15,163 +15,1034 @@ La surface acquise doit notamment être : ```text ksp-store-api - -> RAW backend-agnostic + -> modèles N1 RAW backend-agnostic -> RawTransaction + RawAccountState + observations -> 10 capabilities object-safe + -> queries/cursors, idempotence/conflits, rétention transactionnelle ksp-store-lib -> façade runtime backend-neutral - -> backend postgres activé par feature par défaut + -> un Store lié à un RawNetworkId + -> backend postgres sélectionné par feature par défaut ksp-store-postgres-lib -> PostgreSQL 17 validé -> RAW 10/10 physique + -> transactions + accounts + observations + pagination + rétention transaction ksp-interface-lib - -> ProgramAccountMeta / ProgramInstruction + -> contrats Program passifs historiques -> SlotLifecycleEvent / SlotLifecycleStage -> TransactionSignature / TransactionExecutionEvent / TransactionExecutionOutcome - -> dépendance normale Core-only + -> provider-neutral, sans runtime/event bus, dépendance normale Core-only ksp-onchain-transport-lib -> HTTP Solana typed complet -> WS standard + Helius -> Yellowstone engine actuel + -> ownership du réseau, des providers, des retries transport et des DTOs wire/provider ``` -`0.3.5` a confirmé la séparation suivante : +`0.3.5` a confirmé les frontières suivantes : ```text -DTO riche / provider-specific -> Transport -fait passif provider-neutral -> Interface -modèle persistant / replayable -> Store API -backlog durable -> Store -policy / batch-size / progression -> Job/Worker +DTO riche / provider-specific -> Transport +fait passif provider-neutral -> Interface +modèle persistant / replayable -> Store API +façade backend-neutral -> Store Lib +policy / batch / progression -> Job ou Worker +backlog durable -> Store +notification Store post-commit -> wake-up de backlog, jamais lifecycle Job/Worker ``` -La release à ouvrir est : +La release à ouvrir est désormais explicitement : ```text -0.3.6 — ksp-job-api + premier backfill historique RAW +0.3.6 + -> ksp-job-api + -> ksp-job-backfill-lib + -> lifecycle/progression/cancellation observables + -> notifications/listeners pour les couches supérieures + -> reprise fonctionnelle du backfill historique kbot3 sur l'architecture KSP actuelle + -> première verticale RawTransaction historique complète ``` -La première tranche est `0.3.6-pre.001` et commence par **audit de la base réelle + brainstorming + sizing + plan**, sans implémentation fonctionnelle lourde. +`ksp-job-api` et `ksp-job-backfill-lib` doivent être développés **en parallèle** : l'API ne doit pas être conçue abstraitement plusieurs prereleases avant son premier consumer réel, et l'implémentation ne doit pas inventer des contrats privés qui contournent ensuite l'API. -## 2. Mission +La première tranche est `0.3.6-pre.001` et commence obligatoirement par **lecture des règles + audit de la base réelle + audit fonctionnel kbot3 + audit officiel actuel + brainstorming + sizing + plan**, sans implémentation fonctionnelle lourde. -Cette release doit introduire : +## 2. Règle de lecture du prompt -1. `ksp-job-api`, comme API passive et backend-neutral de lifecycle/progression pour traitements bornés ; -2. un premier job historique RAW concret ; -3. une composition explicite Transport -> conversion RAW -> `ksp-store-lib` ; -4. une ownership claire de la policy, de la pagination réseau, du batch-size, du checkpoint et de la cancellation. - -Le premier candidat prioritaire est un backfill `RawTransaction` historique **scopé par adresse**, fondé sur les primitives HTTP Solana existantes : +Avant toute modification, relire et appliquer les documents de gouvernance KSP, en particulier : ```text -getSignaturesForAddress +RULES.md +ROADMAP.md +CHANGELOG.md +docs/000-README.md +docs/PROMPT_STRUCTURE.md +docs/VERSION_WORKFLOW.md +docs/FILE_CONTRACTS.md +``` + +Le présent prompt complète ces règles ; il ne les remplace pas. + +Si une instruction du prompt contredit une règle canonique plus récente du dépôt, **la règle canonique gagne** et l'écart doit être documenté dans le plan/validation de `pre.001` avant implémentation. + +Respecter notamment : + +```text +pre.001 = audit / brainstorming / sizing / plan +pas d'implémentation lourde en pre.001 +une modification Rust/build/runtime/config => bump workspace.package.version +un fix purement documentaire => pas de bump workspace.package.version +USAGE.md durable et version-neutral +README/architecture/ROADMAP/CHANGELOG chacun dans son rôle propre +``` + +## 3. Mission de `0.3.6` + +La release doit livrer **deux crates alignées** et une première verticale fonctionnelle fermée. + +### 3.1 `ksp-job-api` + +Créer une API publique passive pour les traitements **bornés et terminables** : + +```text +identité du job +request/descriptor observable +lifecycle +progression +snapshot d'état +checkpoint/frontière lorsque pertinent +cancellation / stop reason +outcome terminal +notification / observation par listener externe +``` + +L'API doit être immédiatement exercée par `ksp-job-backfill-lib`. + +### 3.2 `ksp-job-backfill-lib` + +Créer la crate concrète : + +```text +crates/ksp-job-backfill-lib +``` + +Le nom n'est plus à décider en `pre.001`. + +Cette crate doit réimplémenter sur KSP les **fonctionnalités utiles** du backfill historique kbot3, sans reprendre son code, son découpage de crates, ses DTOs, son SQL, ses boucles de retry, ses IDs ni ses choix runtime comme autorité. + +La verticale prioritaire est : + +```text +scope historique explicite | v -signatures ordonnées newest -> oldest +getSignaturesForAddress via ksp-onchain-transport-lib | v -getTransaction +candidats dédupliqués + pagination/direction/anchors | v -conversion vers RawTransaction + observation +getTransaction via ksp-onchain-transport-lib + | + v +projection vers RawTransaction + RawTransactionObservation | v ksp-store-lib + | + v +idempotence/conflit/missing + progression/checkpoint + | + v +notifications ksp-job-api vers listeners/UI/composition ``` -Ce candidat n'est pas encore une décision irrévocable : `pre.001` doit vérifier la sémantique officielle actuelle, la surface Transport réelle, les bornes provider/RPC, les lacunes éventuelles et la faisabilité d'une clôture complète de la release dans une session. +La release doit fermer cette verticale de bout en bout, pas seulement créer des types d'API et un squelette de job. -## 3. Principes d'architecture non négociables +## 4. Sources de vérité et rôle de kbot3 -### 3.1 Store reste une primitive de persistence/navigation +### 4.1 Sources normatives -Ne pas déplacer dans Store : +L'ordre d'autorité est : ```text -batch-size métier -priorité de job -retry policy métier -range historique décidé par le job -checkpoint métier -cadence -scheduler -progression -cancellation +1. règles et architecture KSP actuelles +2. contrats publics réellement présents dans v0.3.5 +3. documentation officielle actuelle Solana / providers concernés +4. tests et preuves réelles KSP +5. archive historique kbot3 comme inventaire fonctionnel ``` -Store peut exposer ses primitives de lecture/écriture/cursorisation existantes ; il ne devient pas orchestrateur. +### 4.2 Archive kbot3 obligatoire en `pre.001` -### 3.2 `ksp-job-api` reste passif +L'archive historique fournie par l'opérateur : -L'API Job ne doit pas devenir : +```text +khadhroony-bot3_v0.5.3-pre.005-fix010.zip +``` + +est **obligatoire** pour l'audit fonctionnel de `pre.001`. + +Elle doit servir à dresser une matrice explicite : + +```text +REPRENDRE FONCTIONNELLEMENT +REDESSINER POUR KSP +REPORTER +REJETER +``` + +Le but est de retrouver les capacités utiles et leurs invariants, **pas** de porter/copier l'ancien code. + +Interdictions : + +```text +copier les modules backfill kbot3 tels quels +copier les anciennes abstractions Store/Transport +copier les anciennes migrations/SQL +copier les DTOs/provider models +copier les anciens retry loops sans audit du Transport KSP actuel +copier les anciens IDs/config defaults comme contrats KSP +faire de kbot3 l'autorité lorsqu'il diverge de KSP ou des RPC actuels +``` + +## 5. Matrice fonctionnelle kbot3 minimale à réauditer + +Les preuves historiques déjà connues montrent au minimum les comportements suivants. `pre.001` doit les retrouver dans l'archive, identifier leur implémentation ancienne et décider leur équivalent KSP. + +### 5.1 Scope, directions et anchors + +Auditer : + +```text +latest/newest scan par adresse +before / older-than-anchor +after / newer-than-anchor si l'ancien backfill le supporte +nearest-newer / gap-fill autour d'un anchor si sémantiquement utile +candidats explicites par signature +limite opérationnelle non nulle +filter/scope identity distinguant cible + direction +``` + +Les tests historiques connus incluent notamment : + +```text +after_address_request_rejects_missing_anchor +before_address_request_accepts_missing_anchor +address_request_requires_non_zero_limit +filter_code_distinguishes_target_and_direction +nearest_newer_candidates_keep_only_entries_closest_to_anchor +``` + +Ne pas transformer ces noms historiques en API KSP automatiquement. Ils prouvent des **comportements** à réauditer. + +### 5.2 Déduplication et ordre + +Auditer et conserver lorsque la sémantique actuelle le justifie : + +```text +déduplication de candidats explicites en conservant l'ordre utile +déduplication des entrées de pages réseau +absence de double hydratation évitable +ordre déterministe de progression +``` + +Preuves historiques connues : + +```text +explicit_candidates_are_deduplicated_in_input_order +nearest_newer_candidates_deduplicate_page_entries +``` + +### 5.3 Frontière de complétion et reprise + +L'ancien système possédait une notion importante de **frontière de complétion contiguë**. + +Réauditer : + +```text +completion_frontier_advances_only_across_contiguous_results +cancelled_before_resume_uses_last_contiguous_candidate +cancelled_before_resume_keeps_anchor_when_nothing_completed +cancelled_latest_scan_without_completed_candidate_restarts_from_latest +``` + +KSP doit conserver l'invariant fonctionnel : une annulation ou un échec ne doit jamais avancer un checkpoint au-delà d'un trou non terminé et provoquer une omission silencieuse à la reprise. + +La représentation KSP exacte reste à concevoir en `pre.001`. + +### 5.4 Cancellation coopérative + +Réauditer les points de cancellation historiques : + +```text +avant admission du travail +pendant pagination +pendant hydratation getTransaction +pendant un RPC long +pendant attente/backoff +avant persistence +entre deux candidats +``` + +Preuves historiques connues : + +```text +cancellable_retry_wait_returns_immediately_when_already_cancelled +long_running_rpc_future_is_cancelled_cooperatively +``` + +La cancellation ne doit pas laisser un état Job annonçant `Completed` si des opérations ont été abandonnées. + +### 5.5 Retry / rate limit + +L'ancien système exposait une pause liée au rate-limit et un nombre de retries Job. Cette fonctionnalité doit être **redessinée** parce que `ksp-onchain-transport-lib` possède déjà sa propre résilience transport. + +`pre.001` doit établir une matrice : + +```text +retry Transport -> Transport uniquement +Retry-After provider -> Transport si déjà classifié/exposé +retry Job sémantique -> seulement si une opération complète doit être rejouée au niveau Job +backoff cancellation -> Job si le Job attend réellement +invalid params déterministe -> jamais retry +Store conflict -> jamais masqué par retry aveugle +``` + +Objectif : éviter toute multiplication `retry Job x retry Transport` non bornée ou non comprise. + +### 5.6 Compteurs et résumé de campagne + +Les campagnes historiques exposaient notamment : + +```text +candidates_selected +candidates_completed +canonical_inserted +canonical_skipped +existing_skipped +missing +observations_inserted +``` + +`pre.001` doit transformer cette liste en un **modèle de progression KSP**, en supprimant les doublons sémantiques et en ajoutant seulement les compteurs nécessaires au consumer réel. + +Les noms historiques ne sont pas imposés, mais les distinctions utiles ne doivent pas disparaître dans un unique `processed`. + +## 6. Audit officiel obligatoire des RPC historiques + +Avant de figer les requests du backfill, réauditer la documentation officielle actuelle et la surface typed réelle de `ksp-onchain-transport-lib`. + +### 6.1 `getSignaturesForAddress` + +Confirmer au minimum : + +```text +ordre newest -> oldest +before +until +limit +commitment +minContextSlot +sémantique de fin de pagination +résultat signature / slot / err / memo / blockTime / confirmationStatus +limites RPC actuelles +comportement des providers réellement supportés par KSP +``` + +Ne pas inventer un scan global du ledger si le RPC standard reste address-scoped. + +### 6.2 `getTransaction` + +Confirmer au minimum : + +```text +forme de config moderne retenue +commitment réellement supporté +encoding retenu +maxSupportedTransactionVersion +null / unavailable / not confirmed +slot +blockTime +transaction +meta +version +complétude requise pour produire le RawTransaction KSP +``` + +Ne pas réintroduire une forme legacy seulement parce que kbot3 l'utilisait. + +### 6.3 Rôle Transport + +Le job consomme les wrappers typed existants. + +Il ne doit jamais : + +```text +créer son propre reqwest Client +faire du JSON-RPC manuel +connaître l'URL provider +brancher sur Helius/PublicNode/... au niveau métier +réimplémenter les limites/rate-limits possédées par Transport +utiliser directement tonic/yellowstone proto pour ce backfill HTTP +``` + +## 7. Architecture obligatoire de `ksp-job-api` + +### 7.1 API passive, pas runtime + +`ksp-job-api` ne doit pas devenir : ```text scheduler global thread pool runtime Tokio propriétaire -event bus queue distribuée -registry de tous les jobs KSP -backend de persistence implicite +cron engine +service registry global +backend de persistence +SQL repository +client Transport +Config runtime +Tauri/IPC ``` -`pre.001` doit déterminer la surface minimale réellement nécessaire au premier consumer. Les concepts à auditer, sans les figer d'avance, sont notamment : +L'API décrit les contrats ; l'exécution appartient au job concret/composition. + +### 7.2 Surface à auditer avec le premier consumer + +Les concepts suivants doivent être étudiés, puis seulement ceux démontrés doivent être matérialisés : ```text JobId +JobDescriptor / JobKind JobState -JobDescriptor +JobPhase JobProgress +JobSnapshot +JobCheckpoint ou frontier observable +JobStopReason JobOutcome -JobCheckpoint -cancellation / stop reason +JobNotification +JobNotificationSequence +JobListener / JobNotificationSink / équivalent +cancellation handle/token contract si réellement API-owned ``` -Éviter les structs Option-soup et les états dont la sémantique n'est pas observable par le premier job. +Ne pas créer un enum/struct pour chaque nom de cette liste par obligation. -### 3.3 Implémentation du backfill séparée de l'API +### 7.3 Lifecycle -`ksp-job-api` ne doit pas dépendre de Transport ou d'un backend Store physique. +Le lifecycle doit être impossible à interpréter de deux façons. -Le job concret peut dépendre de : +Candidat conceptuel à auditer : ```text -ksp-job-api -ksp-onchain-transport-lib -ksp-store-lib -ksp-core-lib si réellement nécessaire -ksp-logging-lib pour le comportement runtime +Created/Queued +Starting +Running +Retrying ou Waiting si distinct observable +Cancelling +Completed +Cancelled +Failed ``` -Aucune dépendance directe vers `ksp-store-postgres-lib` n'est autorisée au consumer ordinaire. - -Le nom et la forme de la crate d'implémentation du premier job doivent être décidés en `pre.001` après audit des conventions workspace. Ne pas créer plusieurs crates auxiliaires spéculatives. - -### 3.4 Conversion RAW - -Le job doit produire les modèles RAW backend-neutral existants et écrire via `ksp-store-lib`. - -Il ne doit pas : +Éviter : ```text -écrire du SQL -connaître tokio-postgres/deadpool -inventer un RawTransaction concurrent -faire du decode Program +state + is_running + is_done + is_cancelled +``` + +qui permet des combinaisons contradictoires. + +Utiliser des enums/variants structurés plutôt qu'une Option-soup si des données n'existent que dans certains états. + +### 7.4 Snapshot et progression + +Une couche supérieure doit pouvoir demander/recevoir un état compréhensible sans reconstruire toute l'histoire interne. + +Le snapshot doit pouvoir représenter au besoin : + +```text +job identity +kind/descriptor sûr +state/phase +progress counters +scope/range sûr +checkpoint/frontier sûr +started/updated/finished time uniquement si ownership clair +terminal outcome / safe error code +``` + +Ne pas exposer les payloads, URLs ou secrets sous prétexte de diagnostic. + +## 8. Notifications Job / listeners / observabilité + +Cette release doit introduire un mécanisme exploitable par une couche supérieure, par exemple : + +```text +future app de backfill +monitor graphique +CLI +orchestrateur +telemetry adapter +``` + +### 8.1 Sémantique + +Les notifications Job sont des **notifications opérationnelles de lifecycle/progression**. + +Elles sont distinctes de : + +```text +ksp-interface-lib acquisition events +ksp-store-api KSP-NOTIFY-* post-commit wake-ups +backlog durable Store +logs tracing +``` + +Ne fusionner aucun de ces concepts. + +### 8.2 Pattern cible + +`pre.001` doit comparer puis choisir une forme qui satisfait au minimum : + +```text +observer externe possible sans connaître ksp-job-backfill-lib internals +ordre local observable ou sequence monotone +snapshot cohérent après chaque transition significative +notification terminale non ambiguë +consumer lent incapable de bloquer indéfiniment le job +politique explicite si des updates de progression intermédiaires sont coalescées/perdues +moyen de récupérer l'état courant après perte d'une notification transitoire +aucune dépendance obligatoire à Tauri +aucun payload provider/RAW dans les notifications +``` + +Une direction préférable à évaluer est : + +```text +notification = envelope léger + sequence + snapshot/delta sûr +snapshot courant = source de vérité runtime pour l'observateur +progress updates = coalesçables si la sequence/snapshot permet resynchronisation +transition terminale = non perdue par contrat de l'adapter choisi +``` + +Ne pas promettre un event log durable si aucun consumer ne l'exige. + +### 8.3 Backpressure du listener + +Le design doit décider explicitement : + +```text +bounded queue ? +latest-value/watch semantics ? +coalescing progress ? +fan-out ? +listener failure isolation ? +``` + +Le choix exact de primitive (`watch`, `broadcast`, channel maison, callback, trait sink, etc.) **n'est pas fixé par ce prompt** et doit être justifié contre : + +```text +runtime-neutralité de ksp-job-api +multi-listener futur +consumer UI lent +terminal delivery +absence de blocage du job +simplicité de test +``` + +Aucune dépendance Tokio ne doit entrer dans `ksp-job-api` uniquement pour imposer une primitive de channel. + +### 8.4 Préparation de `ksp-worker-api` + +Le système de notifications de Job doit volontairement créer un vocabulaire/pattern réutilisable plus tard par les workers : + +```text +identity +state +snapshot +progress/health +sequence +terminal/stop reason lorsque pertinent +listener isolation +safe observability +``` + +Mais `0.3.6` ne doit pas créer `ksp-worker-api` en avance. + +Le futur `ksp-worker-api` devra reprendre le **même pattern conceptuel**, sans dépendre de `ksp-job-backfill-lib`. + +Ne pas créer aujourd'hui une troisième crate générique `task/runtime/observer-api` seulement pour anticiper ce partage. Une extraction commune n'est justifiée que lorsqu'une duplication Job + Worker réelle existe. + +## 9. Architecture obligatoire de `ksp-job-backfill-lib` + +### 9.1 Dépendances attendues + +Le graphe cible à auditer est : + +```text +ksp-job-backfill-lib + -> ksp-job-api + -> ksp-onchain-transport-lib + -> ksp-store-lib + -> ksp-config-lib seulement si la composition/runtime le justifie réellement + -> ksp-logging-lib + -> ksp-core-lib si types fondamentaux nécessaires +``` + +Interdictions directes : + +```text +ksp-store-postgres-lib +postgres/tokio-postgres/deadpool +reqwest +solana-client / RPC SDK parallèle +tonic/yellowstone proto pour la verticale HTTP +tauri +SQL +lecture directe .env / variables KSP si Config possède déjà la source +``` + +### 9.2 `ksp-logging-lib` + +La crate étant comportementale : + +```text +utiliser ksp-logging-lib +posséder constants.rs +posséder TRACING_TARGET selon les règles KSP +logs structurés et redacted +``` + +Ne jamais logguer : + +```text +provider URL/credentials +connection URI Store +raw transaction payload +SQL/binds +secret config values +notification payload non borné +``` + +### 9.3 Pas de backend leakage + +Tous les writes/reads Store ordinaires passent par `ksp-store-lib`. + +Le job ne doit connaître ni PostgreSQL ni ses cursors physiques. + +## 10. Pipeline fonctionnelle du backfill RAW + +La verticale doit être explicitement séparée en phases observables afin que les notifications et la cancellation aient une sémantique claire. + +Candidat de phases à auditer : + +```text +Validate +Discover +Hydrate +Persist +Checkpoint +Finish +``` + +Ces noms ne sont pas imposés, mais un monitor doit pouvoir distinguer : + +```text +recherche de signatures +récupération des transactions +persistence/idempotence +attente/retry +cancellation +fin terminale +``` + +### 10.1 Scope + +Le premier job doit au minimum supporter un scope historique utile et borné par adresse. + +`pre.001` doit décider si la release ferme toutes les formes fonctionnelles kbot3 suivantes ou une partition explicitement justifiée : + +```text +latest +before/older +newer/after gap fill +explicit signatures +``` + +Toute forme reportée doit rester tracée dans le plan/TODO/ROADMAP adéquat ; ne pas la perdre parce que le premier canari utilise seulement `latest`. + +### 10.2 Candidats + +Les candidats doivent : + +```text +être identifiés par signature canonique +préserver l'ordre nécessaire au checkpoint +être dédupliqués +rester bornés +ne pas devenir RawTransaction avant hydratation réussie +``` + +### 10.3 Hydratation + +Chaque signature retenue est hydratée via `getTransaction`. + +Le job doit distinguer au minimum : + +```text +transaction complète +null / missing +réponse invalide Transport +échec transitoire déjà classifié +cancellation +``` + +`missing` n'est pas automatiquement un failure terminal du job ; la policy doit être décidée et observable. + +## 11. Projection Transport -> RAW + +Le job doit construire les modèles backend-neutral existants : + +```text +RawTransaction +RawTransactionObservation +``` + +et utiliser les APIs publiques KSP. + +Interdictions : + +```text +inventer RawTransactionV2 concurrent +stocker le DTO getTransaction tel quel hors contrat RAW +ajouter provider-specific fields au canonical +faire du Program decode produire STRUCTURAL/DECODED/DOMAIN -persister des DTOs Transport tels quels ``` -Auditer si la conversion Transport -> RAW mérite déjà une petite pipeline réutilisable. Par défaut, ne pas introduire `ksp-pipeline-raw-ingestion-lib` tant que la réutilisation job + futur worker ne justifie pas clairement une crate séparée. +### 11.1 Pipeline RAW partagée : décision différée mais audit obligatoire -## 4. Audit obligatoire de `pre.001` +`docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md` prévoit qu'une future ingestion RAW partagée Job + Worker pourrait justifier une crate dédiée. -Avant toute implémentation, relire au minimum : +`0.3.6-pre.001` doit auditer la quantité exacte de logique commune potentielle : + +```text +Transport DTO -> RawTransaction +provenance observation +validation network +hash/payload format +write canonical + observation +post-write outcome mapping +``` + +Par défaut : + +```text +ne pas créer ksp-pipeline-raw-ingestion-lib en pre.001 +``` + +Si la duplication future avec `ksp-worker-live-transactions-retriever-lib` est évidente et que la logique est déjà substantielle, documenter le choix, mais ne pas élargir `0.3.6` sans sizing explicite. + +## 12. Persistence, idempotence, conflits et réseau + +Le backfill doit exploiter les sémantiques Store existantes au lieu de les reconstruire. + +Auditer précisément : + +```text +acquire/write RawTransaction + observation atomique disponible +write observation supplémentaire +read existing canonical +RawWriteOutcome / conflict semantics +retention/tombstone/ForceRehydrate +RawNetworkId du Store +``` + +### 12.1 Idempotence + +Rejouer un même backfill ne doit pas créer des doublons logiques. + +Les compteurs doivent distinguer au besoin : + +```text +inserted +idempotent/already present +observation inserted/already present +missing +conflict +``` + +Ne pas traiter un conflit de contenu comme un simple skip silencieux. + +### 12.2 Tombstone / rehydrate + +Un job historique normal ne doit pas annuler implicitement une décision de purge. + +Si un `RawTransaction` est tombstoned/purged : + +```text +normal backfill -> respecter le contrat normal-skip/refus existant +force rehydrate -> seulement via intention explicite si le scope de 0.3.6 le justifie +``` + +Ne pas ajouter ForceRehydrate au premier job par réflexe. + +### 12.3 Réseau + +Transport et Store doivent viser le même réseau effectif. + +Le mismatch doit être détecté avant d'accumuler un lot de données destiné au mauvais Store. + +## 13. Checkpoint, progression et reprise + +### 13.1 Distinguer les concepts + +Ne pas confondre : + +```text +cursor RPC +before/until anchor +signature candidate +candidat hydraté +candidat persisté/idempotent +frontière contiguë complétée +checkpoint de reprise +compteur UI +cursor Store +``` + +### 13.2 Frontière contiguë + +Si plusieurs hydrations sont concurrentes, les résultats peuvent terminer hors ordre. + +Le checkpoint ne doit avancer qu'à travers une séquence **contiguë** de candidats dont l'outcome requis est terminal/connu. + +Exemple conceptuel : + +```text +candidate 1 -> done +candidate 2 -> in flight +candidate 3 -> done + +frontier = candidate 1 +pas candidate 3 +``` + +Après completion de 2 : + +```text +frontier peut avancer jusqu'à candidate 3 +``` + +Cette propriété doit être testée. + +### 13.3 Persistence du checkpoint + +Ne pas créer une table Job par réflexe. + +`pre.001` doit décider séparément : + +```text +checkpoint runtime seulement pour 0.3.6 ? +checkpoint sérialisable mais persistence externalisée ? +checkpoint durable nécessaire pour reprise après crash ? +``` + +La règle d'architecture indique qu'une reprise après crash ne peut pas dépendre uniquement de mémoire si elle est revendiquée comme fonctionnalité. Donc : + +- soit `0.3.6` ferme une vraie reprise crash-safe et démontre où le checkpoint durable vit ; +- soit elle qualifie explicitement la reprise comme reprise après cancellation/restart contrôlé avec checkpoint fourni par le caller, sans fausse promesse de durability. + +Aucune migration Store n'est autorisée sans décision explicite et ownership démontré. + +## 14. Concurrency et admission + +Le job possède la **concurrency métier** de son traitement, Transport possède ses propres limites/admission réseau, Store possède son pool/backend. + +`pre.001` doit fixer des bornes explicites pour : + +```text +page size / pages max si exposés +candidate limit +hydration concurrency +in-flight candidates +notification queue/coalescing si runtime implementation +retry Job éventuel +shutdown/cancel timeout si nécessaire +``` + +Ne pas importer automatiquement les valeurs historiques kbot3 telles que : + +```text +page_size=100 +max_pages=20 +requested_concurrency=4 +max_retries=2 +``` + +Ces valeurs sont des preuves d'ancien comportement, pas des defaults KSP. + +## 15. Cancellation : contrat de bout en bout + +La cancellation doit être coopérative, déterministe et testable. + +Matrice minimale : + +```text +avant start/admission -> aucun travail démarré +pendant discovery -> stop borné, checkpoint cohérent +pendant getTransaction -> future annulable si Transport API le permet +pendant attente/retry -> wake immédiat/rapide +pendant persistence -> ne pas prétendre annuler une transaction déjà commit +après commit / avant notification -> snapshot final cohérent +pendant Cancelling -> aucune nouvelle admission de candidat +``` + +Un consumer doit recevoir un état terminal `Cancelled` seulement après que le job sait quelles opérations sont effectivement terminées/commitées. + +## 16. Modèle d'erreurs et outcome terminal + +Séparer les familles suivantes : + +```text +invalid job request +unsupported scope/direction +Transport unavailable/timeout/rate-limit +RPC application error +transaction missing/null +RAW conversion invalid +Store unavailable +Store conflict +network mismatch +cancellation +internal invariant violation +``` + +Les erreurs publiques/notifications doivent exposer des codes sûrs et stables, pas les erreurs provider/backend brutes. + +Ne pas mettre une `String` libre contenant le message serveur dans `JobSnapshot`. + +## 17. Configuration et composition + +### 17.1 Ownership Config + +Le job ne lit pas `.env` directement. + +La composition doit utiliser les mécanismes Config existants si des settings sont nécessaires. + +`pre.001` doit décider si `0.3.6` nécessite : + +```text +nouvelle section std.jobs ? +settings programmatic only pour le premier job ? +profil Transport avec rôle history_backfill déjà suffisant ? +``` + +Ne pas ajouter un nouveau schema Config si aucun consumer réel ne le nécessite. + +### 17.2 Injection + +Direction préférée : + +```text +composition/app + -> construit Transport + -> construit Store + -> construit Job settings/request + -> construit ksp-job-backfill-lib avec handles abstraits/publics +``` + +Le frontend futur ne fournit jamais : + +```text +provider URL +Store URI +secret API key +SQL +raw endpoint choice +``` + +## 18. Notifications et future application `0.3.7` + +Le contrat de `0.3.6` doit être suffisant pour qu'en `0.3.7` une application puisse afficher sans introspection privée : + +```text +job identity/type +state +phase courante +scope/range sûr +selected/completed counters +inserted/skipped/missing/conflict counters utiles +progression bornée si total connu +frontière/checkpoint +retry/wait state si observable +cancel requested / cancelling +terminal outcome +safe error code +``` + +Le graphique/monitor ne doit pas avoir besoin de parser les logs pour connaître l'état du job. + +Les logs restent diagnostic ; `ksp-job-api` est le contrat de monitoring. + +## 19. Alignement futur Worker + +Le ROADMAP après `0.3.7` est désormais : + +```text +0.3.8 ksp-worker-api +0.3.9 ksp-worker-live-transactions-retriever-lib +0.3.10 application monitoring/visualisation Jobs + Workers +``` + +### 19.1 `ksp-worker-api` + +Le futur Worker API décrira des services continus, pas des jobs terminables. + +Il devra reprendre la discipline de notification de Job : + +```text +identity +state +health/progress +snapshot +sequence/observation +safe errors +listener isolation +``` + +mais avec un lifecycle continu adapté : start/running/reconfigure/stop/failure plutôt que completed job. + +### 19.2 `ksp-worker-live-transactions-retriever-lib` + +Le futur worker live devra : + +```text +consommer ksp-onchain-transport-lib +utiliser WS/Yellowstone/HTTP complémentaire selon architecture +projeter/persister RawTransaction via Store +émettre ses notifications via ksp-worker-api +rester provider-neutral au niveau métier +réutiliser la pipeline RAW commune seulement si elle a été justifiée +``` + +`0.3.6` ne doit pas implémenter ce worker, mais ne doit pas rendre sa future réutilisation impossible par un couplage du backfill à HTTP/provider/Store PostgreSQL. + +## 20. Audit obligatoire de `0.3.6-pre.001` + +Avant toute implémentation lourde, produire un audit écrit couvrant **toutes** les catégories suivantes. + +### 20.1 Gouvernance et architecture KSP + +Relire au minimum : ```text RULES.md @@ -186,247 +1057,417 @@ docs/architecture/003-COMPONENT_CONTRACTS.md docs/architecture/004-COMPONENT_INVENTORY.md docs/architecture/005-DEPENDENCY_GRAPH.md docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md -crates/ksp-store-api/** -crates/ksp-store-lib/** -crates/ksp-onchain-transport-lib/** ``` -Puis auditer explicitement : +Noter que `009-ACQUISITION_WORKERS_AND_JOBS.md` peut encore employer l'ancien nom conceptuel `ksp-job-backfill` : `0.3.6` doit le réconcilier vers `ksp-job-backfill-lib` lors de la documentation durable appropriée. -### 4.1 Transport historique +### 20.2 Surfaces de code KSP -Vérifier dans le code KSP et dans la documentation officielle actuelle : +Auditer au minimum : + +```text +Cargo.toml workspace +crates/ksp-core-lib/** +crates/ksp-onchain-transport-lib/** +crates/ksp-store-api/** +crates/ksp-store-lib/** +crates/ksp-store-postgres-lib/** seulement pour comprendre la frontière, pas pour créer une dépendance +crates/ksp-config-lib/** si Config doit composer le job +crates/ksp-logging-lib/** pour conventions runtime +``` + +### 20.3 Archive kbot3 + +Auditer l'archive fournie et construire une table avec colonnes au minimum : + +```text +fonction historique +preuve fichier/test/run +sémantique réelle +statut KSP: REPRENDRE / REDESSINER / REPORTER / REJETER +owner KSP cible +risque / différence avec KSP actuel +prerelease cible +``` + +### 20.4 RPC officiels actuels + +Réauditer : ```text getSignaturesForAddress getTransaction ``` -Pour `getSignaturesForAddress`, confirmer notamment : +et toute limite actuelle nécessaire à la verticale. + +### 20.5 Notifications + +Produire une matrice comparant au moins : ```text -ordre newest -> oldest -before -until -limit -commitment -minContextSlot -sémantique de fin de pagination -cardinalité/limites réellement supportées +snapshot polling par caller +callback/sink +watch/latest-value +broadcast/fan-out +bounded queue ``` -Pour `getTransaction`, confirmer notamment : +selon : ```text -commitment supporté -encoding retenu -maxSupportedTransactionVersion -null / transaction unavailable -slot -blockTime -meta / transaction completeness +runtime-neutralité API +backpressure +multi-listener +terminal delivery +resynchronisation +testabilité +future réutilisation Worker ``` -Ne pas inventer une capacité de scan global de toutes les transactions si le RPC standard ne l'offre pas. +Ne pas choisir la primitive avant cet audit. -### 4.2 Store - -Inventorier les capacités `RawTransaction*` réellement disponibles et vérifier comment le job doit : - -```text -écrire canonical + observation -traiter l'idempotence -traiter un conflit réel -éviter une réhydratation implicite d'un tombstone -respecter le RawNetworkId du Store -``` - -Le job consomme `ksp-store-lib`; il ne bypass pas la façade pour parler à `ksp-store-api` ou au backend PostgreSQL directement sauf preuve architecturale contraire explicite. - -### 4.3 Checkpoint et reprise - -Définir ce qui constitue un checkpoint fiable pour une pagination newest -> oldest par adresse. - -Le checkpoint doit être distingué de : - -```text -cursor Store -signature candidate courante -signature réellement persistée -frontière contiguë complétée -simple compteur de progression -``` - -La cancellation et une reprise doivent éviter de sauter silencieusement une transaction non terminée. - -Ne pas créer une table Job dans Store par réflexe. Si une persistence de checkpoint devient nécessaire, l'ownership et le besoin doivent être démontrés avant toute migration. - -### 4.4 Retry et erreurs - -Séparer : - -```text -retry Transport déjà possédé par Transport -retry métier du job -provider rate limit / Retry-After -transaction null/indisponible -conflit Store -cancellation -échec terminal -``` - -Éviter les doubles boucles de retry Transport + Job qui amplifient involontairement les appels réseau. - -### 4.5 Logging - -Le job concret étant comportemental, utiliser `ksp-logging-lib` si logging runtime nécessaire et respecter les conventions KSP de `TRACING_TARGET` / `constants.rs`. - -Ne jamais logguer : - -```text -URL/secret provider -payload transaction complet -credentials -SQL -bytes sensibles inutiles -``` - -Les signatures peuvent apparaître uniquement si les règles de logging KSP et le besoin opérationnel l'autorisent explicitement ; ne pas les rendre automatiquement via `Debug`. - -## 5. Livrables obligatoires de `pre.001` +## 21. Livrables obligatoires de `pre.001` Créer : ```text -docs/plans/027-V0_3_6_JOB_API_RAW_BACKFILL_PLAN.md -docs/validation/023-V0_3_6_JOB_API_RAW_BACKFILL.md +docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md +docs/validation/023-V0_3_6_JOB_API_BACKFILL.md deltas/0.3.6/pre.001.md ``` Le plan doit contenir au minimum : ```text -inventaire des contrats existants -matrice ownership API Job / job concret / Transport / Store -choix ou rejet du backfill RawTransaction par adresse -modèle de pagination/checkpoint/reprise -modèle cancellation/progression/outcome -risques de double retry et de gaps historiques -choix de crate(s) minimal -forecast des prereleases -critères de clôture +1. inventaire réel des crates/surfaces KSP +2. matrice fonctionnelle kbot3 -> KSP +3. matrice ownership Job API / Backfill / Transport / Store / Config / Logging / future Worker +4. surface publique candidate ksp-job-api +5. lifecycle et invariants d'état +6. modèle notification/listener/backpressure/resynchronisation +7. scopes/directions/anchors du backfill retenus +8. pagination RPC et limites officielles +9. modèle candidat/hydratation/déduplication +10. projection vers RawTransaction + observation +11. idempotence/conflits/missing/tombstone +12. modèle de frontier/checkpoint/reprise +13. cancellation matrix +14. retry/rate-limit ownership matrix +15. concurrency/bounds +16. logging/security +17. Config/composition si nécessaire +18. tests/live proof plan +19. dependency graph cible +20. forecast des prereleases avec critères d'entrée/sortie +21. critères de clôture de release +22. liste explicite des fonctionnalités kbot3 reportées/rejetées ``` -`pre.001` peut faire évoluer `Cargo.toml` vers `0.3.6-pre.1`, mais ne doit pas créer de code fonctionnel lourd simplement pour remplir la tranche. +`pre.001` peut créer les deux crates en scaffold **uniquement si** les règles de prompt/versioning et le sizing le justifient, mais ne doit pas masquer l'audit sous une grosse implémentation. -## 6. Direction préférée pour le premier backfill +## 22. Surface publique candidate — règles de conception -Si l'audit confirme le candidat, viser une verticale minimale : +La surface exacte est décidée en `pre.001`, mais les règles sont : ```text -adresse explicite -+ réseau explicite via Store/Transport configurés -+ commitment explicite -+ plage/bornes explicites si supportables sans fausse précision -+ pagination getSignaturesForAddress -+ hydratation getTransaction -+ conversion RAW -+ write via ksp-store-lib -+ progression observable -+ cancellation propre -+ checkpoint/reprise déterministes +champs privés +constructeurs/accessors explicites +#[non_exhaustive] sur enums publics évolutifs si approprié +Debug borné/redacted +pas de serde par défaut sans wire réel +pas de Any +pas de Stringly-typed state machine +pas de payload RAW dans Job API +pas de provider metadata +pas de backend Store type +pas de Tokio type public dans ksp-job-api +pas d'Option-soup contradictoire ``` -Le premier job n'a pas à devenir un crawler global multi-address/provider ou un scheduler de production. +Prévoir des tests external consumer/implementation lorsque l'API comporte des traits extensibles. -## 7. Tests attendus à terme +## 23. Tests attendus pendant la release -Prévoir selon l'implémentation : +### 23.1 `ksp-job-api` + +Prévoir au minimum : ```text -unit tests Job API -public API canaries -external implementation/consumer -pagination newest -> oldest -checkpoint contigu / reprise -cancellation avant/pendant fetch et avant/pendant persistence -idempotence Store -conflit Store terminal et sûr -null getTransaction -rate-limit / retry ownership -no secret/payload debug leak +lifecycle variants distincts +transitions/invariants si l'API les encode +snapshot/progress bornés +terminal outcomes distincts +safe Debug +notification sequence/order contract +external consumer +public API canary manifest/dependency firewall +absence runtime/provider/Store backend +future enum evolvability ``` -Un smoke Devnet opt-in peut être ajouté seulement s'il apporte une preuve que les fixtures ne peuvent pas apporter. Aucun test live payant n'est requis. +### 23.2 `ksp-job-backfill-lib` -## 8. Hors périmètre `0.3.6` +Prévoir au minimum : ```text -application desktop de backfill/inspection (0.3.7) -worker RAW live continu +request validation +latest/before/after/explicit selon scope admis +after sans anchor rejeté si applicable +nonzero limits/bounds +déduplication candidates/pages +pagination newest -> oldest +nearest-newer/gap behavior si repris +getTransaction null/missing +conversion RAW exacte +idempotent rerun +Store conflict +network mismatch +frontier contiguë avec completions hors ordre +resume après cancellation +cancel avant work +cancel pendant discovery +cancel pendant long RPC +cancel pendant wait/backoff +cancel autour de persistence +bounded concurrency +retry ownership sans amplification +listener lent isolé +notification terminale +progress snapshot cohérent +no secret/provider URL/raw payload leak +``` + +### 23.3 Intégration + +Utiliser des fakes/fixtures aux frontières publiques lorsque possible. + +Un smoke Devnet opt-in peut être ajouté si nécessaire pour prouver : + +```text +Transport réel -> backfill -> Store réel/configuré -> notifications observables +``` + +Aucun service payant n'est requis pour fermer la release. + +Un test PostgreSQL réel ne doit être ajouté que si la verticale Job introduit une sémantique impossible à prouver avec les tests Store déjà existants ; ne pas refaire gratuitement toute la validation PostgreSQL de `0.3.3/0.3.4`. + +## 24. Hardening obligatoire + +Avant clôture : + +```text +hostile JobId/descriptor/scope si textual +oversized candidate sets +pathological limits/concurrency +slow listener +listener drop/disconnect +notification storm +cancellation races +out-of-order completion +repeated cancellation +Transport transient + Job cancellation race +Store commit + cancellation race +Store conflict +missing transaction sequences +duplicate pages/candidates +Debug/log redaction +no env bypass +no backend leakage +no unbounded queue +``` + +Si un compteur peut overflow, définir la stratégie (`u64`, saturating ou erreur) explicitement au lieu de laisser un comportement implicite. + +## 25. Hors périmètre `0.3.6` + +```text +application desktop finale de backfill/inspection # 0.3.7 +ksp-worker-api # 0.3.8 +ksp-worker-live-transactions-retriever-lib # 0.3.9 +application générale monitoring Jobs/Workers # 0.3.10 +worker live continu scheduler global queue distribuée cron engine +orchestrateur multi-host +persistence générique de tous les jobs par réflexe STRUCTURAL/DECODED/DOMAIN Program decoding materialization nouveau backend Store -nouvelle persistence RawAccountState -réouverture des migrations RAW PostgreSQL sans nécessité démontrée -event bus Interface -persistence Job ajoutée par réflexe -support provider-specific payant requis pour fermer la release +réécriture de ksp-onchain-transport-lib en client dédié Job +nouvelle migration RAW PostgreSQL sans besoin démontré +nouvelle crate générique task/runtime/observer sans duplication concrète +réutilisation/copier-coller de code kbot3 +support provider payant obligatoire ``` -## 9. Archive historique kbot3 +## 26. Dependency firewalls à verrouiller -L'archive kbot3 **n'est pas requise** pour démarrer ou fermer `0.3.6`. - -La source de vérité est : +Cibles minimales : ```text -base KSP stable v0.3.5 -règles/architecture KSP actuelles -surfaces Transport/Store réelles -contrats RPC officiels actuels +ksp-job-api + -> dépendances fondamentales strictement nécessaires seulement + -X-> ksp-onchain-transport-lib + -X-> ksp-store-lib + -X-> ksp-config-lib + -X-> ksp-logging-lib si l'API reste purement passive + -X-> tokio / reqwest / tonic / tauri + +ksp-job-backfill-lib + -> ksp-job-api + -> ksp-onchain-transport-lib + -> ksp-store-lib + -> ksp-logging-lib + -> Config/Core seulement si justifiés + -X-> ksp-store-postgres-lib + -X-> postgres drivers + -X-> reqwest direct + -X-> provider SDK + -X-> tauri ``` -Si une comparaison avec un ancien mécanisme de backfill kbot3 devient utile pendant le brainstorming, elle peut être fournie comme référence historique uniquement ; elle ne doit pas être copiée comme architecture normative. +Les graphes exacts doivent être prouvés par tests/manifests et `cargo tree` à la clôture. -## 10. Cadence provisoire +## 27. Cadence provisoire de prereleases -Ne pas figer le nombre exact de prereleases avant le sizing de `pre.001`. Une trajectoire raisonnable à confirmer est : +`pre.001` doit faire le sizing final. La trajectoire de départ est : ```text -pre.001 audit + brainstorming + sizing + plan -pre.002 ksp-job-api minimal -pre.003 première verticale backfill RawTransaction -pre.004 checkpoint/reprise/cancellation + canaris externes -pre.005 hardening + intégration Store/Transport -pre.006 gate technique final -pre.007 réconciliation documentaire -pre.008 préparation de publication -rel.001 stable +pre.001 règles + audit KSP/kbot3/officiel + brainstorming + sizing + plan +pre.002 ksp-job-api foundation + lifecycle/snapshot/outcome + canaris +pre.003 notifications/listener contract + backpressure/resync + API alignment +pre.004 ksp-job-backfill-lib foundation + request/scope/candidates/pagination +pre.005 getTransaction hydration + RAW conversion + Store persistence/idempotence +pre.006 directions/anchors + frontier/checkpoint/reprise + bounded concurrency +pre.007 cancellation/retry/rate-limit ownership + notification integration complète +pre.008 external canaries + adversarial hardening + live proof si justifiée +pre.009 gate technique final complet + cargo trees +pre.010 réconciliation documentaire finale + transfert TODO/IDEAS +pre.011 préparation de publication + prompt 0.3.7 +rel.001 stable 0.3.6 ``` -La release doit rester dimensionnée pour **une session maximum**. Si le premier job réel exige nettement plus, réduire le scope plutôt que d'introduire une architecture partielle non fermable. +Cette séquence est **un forecast**, pas une obligation de produire des prereleases vides. -## 11. Gate opérateur de base +Si une tranche se révèle plus petite, fusionner raisonnablement. Si un problème structurel réel apparaît, insérer un fix/prerelease et décaler la clôture plutôt que de masquer le manque. -Après les tranches Rust significatives : +L'objectif « une version = une session maximum » reste une contrainte de sizing. Pour la respecter, réduire une fonctionnalité non essentielle ou reporter explicitement un mode de backfill plutôt que livrer une API incohérente ou une notification non testée. -```text +## 28. Gate opérateur + +Après chaque tranche Rust significative : + +```bash cargo fmt --all 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.6 cargo check --workspace cargo clippy --workspace --all-targets cargo test -p ksp-job-api +cargo test -p ksp-job-backfill-lib ``` -Ajouter les tests ciblés des crates concrètement modifiées. Le gate technique final doit inclure `cargo test --workspace` et les graphes Cargo pertinents. +Ajouter les tests des crates réellement touchées : -## 12. Règle de décision +```bash +cargo test -p ksp-onchain-transport-lib +cargo test -p ksp-store-api +cargo test -p ksp-store-lib +cargo test -p ksp-config-lib +``` -Si le brainstorming de `pre.001` montre que `getSignaturesForAddress + getTransaction` ne permet pas un premier backfill suffisamment exact, reprenable et testable sans élargissement excessif, **ne pas forcer cette verticale**. Documenter le blocage, choisir le plus petit backfill RAW réellement démontrable, et préserver les frontières Job / Transport / Store. +seulement lorsque la tranche les modifie ou lorsque la preuve d'intégration le nécessite. + +Gate technique final minimal : + +```bash +cargo fmt --all +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.6 +cargo check --workspace +cargo clippy --workspace --all-targets +cargo test -p ksp-job-api +cargo test -p ksp-job-backfill-lib +cargo test --workspace +cargo tree -p ksp-job-api --edges normal +cargo tree -p ksp-job-backfill-lib --edges normal +cargo tree -p ksp-job-api -e features +cargo tree -p ksp-job-backfill-lib -e features +cargo tree --duplicates +``` + +Ajouter les preuves live opt-in décidées par le plan avant la réconciliation documentaire finale. + +## 29. Critères de clôture `0.3.6` + +La release n'est pas fermable tant que les points suivants ne sont pas démontrés : + +```text +[ ] ksp-job-api existe et est consommable depuis le crate-root +[ ] ksp-job-backfill-lib est aligné sur cette API, sans contrat lifecycle parallèle +[ ] la matrice fonctionnelle kbot3 est documentée avec chaque fonction classée +[ ] le scope RawTransaction historique retenu fonctionne de bout en bout +[ ] getSignaturesForAddress et getTransaction passent exclusivement par Transport +[ ] writes passent exclusivement par ksp-store-lib +[ ] déduplication/idempotence/missing/conflit sont distincts +[ ] frontier/checkpoint ne saute jamais un trou incomplet +[ ] cancellation est coopérative sur les phases critiques +[ ] retry Job n'amplifie pas silencieusement retry Transport +[ ] concurrency/bounds sont explicites +[ ] lifecycle/progress/outcome sont observables sans parser les logs +[ ] notifications/listeners sont bornés et un consumer lent n'arrête pas le job +[ ] un observer peut se resynchroniser sur un snapshot courant +[ ] aucune URL/credential/payload RAW/SQL n'est exposé par notification/Debug/log public +[ ] ksp-job-api n'impose aucun runtime +[ ] ksp-job-backfill-lib ne dépend d'aucun backend Store physique/provider SDK +[ ] les canaris external consumer/dependency/hardening passent +[ ] cargo test --workspace passe +[ ] les cargo trees confirment les firewalls +[ ] documentation durable et ROADMAP sont réconciliés +``` + +## 30. Livrables de clôture + +À la réconciliation finale, auditer au minimum : + +```text +README.md +ROADMAP.md +CHANGELOG.md +docs/architecture/002-LAYERS_AND_DEPENDENCIES.md +docs/architecture/003-COMPONENT_CONTRACTS.md +docs/architecture/004-COMPONENT_INVENTORY.md +docs/architecture/005-DEPENDENCY_GRAPH.md +docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md +crates/ksp-job-api/README.md +crates/ksp-job-api/USAGE.md +crates/ksp-job-backfill-lib/README.md +crates/ksp-job-backfill-lib/USAGE.md +docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md +docs/validation/023-V0_3_6_JOB_API_BACKFILL.md +``` + +Les `USAGE.md` doivent rester version-neutral et ne jamais contenir les résultats du gate ou le journal des prereleases. + +La publication doit préparer le prompt `0.3.7` pour l'application spécialisée de backfill/inspection consommant les contrats de notification Job stabilisés. + +## 31. Règle finale de décision + +`0.3.6` n'est pas une réécriture de kbot3 et n'est pas non plus un petit exercice de scaffold. + +La règle est : + +```text +reprendre les capacités utiles ++ redessiner selon les frontières KSP actuelles ++ les rendre observables et testables ++ fermer une verticale RawTransaction historique réelle +``` + +Si l'audit `pre.001` découvre une fonction kbot3 importante non couverte par ce prompt, ne pas l'ignorer : la classer explicitement `REPRENDRE`, `REDESSINER`, `REPORTER` ou `REJETER`, puis ajuster le forecast avant implémentation. + +Si une fonction ne peut pas être fermée correctement dans `0.3.6` sans ouvrir Worker/STRUCTURAL/DECODED ou un scheduler global, la reporter avec trace durable plutôt que casser les frontières.