# ksp-job-api `ksp-job-api` fournit les contrats passifs et runtime-neutral communs aux jobs bornés de KSP. La crate possède l'identité logique d'un job, son lifecycle terminable, l'intention d'annulation coopérative et le contrat latest-value utilisé pour observer un snapshot complet. Elle ne possède aucun runtime concret, aucune politique métier de backfill, aucun Transport, aucun Store et aucun Worker. ## Responsabilités La façade crate-root expose : - `JobId` et `JobKindCode`, bornés et validés ; - `JobState` et `JobCompletion` ; - `JobLifecycle`, propriétaire des transitions admises ; - `JobCancellationToken`, cloneable et idempotent ; - `JobNotificationSequence`, strictement monotone et sans wrap silencieux ; - `JobNotification`, valeur observable complète à une position donnée ; - `JobSnapshotSource`, contrat runtime-neutral de lecture courante et attente d'une valeur plus récente ; - les codes d'erreur Job et les types `Error`/`Result` communs de Core. ## Lifecycle Le lifecycle admis reste explicitement borné : ```text Created | | +----------------------> Cancelled v Running | | +----> Cancelling -----> Cancelled | | | | +---------> Failed | +-------------> Completed(Complete|Partial) | +------------------------> Completed(Complete|Partial) +------------------------> Failed ``` Tout état terminal est immuable. Une transition invalide retourne `ERROR_CODE_JOB_TRANSITION_INVALID` sans modifier l'état source. ## Observation latest-value `JobSnapshotSource` n'impose ni callback, ni queue d'événements, ni runtime async particulier. Un listener peut : 1. lire la valeur complète courante ; 2. mémoriser sa `JobNotificationSequence` ; 3. attendre une valeur plus récente ; 4. recevoir directement la dernière valeur complète, même si plusieurs mises à jour intermédiaires ont été coalescées. Le snapshot concret appartient au job qui implémente la source. `ksp-job-api` ne connaît pas son contenu. ## Annulation `JobCancellationToken` représente uniquement une intention coopérative partagée. Il ne tue pas une tâche, n'annule pas une I/O par lui-même et ne décide pas du résultat terminal. Le runtime concret reste responsable d'observer le token aux frontières sûres et de publier son état final. ## Firewall La dépendance normale est volontairement minimale : ```text ksp-job-api -> ksp-core-lib ``` La crate ne dépend pas de Tokio, Futures, Transport, Store, Config, Logging, serde ni d'une crate de job concret. ## Documentation - [`USAGE.md`](USAGE.md) — utilisation durable des contrats Job ; - [`../../docs/architecture/003-COMPONENT_CONTRACTS.md`](../../docs/architecture/003-COMPONENT_CONTRACTS.md) — contrats de composants ; - [`../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md`](../../docs/architecture/009-ACQUISITION_WORKERS_AND_JOBS.md) — séparation workers/jobs et premier backfill RAW.