From 92f08ca5a8cbb87bef72cb01a60241b743f6da57 Mon Sep 17 00:00:00 2001 From: SinuS Von SifriduS Date: Fri, 4 Sep 2026 12:47:53 +0200 Subject: [PATCH] v0.3.9-pre.001 --- deltas/0.3.9/pre.001.md | 187 ++++++ ...9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md | 567 ++++++++++++++++++ ...V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md | 204 +++++++ 3 files changed, 958 insertions(+) create mode 100644 deltas/0.3.9/pre.001.md create mode 100644 docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md create mode 100644 docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md diff --git a/deltas/0.3.9/pre.001.md b/deltas/0.3.9/pre.001.md new file mode 100644 index 0000000..8415845 --- /dev/null +++ b/deltas/0.3.9/pre.001.md @@ -0,0 +1,187 @@ + + + +# 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 l’architecture générique `ksp-worker-api`, threat map, tests et sizing, **sans créer la crate Worker ni commencer l’audit 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é n’a été détecté. + +La source de code reste exclusivement KSP `v0.3.8`. kbot3 n’a pas été utilisé pour concevoir Worker API ; son futur usage est réservé à la référence **fonctionnelle historique** lors de l’audit 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 l’environnement d’assemblage. 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 n’est modifié ou supprimé. Le cache Python créé par l’audit 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 l’API 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 n’est 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 +``` + +L’audit 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 +``` + +L’owner prévu du document d’audit 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 n’est modifié. Conformément à l’autorisation 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. diff --git a/docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md b/docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md new file mode 100644 index 0000000..4edee5e --- /dev/null +++ b/docs/plans/030-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT_PLAN.md @@ -0,0 +1,567 @@ + + + +# 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 d’acquisition 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 d’ouverture + +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 d’archive : + +```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` n’est donc pas réinspectable depuis `.git`. La base est néanmoins admissible selon le prompt car l’opérateur l’a 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 l’archive 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` n’est pas installé dans l’environnement d’assemblage. 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 qu’un 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 n’est 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 s’arrête, il ne termine pas un Job annulé | +| Completed + JobCompletion | non | interdit | un Worker continu n’a pas de completion normale | +| Cancelled | non | WorkerState::Stopped | arrêt normal distinct d’une 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 qu’une 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 d’un 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 l’instance 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` n’a aucune notion de completion ; +- `Faulted(ErrorCode)` ne conserve qu’un identifiant d’erreur KSP statique, jamais un message arbitraire ni un `Box` ; +- `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 l’autorité 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 : l’idempotence appartient à l’intention 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 l’intention 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 qu’un 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 n’entre 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`, 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 d’empê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` n’est attendu qu’aprè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 s’arrê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 l’intention 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 n’est 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 d’attente 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 qu’un besoin réel n’est 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 d’identité 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 l’API | 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 qu’un 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 lorsqu’au 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 n’est effectué dans `pre.001`, conformément au séquencement du prompt. + +Après freeze fonctionnelle de `ksp-worker-api` en `pre.003`, l’audit 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. L’index architecture ne sera synchronisé qu’au 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 n’en sera repris. + +## 17. Prévision souple recalibrée + +Le `pre.004` unique imaginé par le prompt est scindé en trois tranches d’audit/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 l’opérateur dans un environnement Rust. Leur absence locale n’est pas masquée par les audits Python. diff --git a/docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md b/docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md new file mode 100644 index 0000000..beac41a --- /dev/null +++ b/docs/validation/026-V0_3_9_WORKER_API_RAW_TRANSACTION_AUDIT.md @@ -0,0 +1,204 @@ + + + +# 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 l’audit externe RAW restent ouverts jusqu’à leurs tranches dédiées. + +## 2. Gate d’ouverture `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é à l’audit 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`; l’existence du tag n’est pas inspectée directement. Le `rel.001` stable décrit l’opération `tag v0.3.8` et le prompt autorise l’archive 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 l’API 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 qu’un `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 n’est 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 l’audit. + +## 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 l’audit 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 n’est modifié. Le premier changement Rust de la release est réservé à `pre.002`.