v0.3.9-pre.001

This commit is contained in:
2026-09-04 12:47:53 +02:00
parent 85f292a36d
commit 92f08ca5a8
3 changed files with 958 additions and 0 deletions

187
deltas/0.3.9/pre.001.md Normal file
View File

@@ -0,0 +1,187 @@
<!-- file: deltas/0.3.9/pre.001.md -->
<!-- version: 1 -->
# Delta `0.3.9-pre.001` — audit, architecture et sizing Worker API
## Base requise
```text
archive stable fournie : khadhroony-solana-project-v0.3.8.zip
workspace.package.version = 0.3.8
delta stable = deltas/0.3.8/rel.001.md
prompt = prompts/028-V0_3_9_START_PROMPT.md
```
## Type de livraison
```text
ksp-doc-0.3.9-pre.001.zip
```
La livraison est strictement documentaire et contient uniquement les deux nouveaux documents `docs/` et le présent delta.
## Objectif
Ouvrir `0.3.9` par le gate documentaire imposé : vérification complète des archives/règles, audit de `ksp-job-api` comme référence de propriétés, décision de larchitecture générique `ksp-worker-api`, threat map, tests et sizing, **sans créer la crate Worker ni commencer laudit fonctionnel RAW provider**.
## Vérification des archives
```text
KSP SHA-256 = b3a34a3dfd56fac1eef3d23f13631ff001338b612834488038cf259112c63624
KSP entries = 1809
KSP unzip -t = PASS
kbot3 SHA-256 = ee47643b9f8b582ee8db97b2381ec107e45aef8c009fee44757531514615d318
kbot3 entries = 2501
kbot3 unzip -t = PASS
```
Aucune entrée absolue/traversal/symlink et aucun `target`, `node_modules`, `.git`, `Cargo.lock` ou `.env` livré na été détecté.
La source de code reste exclusivement KSP `v0.3.8`. kbot3 na pas été utilisé pour concevoir Worker API ; son futur usage est réservé à la référence **fonctionnelle historique** lors de laudit RAW après freeze.
## Audits baseline exécutés avant modification
```text
python3 scripts/audit_rust_workspace_rules.py
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
Markdown table audit: clean (316 table(s), 725 file(s))
```
Le binaire `cargo` est absent de lenvironnement dassemblage. Les commandes Cargo de baseline et `cargo tree -p ksp-job-api` sont donc **non exécutées et non PASS** localement. Le manifest de `ksp-job-api` a néanmoins été audité statiquement : une seule dépendance normale `ksp-core-lib`, aucune feature/dev/build dependency.
## Audits post-modification
Après ajout du plan, de la validation et du présent delta :
```text
python3 scripts/audit_rust_workspace_rules.py
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
Markdown table audit: clean (321 table(s), 728 file(s))
```
Le diff exact contre les bytes du ZIP stable contient uniquement les trois fichiers ajoutés de cette livraison ; aucun fichier de la base nest modifié ou supprimé. Le cache Python créé par laudit local est un artefact ignoré et est supprimé avant packaging.
## Décisions Worker API
Surface V1 prévue :
```text
WorkerId / WorkerKindCode, bornés à 128 octets
WorkerState = Created / Starting / Running / Stopping / Stopped / Faulted(ErrorCode)
WorkerHealth = Unknown / Healthy / Degraded / Unhealthy
WorkerActivity = Unknown / Idle / Active
WorkerLifecycle producteur-owned, terminal immutable
WorkerStopToken coopératif partagé/idempotent
WorkerSnapshotSequence monotone checked
WorkerSnapshot fixe sans payload arbitraire
WorkerSnapshotSource latest-value, Send + Sync et object-safe
Core Error/ErrorCode/ErrorContext/Result
```
Dependency map exact décidé :
```text
ksp-worker-api -> ksp-core-lib uniquement
```
Explicitement exclus : Job API, Interface, Config, Logging, Transport, Store, Tokio, futures, serde, Tauri, provider SDK et toute notion RawTransaction/slot/provider/endpoint/replay/backfill.
Le snapshot commun est volontairement fixe plutôt que générique : le control plane obtient un état uniforme et aucun payload/string libre ne peut entrer dans lAPI Worker. Les métriques métier restent au worker concret.
Restart/retry/process control ne font pas partie de Worker API V1. Un lifecycle/source terminal ne redevient jamais actif et nest jamais rebinding vers une nouvelle instance ; la recréation appartient au caller/futur control plane.
## Recalibrage de la trajectoire
Le noyau API reste en deux tranches de code :
```text
pre.002 contrats
pre.003 hardening + external implementation + freeze fonctionnelle
```
Laudit RAW initialement regroupé en une tranche est scindé afin de respecter le budget KSP :
```text
pre.004 Solana standard + inventaire KSP
pre.005 Helius/Yellowstone/providers + kbot3 fonctionnel historique
pre.006 synthèse multi-source + handoff 0.3.10/0.3.12
pre.007 gate technique final
pre.008 réconciliation documentaire
pre.009 préparation publication
rel.001 publication stable
```
Lowner prévu du document daudit final est `docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md`, créé seulement après freeze de Worker API.
## Fichiers ajoutés
```text
docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md
docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md
deltas/0.3.9/pre.001.md
```
## Fichiers modifiés
```text
aucun
```
## Fichiers supprimés
```text
aucun
```
## Version Cargo
Aucun code/build/runtime/config nest modifié. Conformément à lautorisation explicite du prompt 028 pour ce premier gate doc-only :
```text
workspace.package.version reste 0.3.8
```
## Non inclus
```text
aucune crate ksp-worker-api créée
aucun Rust modifié
aucun Cargo.toml modifié
aucun worker RawTransaction
aucune modification Transport/Config/Store
aucun endpoint/profil Helius
aucun nouveau secret
aucun audit provider courant déclaré réalisé
aucune analyse fonctionnelle kbot3 encore réalisée
aucune modification CHANGELOG/ROADMAP
```
## Validations non exécutées
```text
cargo fmt/check/clippy/test/tree : cargo absent du sandbox
sources externes RAW : réservées après freeze Worker API
smoke réseau/provider : hors pre.001
```
## Questions différées
```text
WorkerHandle/start/join générique
registry/factory/restart generation
reconfiguration live
remote protocol/IPC
serialization commune
metrics métier universelles
```
Elles ne sont pas nécessaires au contrat générique V1 et ne doivent pas élargir `pre.002` sans preuve.

