Files
khadhroony-solana-project/prompts/025-V0_3_6_START_PROMPT.md

1474 lines
41 KiB
Markdown

<!-- file: prompts/025-V0_3_6_START_PROMPT.md -->
<!-- version: 2 -->
# 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.