v0.3.7-pre.010

This commit is contained in:
2026-09-02 18:56:09 +02:00
parent 97f84e5c58
commit 313d2a1ea6
20 changed files with 533 additions and 40 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/024-V0_3_7_BACKFILL_DESK.md -->
<!-- version: 17 -->
<!-- version: 18 -->
# Validation v0.3.7 — Backfill Desk
@@ -480,3 +480,24 @@ Le correctif conserve le même niveau de sécurité mais cible désormais les d
- [X] version Cargo synchronisée en `0.3.7-pre.9.fix.2` ;
- [X] audits statiques Rust/Markdown rejoués dans l'environnement d'assemblage ;
- [ ] replay opérateur `cargo fmt/check/clippy/test` du fix à exécuter ; aucun `cargo tree` requis car dépendances/features inchangées.
## 24. `pre.010` — Cancel ciblé, idempotence et races terminales
Le replay opérateur de `pre.009-fix.002` ferme le monitoring latest-value : audits Rust/Markdown, `cargo check --workspace`, Clippy, les 49 tests unitaires `ksp-job-backfill-lib` et toutes les suites Backfill Desk passent. La surface `pre.010` peut donc ouvrir le contrôle coopératif sans rattrapage antérieur.
`backfill_cancel(job_id)` cible explicitement le JobId backend actuellement observé. Cette cible empêche une requête Cancel IPC retardée, émise pour un run terminé, d'annuler un run ultérieur. Le slot single-run sérialise Start/Cancel/finish : le premier Cancel pré-terminal appelle `BackfillJobHandle::cancel()` et renvoie `accepted=true`; les répétitions renvoient `accepted=false`; un terminal déjà gagné reste terminal; un JobId qui ne correspond ni au run actif ni au terminal retenu est rejeté par un code `backfill_desk` stable.
Le frontend ajoute un bouton **Annuler** au monitoring, transmet uniquement le JobId sûr, n'envoie aucun payload de campagne et se resynchronise immédiatement via `backfill_status`. La fermeture de la fenêtre principale gagne d'abord `begin_shutdown()`, ce qui interdit tout nouveau Start, puis demande best-effort l'annulation du run actif avant le shutdown Store et l'exit. Cette fermeture ne promet pas le drain crash-safe du travail déjà soumis ; le runtime Job conserve seul la sémantique de drain coopératif.
### Gate statique local `pre.010`
- [X] Cancel ciblé par JobId backend, sans identité fournie au Start ;
- [X] premier Cancel accepté et répétitions idempotentes ;
- [X] stale JobId rejeté avant action sur un nouveau run ;
- [X] terminal tardif prioritaire sur un Cancel non accepté ;
- [X] shutdown bloque Start puis tente l'annulation active avant exit ;
- [X] DTO Cancel limité à `accepted`, `job_id`, `state` ;
- [X] frontend Cancel sans adresse/signature/provider/endpoint/checkpoint/payload ;
- [X] aucune dépendance/feature Cargo ajoutée ;
- [X] Resume non ouvert ;
- [ ] `cargo fmt/check/clippy/test` de `pre.010` à rejouer par l'opérateur.