View File

@@ -0,0 +1,567 @@
<!-- file: docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md -->
<!-- version: 1 -->
# Plan v0.3.9 — Worker API générique + audit RAW Transaction
## 1. But de la version
La version `0.3.9` a deux responsabilités successives et volontairement séparées :
```text
1. stabiliser ksp-worker-api comme lifecycle API générique de services continus ;
2. seulement après sa freeze fonctionnelle, auditer exhaustivement les voies dacquisition RawTransaction afin de préparer 0.3.10.
```
Aucun besoin Solana, provider, Store, endpoint, replay ou backfill ne doit influencer le contrat générique de `ksp-worker-api` avant sa freeze.
## 2. Base autoritaire et vérification douverture
Base fournie et vérifiée le 4 septembre 2026 :
```text
archive KSP : khadhroony-solana-project-v0.3.8.zip
workspace.package.version : 0.3.8
delta stable : deltas/0.3.8/rel.001.md
prompt : prompts/028-V0_3_9_START_PROMPT.md
```
Preuves darchive :
```text
KSP SHA-256 = b3a34a3dfd56fac1eef3d23f13631ff001338b612834488038cf259112c63624
KSP entries = 1809
KSP raw bytes = 19667131
KSP unzip -t = PASS
kbot3 SHA-256 = ee47643b9f8b582ee8db97b2381ec107e45aef8c009fee44757531514615d318
kbot3 entries = 2501
kbot3 raw bytes = 37467702
kbot3 unzip -t = PASS
```
Les deux ZIP ont été contrôlés sans entrée absolue, traversal, lien symbolique, `target/`, `node_modules/`, `.git/`, `Cargo.lock` ou `.env` livré.
Le ZIP stable ne contient volontairement pas les métadonnées Git ; le tag `v0.3.8` nest donc pas réinspectable depuis `.git`. La base est néanmoins admissible selon le prompt car lopérateur la fournie explicitement comme archive stable, sa version Cargo vaut `0.3.8` et son `rel.001` exige puis décrit le tag stable `v0.3.8`.
### 2.1 Membres structurants confirmés
```text
ksp-app-store-desk
ksp-job-api
ksp-job-backfill-lib
ksp-onchain-transport-lib
ksp-config-lib
ksp-store-api
ksp-store-lib
ksp-store-postgres-lib
```
Le workspace stable comporte 18 membres et ne contient pas encore `ksp-worker-api`.
### 2.2 Baseline locale avant modification
Exécuté sur larchive KSP inchangée :
```text
python3 scripts/audit_rust_workspace_rules.py
General Rust rule audit: clean
Rust export completeness audit: 0 candidate(s)
KSP workspace Rust rule audit: clean
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates deltas
Markdown table audit: clean (316 table(s), 725 file(s))
```
Le binaire `cargo` nest pas installé dans lenvironnement dassemblage. Les commandes Cargo de baseline, dont `cargo fmt --all -- --check`, `cargo check --workspace`, `cargo clippy --workspace --all-targets` et `cargo tree -p ksp-job-api`, sont donc **non exécutées ici et non déclarées PASS**. La preuve stable du delta `0.3.8-rel.001` rappelle quun gate opérateur complet avait été fermé en amont ; elle ne remplace pas une exécution locale de cette session.
## 3. Sources internes lues avant décision
Les règles et architectures demandées par le prompt ont été auditées avant la présente planification :
```text
RULES.md
ROADMAP.md
CHANGELOG.md
docs/000-README.md
docs/rules/RULES_GENERAL.md
docs/rules/RULES_KSP.md
docs/rules/RULES_RUST.md
docs/rules/RULES_DEPENDENCIES.md
docs/rules/RULES_DOCUMENTATION.md
docs/rules/FILE_CONTRACTS.md
docs/rules/VERSION_WORKFLOW.md
docs/rules/PROMPT_STRUCTURE.md
docs/architecture/000-README.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
docs/architecture/010-APPS_SERVICES_SCENARIOS_AND_CONTROL.md
ksp-job-api manifest/README/USAGE/src/tests
docs/plans/027-V0_3_6_JOB_API_BACKFILL_PLAN.md
docs/validation/023-V0_3_6_JOB_API_BACKFILL.md
ksp-job-backfill-lib README/USAGE/src/tests
ksp-app-backfill-desk README/USAGE
docs/plans/028-V0_3_7_BACKFILL_DESK_PLAN.md
docs/validation/024-V0_3_7_BACKFILL_DESK.md
```
Les headers/version des fichiers normatifs et architecturaux exigés sont présents et cohérents. Aucun document stable antérieur nest modifié dans `pre.001`.
## 4. Frontière Worker / Job décidée
Règle sémantique de base :
```text
Job = traitement borné/terminable, fin normale et outcome attendus.
Worker = service continu, Running peut durer indéfiniment, arrêt normal sans notion de completion.
```
`ksp-job-api` est une référence de **propriétés déjà prouvées**, pas un parent nominal de Worker et pas une dépendance.
| Concept Job audité | Propriété générique | Décision Worker API | Motif |
|---------------------------|-----------------------------------------|---------------------------------|--------------------------------------------------------|
| JobId borné | oui | WorkerId propre | même propriété, identité sémantiquement distincte |
| JobKindCode borné | oui | WorkerKindCode propre | famille stable utile au contrôle sans dépendre de Job |
| Created | oui | WorkerState::Created | état passif avant démarrage |
| Running | oui | WorkerState::Running | un Worker peut y rester indéfiniment |
| Cancelling | non nominalement | WorkerState::Stopping | un service sarrête, il ne termine pas un Job annulé |
| Completed + JobCompletion | non | interdit | un Worker continu na pas de completion normale |
| Cancelled | non | WorkerState::Stopped | arrêt normal distinct dune annulation de traitement |
| Failed | partiellement | WorkerState::Faulted(ErrorCode) | fault terminal avec diagnostic statique sûr |
| Cancellation token | oui conceptuellement | WorkerStopToken | intention coopérative partagée et idempotente |
| Notification générique S | latest-value oui, payload générique non | WorkerSnapshot fixe | évite payload arbitraire et simplifie le control plane |
| Sequence monotone | oui | WorkerSnapshotSequence | resynchronisation sans queue |
| SnapshotSource | oui | WorkerSnapshotSource | lecture current + wait_for_change runtime-neutral |
| Terminal immuable | oui | retenu | ancien handle/source ne peut pas être réactivé |
| Checkpoint / resume | non | interdit | spécifique aux Jobs/backfills |
| Outcome / résultat | non | interdit | spécifique à un traitement terminable |
| Core-only | oui | retenu | API passive et dependency firewall minimal |
Conséquence : une duplication limitée de petites primitives (`WorkerId`, séquence, token stop) est intentionnelle. Elle maintient deux vocabulaires de lifecycle indépendants et évite quune future évolution Job force Worker ou inversement.
## 5. Surface publique Worker API prévue
`pre.002` doit ouvrir uniquement le noyau suivant, sous réserve dun défaut réel découvert lors de sa matérialisation :
```text
WorkerId
WorkerKindCode
MAX_WORKER_ID_BYTES = 128
MAX_WORKER_KIND_CODE_BYTES = 128
WorkerState
WorkerHealth
WorkerActivity
WorkerLifecycle
WorkerStopToken
WorkerSnapshotSequence
WorkerSnapshot
WorkerSnapshotFuture<'a>
WorkerSnapshotSource
ERROR_CODE_WORKER_ID_INVALID
ERROR_CODE_WORKER_KIND_INVALID
ERROR_CODE_WORKER_TRANSITION_INVALID
ERROR_CODE_WORKER_SNAPSHOT_SEQUENCE_EXHAUSTED
reexports Core : Error, ErrorCode, ErrorContext, Result
```
Modules de production prévus :
```text
src/lib.rs
src/error.rs
src/identity.rs
src/lifecycle.rs
src/snapshot.rs
src/stop.rs
```
La façade reste crate-root ; aucun `pub mod`.
### 5.1 Identité
`WorkerId` et `WorkerKindCode` utilisent un contrat borné analogue dans ses propriétés à Job mais avec leurs propres types :
```text
non vide
maximum 128 octets
alphabet ASCII sûr : A-Z a-z 0-9 _ - . :
aucun slash, whitespace ou Unicode libre
WorkerId Debug = redacted
WorkerKindCode Debug = valeur validée sûre
```
`WorkerId` identifie linstance logique observée par un lifecycle/source donné. La V1 ne définit aucune notion de génération/restart et ne rebinde jamais un ancien handle/source terminal vers une nouvelle exécution.
## 6. Lifecycle exact retenu
États :
```text
Created
Starting
Running
Stopping
Stopped
Faulted(ErrorCode)
```
| État source | Transitions autorisées | Transitions interdites notables |
|---------------|----------------------------------|-----------------------------------|
| Created | Starting, Stopped | Running direct, Stopping, Faulted |
| Starting | Running, Stopping, Faulted(code) | Stopped direct, Created |
| Running | Stopping, Faulted(code) | Starting, Stopped direct |
| Stopping | Stopped, Faulted(code) | Running, Starting |
| Stopped | aucune | toutes |
| Faulted(code) | aucune | toutes |
Décisions :
- `Created -> Stopped` représente un arrêt demandé avant démarrage effectif ;
- `Starting` et `Stopping` sont nécessaires parce que start/shutdown peuvent avoir une durée non nulle ;
- `Running` na aucune notion de completion ;
- `Faulted(ErrorCode)` ne conserve quun identifiant derreur KSP statique, jamais un message arbitraire ni un `Box<dyn Error>` ;
- `Stopped` et `Faulted` sont terminaux et immuables ;
- `WorkerLifecycle` est producteur-owned et non cloneable ; les clones éventuels concernent le token de stop et la source de snapshot, pas lautorité de transition ;
- une transition invalide retourne une erreur stable et laisse létat inchangé ;
- les appels lifecycle répétés ne sont pas silencieusement idempotents : lidempotence appartient à lintention de stop, pas à la state machine.
### 6.1 Race stop / fault
Le modèle ne crée pas de mutation concurrente de `WorkerLifecycle`. Le runtime concret possède une seule autorité de transition et arbitre les événements. Les ordres légaux sont explicitement testables :
```text
Running -> Faulted => terminal Faulted, stop lifecycle ultérieur rejeté
Running -> Stopping -> Faulted => terminal Faulted, Stopped ultérieur rejeté
Running -> Stopping -> Stopped => terminal Stopped, Faulted ultérieur rejeté
```
Le premier état terminal **validement enregistré** gagne. Un `WorkerStopToken` demandé après terminal peut conserver lintention atomique mais ne réanime ni ne transforme létat terminal.
## 7. Health et activity
`health` est distinct du lifecycle. Il décrit la qualité opérationnelle observée, pas la phase du service :
```text
WorkerHealth::Unknown
WorkerHealth::Healthy
WorkerHealth::Degraded
WorkerHealth::Unhealthy
```
`activity` est volontairement plus faible quun progrès de Job :
```text
WorkerActivity::Unknown
WorkerActivity::Idle
WorkerActivity::Active
```
Aucun `current/total`, pourcentage, ETA, compteur métier, slot, signature, backlog ou débit nentre dans Worker API. Un worker concret peut publier ses métriques métier via sa propre API/snapshot sans les injecter dans le snapshot commun.
Le lifecycle reste autoritaire pour savoir si le service est terminal ; health/activity ne doivent jamais être interprétés comme une seconde state machine.
## 8. Snapshot latest-value décidé
Contrairement à `JobNotification<S>`, Worker V1 retient un snapshot **fixe et non générique** afin que le control plane puisse lire la même forme pour tous les workers et afin dempêcher un payload arbitraire dans le contrat commun.
`WorkerSnapshot` contient uniquement :
```text
WorkerId
WorkerKindCode
WorkerSnapshotSequence
WorkerState
WorkerHealth
WorkerActivity
```
Aucune `String` diagnostique libre, aucun provider, endpoint, payload, transaction, slot, Store reference ou secret.
### 8.1 Séquence
`WorkerSnapshotSequence` :
```text
initial = 0
next = checked_add(1)
aucun wrap silencieux
is_after(observed) pour la resynchronisation
```
Toute modification publiée du snapshot commun avance la séquence exactement une fois. Le détail de stockage/wakeup reste au runtime concret.
### 8.2 Source
Contrat prévu :
```text
trait WorkerSnapshotSource: Send + Sync
current() -> WorkerSnapshot
wait_for_change(observed: WorkerSnapshotSequence) -> WorkerSnapshotFuture<'_>
```
Le trait doit être object-safe pour permettre `&dyn WorkerSnapshotSource` ou une composition équivalente sans imposer Tokio.
Sémantique latest-value :
```text
pas de queue dévénements
pas de callback producteur
les updates intermédiaires peuvent être coalescées
un listener lent reçoit le snapshot courant le plus récent
plusieurs listeners restent indépendants
un listener tardif commence par current()
le snapshot terminal reste lisible tant que la source existe
```
Un appel `wait_for_change` nest attendu quaprès inspection de `current()` et ne doit pas produire de boucle artificielle sur une séquence terminale déjà observée.
## 9. Stop coopératif
`WorkerStopToken` est une primitive runtime-neutral cloneable fondée sur une intention atomique :
```text
request_stop() -> true uniquement pour la première demande partagée
is_stop_requested() -> bool
```
La demande est bornée au sens API : opération atomique locale, non bloquante, sans attente réseau/process/thread. Elle **ne garantit pas** que le worker concret sarrête dans un délai donné. Timeout, drain, join, retry et politique de shutdown appartiennent au runtime/caller.
Le token ne modifie pas directement `WorkerLifecycle`; le producteur observe lintention puis publie `Stopping`/terminal selon sa politique concrète.
## 10. Restart et supervision
La V1 ne contient pas :
```text
restart()
restart policy
retry/backoff policy
scheduler
process manager
remote protocol
registry global
WorkerHandle générique possédant le runtime
```
Restart/recreate appartient au caller ou au futur `ksp-worker-control-lib`. Un lifecycle/source terminal ne redevient jamais Running et nest jamais rebinding vers une nouvelle instance. Cette règle ferme la race « old handle observes a restarted worker » sans introduire prématurément une génération globale.
Un futur control plane peut composer les primitives `WorkerId`/kind/snapshot/stop avec ses propres factories et règles de remplacement.
## 11. Dépendances exactes
Cible décidée :
```text
ksp-worker-api -> ksp-core-lib
```
| Dépendance | Statut prévu | Justification |
|-------------------------------|--------------|---------------------------------------------------------------|
| ksp-core-lib | REQUISE | Error, ErrorCode, ErrorContext et Result communs |
| ksp-job-api | INTERDITE | lifecycle Job distinct ; réutilisation seulement conceptuelle |
| ksp-interface-lib | INTERDITE | aucun événement wire/domain requis |
| ksp-config-lib | INTERDITE | Config/secrets hors API passive |
| ksp-logging-lib | INTERDITE | aucun comportement runtime à instrumenter |
| ksp-onchain-transport-lib | INTERDITE | aucun transport dans le contrat Worker |
| ksp-store-api / ksp-store-lib | INTERDITES | aucune persistence dans le lifecycle commun |
| tokio / futures | INTERDITES | std::future suffit au contrat dattente abstrait |
| serde | INTERDITE | aucun wire/serialization commun imposé |
| Tauri / provider SDK | INTERDITS | contrôle UI/provider hors API |
Le manifeste prévu ne comporte ni feature, ni dev-dependency, ni build-dependency tant quun besoin réel nest pas démontré. Les tests doivent fonctionner avec `std` + dépendance normale Core.
## 12. Error codes et Debug
Domaine prévu :
```text
worker_api
```
Codes prévus :
```text
worker_id_invalid
worker_kind_invalid
worker_transition_invalid
worker_snapshot_sequence_exhausted
```
Les erreurs didentité ne recopient pas la valeur hostile dans message/context ; elles indiquent uniquement le champ fautif. Les erreurs de transition exposent seulement les codes détat source/cible. `Faulted(ErrorCode)` expose un code statique et non une chaîne externe.
Debug :
```text
WorkerId -> valeur masquée
WorkerKindCode -> code sûr borné autorisé
WorkerLifecycle -> id masqué, kind/state sûrs
WorkerStopToken -> bool stop_requested uniquement
WorkerSnapshot -> id masqué, autres champs statiques/bornés
```
## 13. Threat map
| Risque | Mesure décidée | Preuve prévue |
|-------------------------------------|------------------------------------------------------------------------|-----------------------------------|
| queue de notifications non bornée | latest-value unique, aucun backlog événementiel dans lAPI | canarie source + audit production |
| listener lent bloque producteur | coalescing ; listener se resynchronise sur current | listeners lents/indépendants |
| snapshot périmé | sequence monotone attachée à toute valeur publiée | late listener + is_after |
| wrap sequence | checked_add et erreur explicite | test exhaustion |
| stop vs fault | lifecycle producteur unique ; premier terminal valide gagne | matrice et ordres adversariaux |
| stop répété | WorkerStopToken atomique idempotent | multi-clone / cross-thread |
| restart réanime ancien handle | terminal immutable ; nouvelle instance/source, aucun rebind | canarie terminal + documentation |
| fuite identité | alphabet borné ; Debug WorkerId redacted | hostile marker |
| payload/secret dans snapshot commun | snapshot fixe sans String/payload générique | inventaire de champs + Debug |
| erreur externe dans état | Faulted ne retient quun ErrorCode statique | surface publique exacte |
| confusion health/lifecycle | dimensions séparées ; lifecycle terminal reste autoritaire | tests indépendance |
| fausse progression finie | aucun percent/total générique ; activité Unknown/Idle/Active seulement | inventaire API |
| contamination Solana/Store/Config | Core-only + canaries lexicales/dependencies | dependency_boundary |
| runtime implicite | aucun spawn/thread/channel Tokio possédé par API | manifest/source firewall |
## 14. Tests planifiés
### 14.1 Unit tests
```text
identity exact bounds : 0, 1, 128, 129 octets
alphabet hostile : whitespace, slash, backslash, Unicode, control chars
lifecycle transition matrix exhaustive
invalid transition leaves state unchanged
Stopped/Faulted immutable sous tous les mutateurs
Faulted conserve uniquement ErrorCode
stop token first-wins/idempotent/shared
stop token Send + Sync / cross-thread
snapshot sequence initial/next/is_after/exhaustion
health/activity stable safe codes si helpers exposés
Debug hostile marker absent
```
### 14.2 Integration/public API
```text
construction exclusivement depuis crate root
ErrorCode constants exacts
bounds publics exacts
WorkerSnapshotSource implémentable depuis une crate externe
WorkerSnapshotSource object-safe
source custom std-only sans Tokio
slow + independent listeners resync vers latest value
late listener current puis wait
terminal current reste disponible
Send/Sync des primitives promises
```
### 14.3 Dependency/release completeness
```text
manifest dependency exacte = ksp-core-lib uniquement
aucune feature/dev/build dependency
aucun tokio/futures/serde/tracing/Tauri
aucun ksp-job-api/Config/Interface/Transport/Store
aucun RawTransaction/slot/provider/endpoint/backfill/checkpoint
modules de production exacts
exports crate-root exacts
aucun pub mod
```
Les tests ne créent aucun runtime KSP fictif. Une implémentation de test peut utiliser `std::future::ready`, `Arc` et primitives `std` uniquement.
## 15. Questions explicitement différées
Les points suivants ne bloquent pas Worker API V1 et ne doivent pas être ouverts en `pre.002` par anticipation :
```text
WorkerHandle générique de start/join
registry/factory commune
reconfiguration live
generation/restart identity globale
remote proxy/protocol/IPC
serialization du snapshot commun
metrics/rates/counters métier universels
control-plane persistence
process ownership
```
Ils ne deviennent candidats que lorsquau moins plusieurs workers ou le futur control plane prouvent un besoin transverse.
## 16. Audit RAW Transaction : position et owner documentaire
Aucune analyse fonctionnelle de kbot3 ni réaudit provider courant nest effectué dans `pre.001`, conformément au séquencement du prompt.
Après freeze fonctionnelle de `ksp-worker-api` en `pre.003`, laudit RAW est scindé pour respecter le budget de tranche. Son owner durable prévu est :
```text
docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md
```
Ce document séparera :
```text
partie durable : taxonomy capabilities/roles/combinations/convergence
partie audit daté : disponibilité provider, quotas, replay, tiers et liens sources primaires
handoff : gaps Transport/Config 0.3.10 et applicability Backfill 0.3.12
```
Ce choix évite de transformer le plan de release en registre provider tout en donnant à `0.3.10` et `0.3.12` une référence architecturale réauditable. Lindex architecture ne sera synchronisé quau moment où ce document sera réellement créé, puis réconcilié dans le couloir documentaire final.
kbot3 ne sera alors utilisé que pour inventorier des comportements historiques. Aucun code, DTO, Config, URL, dependency ou version nen sera repris.
## 17. Prévision souple recalibrée
Le `pre.004` unique imaginé par le prompt est scindé en trois tranches daudit/synthèse : un audit Solana/KSP, un audit provider/kbot3, puis une synthèse. Un audit externe exhaustif Solana + Helius + Yellowstone + providers + KSP + mainnet naming dans une seule tranche dépasserait vraisemblablement le budget normatif de 15-20 minutes.
| Tranche | Objet | Budget de planification | Sortie |
|---------|-----------------------------------------------------------------|-------------------------|--------------------------------------------------------|
| pre.001 | audit, architecture, threat map, plan/tests | 15-20 min | présente livraison doc-only |
| pre.002 | crate + contrats Worker API décidés | 15-20 min | noyau + tests unit/public/dependency |
| pre.003 | hardening, races, object-safety, impl externe, freeze | 15-20 min | Worker API fonctionnellement fermée |
| pre.004 | audit RAW A : Solana standard + KSP Transport/Store/Config | 15-20 min | capabilities/roles/gaps internes |
| pre.005 | audit RAW B : Helius, Yellowstone/providers + kbot3 fonctionnel | 15-20 min | preuves primaires, quotas/replay/disponibilité |
| pre.006 | synthèse RAW multi-source + handoff 0.3.10/0.3.12 | 15-20 min | matrice finale, combinaisons, gaps et stratégie réseau |
| pre.007 | gate technique final | 10-15 min | workspace/worker-api/trees/duplicates verts |
| pre.008 | réconciliation documentaire finale | 10-15 min | README/USAGE/plan/validation/architecture cohérents |
| pre.009 | préparation de publication | 5-10 min | prompt 0.3.10 + CHANGELOG + ROADMAP + Cargo + delta |
| rel.001 | publication mécanique stable | 5-10 min | v0.3.9 sans rattrapage |
Les numéros restent souples. Un défaut réel peut ouvrir `pre.NNN-fix.MMM` dans le même couloir ou forcer un split supplémentaire. Les responsabilités `gate technique -> réconciliation documentaire -> préparation de publication` restent séparées.
## 18. Versioning de `pre.001`
La présente tranche est strictement documentaire : nouveau plan, nouvelle validation et nouveau delta. Elle ne modifie aucun code/build/runtime/configuration et conserve donc explicitement :
```text
workspace.package.version = 0.3.8
```
Cette exception de démarrage est explicitement autorisée par le prompt 028 et cohérente avec `VER-ID-008`. Le premier changement Rust de `pre.002` portera la version technique correspondant à sa livraison selon le workflow KSP.
## 19. Gate de sortie `pre.001`
La tranche est fermée architecturalement lorsque les points suivants sont présents dans le plan/validation :
```text
architecture Worker API décidée
state/health/activity/snapshot/stop décidés
surface publique prévue
Core-only exact dependency map
questions différées listées
threat map
plan de tests
prévision souple recalibrée
audit RAW positionné après freeze Worker API
aucun code worker concret commencé
```
Les gates Cargo restent à exécuter par lopérateur dans un environnement Rust. Leur absence locale nest pas masquée par les audits Python.

