# Prompt de démarrage `0.3.6` — Job API + backfill RAW observable ## 1. Contexte de reprise La base attendue est la release stable : ```text v0.3.5 ``` La surface acquise doit notamment être : ```text ksp-store-api -> 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 -> 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 -> contrats Program passifs historiques -> SlotLifecycleEvent / SlotLifecycleStage -> TransactionSignature / TransactionExecutionEvent / TransactionExecutionOutcome -> 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é les frontières suivantes : ```text 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 désormais explicitement : ```text 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 ``` `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. 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. ## 2. Règle de lecture du prompt Avant toute modification, relire et appliquer les documents de gouvernance KSP, en particulier : ```text 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 getSignaturesForAddress via ksp-onchain-transport-lib | v candidats dédupliqués + pagination/direction/anchors | v 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 ``` La release doit fermer cette verticale de bout en bout, pas seulement créer des types d'API et un squelette de job. ## 4. Sources de vérité et rôle de kbot3 ### 4.1 Sources normatives L'ordre d'autorité est : ```text 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 ``` ### 4.2 Archive kbot3 obligatoire en `pre.001` L'archive historique fournie par l'opérateur : ```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 queue distribuée cron engine service registry global backend de persistence SQL repository client Transport Config runtime Tauri/IPC ``` 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 JobPhase JobProgress JobSnapshot JobCheckpoint ou frontier observable JobStopReason JobOutcome JobNotification JobNotificationSequence JobListener / JobNotificationSink / équivalent cancellation handle/token contract si réellement API-owned ``` Ne pas créer un enum/struct pour chaque nom de cette liste par obligation. ### 7.3 Lifecycle Le lifecycle doit être impossible à interpréter de deux façons. Candidat conceptuel à auditer : ```text Created/Queued Starting Running Retrying ou Waiting si distinct observable Cancelling Completed Cancelled Failed ``` Éviter : ```text 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 ``` ### 11.1 Pipeline RAW partagée : décision différée mais audit obligatoire `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. `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 ROADMAP.md CHANGELOG.md docs/000-README.md docs/PROMPT_STRUCTURE.md docs/VERSION_WORKFLOW.md docs/FILE_CONTRACTS.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 ``` 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. ### 20.2 Surfaces de code KSP 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 ``` et toute limite actuelle nécessaire à la verticale. ### 20.5 Notifications Produire une matrice comparant au moins : ```text snapshot polling par caller callback/sink watch/latest-value broadcast/fan-out bounded queue ``` selon : ```text runtime-neutralité API backpressure multi-listener terminal delivery resynchronisation testabilité future réutilisation Worker ``` Ne pas choisir la primitive avant cet audit. ## 21. Livrables obligatoires de `pre.001` Créer : ```text 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 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 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. ## 22. Surface publique candidate — règles de conception La surface exacte est décidée en `pre.001`, mais les règles sont : ```text 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 ``` Prévoir des tests external consumer/implementation lorsque l'API comporte des traits extensibles. ## 23. Tests attendus pendant la release ### 23.1 `ksp-job-api` Prévoir au minimum : ```text 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 ``` ### 23.2 `ksp-job-backfill-lib` Prévoir au minimum : ```text 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 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 ``` ## 26. Dependency firewalls à verrouiller Cibles minimales : ```text 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 ``` Les graphes exacts doivent être prouvés par tests/manifests et `cargo tree` à la clôture. ## 27. Cadence provisoire de prereleases `pre.001` doit faire le sizing final. La trajectoire de départ est : ```text 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 ``` Cette séquence est **un forecast**, pas une obligation de produire des prereleases vides. 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. 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. ## 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 des crates réellement touchées : ```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 ``` 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.