View File

@@ -0,0 +1,204 @@
<!-- file: docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md -->
<!-- version: 1 -->
# Validation v0.3.9 — Worker API + audit RAW Transaction
## 1. Objet
Cette matrice suit les preuves de `0.3.9` sans remplacer les deltas. `pre.001` ferme seulement le cadrage architectural ; les preuves Rust et laudit externe RAW restent ouverts jusquà leurs tranches dédiées.
## 2. Gate douverture `pre.001`
- [X] Archive KSP fournie explicitement comme stable `v0.3.8`.
- [X] SHA-256 KSP : `b3a34a3dfd56fac1eef3d23f13631ff001338b612834488038cf259112c63624`.
- [X] `unzip -t` KSP intégral propre.
- [X] 1 809 entrées KSP contrôlées sans traversal/absolu/symlink/artefact interdit.
- [X] `workspace.package.version = 0.3.8`.
- [X] `deltas/0.3.8/rel.001.md` présent.
- [X] 18 membres workspace inventoriés ; Store Desk, Job, Transport, Config et Store requis présents.
- [X] Archive kbot3 SHA-256 `ee47643b9f8b582ee8db97b2381ec107e45aef8c009fee44757531514615d318` et `unzip -t` propre.
- [X] kbot3 **non inspecté fonctionnellement** pendant la conception Worker API ; usage réservé à laudit RAW après freeze.
- [X] Règles normatives et architectures obligatoires du prompt lues avant décision.
- [X] Headers/version des documents obligatoires confirmés.
- [X] `ksp-job-api` manifest/src/tests et plan/validation `0.3.6` audités comme référence de propriétés.
- [X] `ksp-job-backfill-lib` et Backfill Desk audités comme contraste API générique / consumer concret.
- [X] Audit Rust Python baseline : clean, export completeness 0, KSP workspace clean.
- [X] Audit Markdown baseline : clean, 316 tables / 725 fichiers.
- [ ] `cargo fmt --all -- --check` local : non exécuté, `cargo` absent.
- [ ] `cargo check --workspace` local : non exécuté, `cargo` absent.
- [ ] `cargo clippy --workspace --all-targets` local : non exécuté, `cargo` absent.
- [ ] `cargo tree -p ksp-job-api --edges normal` local : non exécuté, `cargo` absent ; manifest statique Core-only confirmé séparément.
### Audit post-documentation `pre.001`
- [X] Audit Rust post-modification : General clean, export completeness 0, KSP workspace clean.
- [X] Audit Markdown post-modification : clean, 321 tables / 728 fichiers.
- [X] Diff byte-level contre le ZIP stable : trois ajouts, zéro modification, zéro suppression après retrait des artefacts ignorés.
- [X] `Cargo.toml` reste byte-identique à la base et `workspace.package.version = 0.3.8`.
Le ZIP ne contient pas `.git`; lexistence du tag nest pas inspectée directement. Le `rel.001` stable décrit lopération `tag v0.3.8` et le prompt autorise larchive stable explicitement fournie comme base.
## 3. Architecture Worker API décidée en `pre.001`
- [X] Job et Worker restent deux lifecycle APIs sémantiquement distinctes.
- [X] Aucun edge `ksp-worker-api -> ksp-job-api`.
- [X] Dependency cible exacte : `ksp-worker-api -> ksp-core-lib` uniquement.
- [X] `WorkerId` et `WorkerKindCode` propres, 128 octets max, alphabet sûr.
- [X] States retenus : Created, Starting, Running, Stopping, Stopped, Faulted(ErrorCode).
- [X] Stopped et Faulted terminaux/immutables.
- [X] Health distinct : Unknown, Healthy, Degraded, Unhealthy.
- [X] Activity générique minimale : Unknown, Idle, Active.
- [X] Aucun progress `current/total`, pourcentage, ETA ou métrique métier dans lAPI commune.
- [X] Snapshot commun fixe, non générique, sans payload arbitraire.
- [X] Snapshot fields limités à identity/kind/sequence/state/health/activity.
- [X] Latest-value retenu : current + wait_for_change + coalescing + resync.
- [X] Sequence monotone checked, exhaustion explicite.
- [X] `WorkerSnapshotSource` prévu `Send + Sync` et object-safe sans Tokio.
- [X] `WorkerStopToken` coopératif, partagé, idempotent, non bloquant.
- [X] Stop token ne possède ni timeout, ni join, ni runtime.
- [X] Fault public ne conserve quun `ErrorCode` statique.
- [X] Restart/retry/factory/control plane explicitement caller-owned et différés.
- [X] Ancien lifecycle/source terminal jamais rebinding vers une nouvelle instance.
- [X] Aucun WorkerHandle générique imposé en V1.
- [X] Aucun type transaction/slot/provider/endpoint/Store/replay/backfill/checkpoint dans la surface prévue.
## 4. Surface et hardening à matérialiser
### `pre.002`
- [ ] `crates/ksp-worker-api` créée dans le workspace.
- [ ] Manifest sans feature/dev/build dependency et avec Core uniquement.
- [ ] `identity.rs`, `error.rs`, `lifecycle.rs`, `snapshot.rs`, `stop.rs`, `lib.rs` matérialisés.
- [ ] Façade crate-root uniquement, aucun `pub mod`.
- [ ] Quatre error codes stables `worker_api` matérialisés.
- [ ] Bounds exacts identity testés.
- [ ] Lifecycle transition matrix exacte testée.
- [ ] Transition invalide conserve létat source.
- [ ] Stop token idempotent/shared testée.
- [ ] Snapshot sequence/exhaustion testée.
- [ ] Public API consumer depuis crate root testée.
- [ ] Dependency firewall initial testée.
### `pre.003`
- [ ] Stop-vs-fault ordres adversariaux couverts.
- [ ] Tous mutateurs refusent Stopped/Faulted.
- [ ] Debug hostile identity redacted.
- [ ] Snapshot ne contient aucun payload/string libre.
- [ ] Stop token `Send + Sync` prouvé cross-thread.
- [ ] `WorkerSnapshotSource: Send + Sync` prouvé.
- [ ] `WorkerSnapshotSource` object-safe prouvé avec trait object.
- [ ] Implémentation externe std-only compilée/testée.
- [ ] Listeners lents indépendants resynchronisés vers latest value.
- [ ] Late listener `current()` + séquence validés.
- [ ] Snapshot terminal reste lisible.
- [ ] Exact module inventory prouvé.
- [ ] Exact crate-root export inventory prouvé.
- [ ] Production sources sans Job/Config/Interface/Transport/Store/Tokio/futures/serde/Tauri/Solana.
- [ ] Worker API déclarée fonctionnellement frozen avant tout audit RAW détaillé.
## 5. Threat model à fermer
- [X] Queue non bornée évitée architecturalement par latest-value.
- [X] Slow-listener blocking évité architecturalement par coalescing/resync.
- [X] Stale snapshot couvert par sequence monotone.
- [X] Sequence wrap prévu comme erreur explicite.
- [X] Stop répété couvert par token first-wins.
- [X] Stop/fault terminal défini par first valid terminal transition.
- [X] Old-handle/restart fermé par immutabilité + no rebind.
- [X] Identity/log leakage réduit par bornes + Debug redaction.
- [X] Arbitrary payload dans snapshot commun interdit par forme fixe.
- [X] External error payload dans état interdit ; ErrorCode only.
- [X] Health/lifecycle séparés.
- [X] Fausse notion de completion/progress Worker interdite.
- [X] Runtime ownership reste hors API.
- [ ] Canaries Rust correspondantes exécutées après matérialisation.
## 6. Audit RAW Transaction post-freeze
Aucun item ci-dessous nest déclaré exécuté en `pre.001`.
### `pre.004` — Solana standard + KSP
- [ ] Réaudit Solana JSON-RPC HTTP primaire.
- [ ] Réaudit Solana WebSocket primaire.
- [ ] Capabilities KSP Transport réellement publiques inventoriées.
- [ ] Store RAW identity/content/provenance réconfirmés.
- [ ] Config/secrets/network descriptors inventoriés pour handoff uniquement.
- [ ] HTTP discovery/hydration roles classifiés.
- [ ] WS logs/signature/block roles classifiés.
- [ ] Live/catch-up/gap-repair/history applicability documentée.
- [ ] `mainnet` / `mainnet-beta` audit interne commencé sans migration.
### `pre.005` — providers + kbot3 historique
- [ ] Helius HTTP standard Mainnet/Devnet réaudité sur sources officielles courantes.
- [ ] Helius WS standard Mainnet/Devnet réaudité.
- [ ] Helius transactionSubscribe/extensions réaudités séparément avec tier courant.
- [ ] Yellowstone upstream transactions/transaction_status/blocks/block_meta réaudité.
- [ ] Replay/from_slot réellement supporté classifié provider par provider.
- [ ] Quotas/filter/subscription/reconnect limits sourcés.
- [ ] Providers supplémentaires pertinents réaudités uniquement sur docs officielles.
- [ ] kbot3 réaudité fonctionnellement : acquisition/live/history/recovery/fallback/provenance.
- [ ] Aucun code/DTO/URL/Config/dependency kbot3 repris.
### `pre.006` — synthèse et handoff
- [ ] Matrice complète des dimensions imposées par le prompt 028.
- [ ] Alternatives/complements/redundancy/specialization classifiés.
- [ ] Discovery + hydration distingués des streams full transaction.
- [ ] Dedup content vs observations de provenance explicitée.
- [ ] Stratégie multi-source V1 `0.3.10` proposée sans enum protocole simpliste.
- [ ] Gaps Transport `0.3.10` listés, non implémentés en `0.3.9`.
- [ ] Gaps Config `0.3.10` listés, aucun nouvel endpoint ajouté en `0.3.9`.
- [ ] Réutilisation unique `KSP_SECRET_HELIUS_API_KEY` confirmée.
- [ ] Stratégie compatible `mainnet` / `mainnet-beta` conclue.
- [ ] Applicability `0.3.12` Backfill indiquée par source/méthode.
- [ ] `docs/architecture/011-RAW_TRANSACTION_ACQUISITION.md` créé comme owner de laudit.
## 7. Couloirs de fermeture
### `pre.007` — gate technique final
- [ ] `cargo fmt --all -- --check`.
- [ ] audits Rust/Markdown complets.
- [ ] `cargo check --workspace`.
- [ ] `cargo clippy --workspace --all-targets --all-features -- -D warnings`.
- [ ] `cargo test --workspace --all-targets --all-features`.
- [ ] `cargo test -p ksp-worker-api`.
- [ ] `cargo tree -p ksp-worker-api --edges normal`.
- [ ] `cargo tree -p ksp-worker-api -e features`.
- [ ] `cargo tree --duplicates`.
### `pre.008` — réconciliation documentaire
- [ ] Worker API README version-neutral de surface/responsabilités.
- [ ] Worker API USAGE version-neutral avec exemples réutilisables.
- [ ] Plan/validation réconciliés sur preuves réelles.
- [ ] Architectures/index docs réconciliés.
- [ ] Audit RAW final relu comme handoff 0.3.10/0.3.12.
- [ ] Aucun CHANGELOG/ROADMAP/prompt suivant finalisé ici.
### `pre.009` — publication
- [ ] Prompt `0.3.10` produit depuis laudit final.
- [ ] CHANGELOG synchronisé.
- [ ] ROADMAP synchronisé.
- [ ] Cargo version mécanique synchronisée selon workflow.
- [ ] Delta publication préparatoire minimal.
### `rel.001`
- [ ] Version stable `0.3.9` mécanique.
- [ ] Aucun rattrapage fonctionnel/documentaire.
- [ ] Commit/tag stable selon workflow.
## 8. Versioning courant
`pre.001` est doc-only et conserve :
```text
workspace.package.version = 0.3.8
```
Aucun code/build/runtime/config nest modifié. Le premier changement Rust de la release est réservé à `pre.002`.