0.3.15-pre.012

This commit is contained in:
2026-09-16 10:58:29 +02:00
parent 2f587e22be
commit 31ae38853d
21 changed files with 815 additions and 79 deletions

View File

@@ -1,5 +1,5 @@
<!-- file: docs/plans/036-V0_3_15_RAW_TRANSACTION_INGEST_DESK_PLAN.md -->
<!-- version: 19 -->
<!-- version: 20 -->
# Plan v0.3.15 — Raw Transaction Ingest Desk
@@ -835,7 +835,15 @@ Budget cible : une tranche frontend.
### `pre.012` — races / shutdown / sécurité IPC
Durcir stale inventory, Start/Stop concurrents, fermeture application, joins bornés, erreurs sûres, surfaces IPC et scénarios hostiles.
**État : implémenté.** Le Desk ferme désormais explicitement l'admission de nouveaux Start dès qu'une fermeture de la fenêtre principale est engagée. La fermeture Tauri est interceptée une seule fois, demande un Stop coopératif à toutes les routes actives, marque aussi les réservations encore en `Starting`, puis attend de façon bornée la disparition de tous les Workers et du Store partagé avant de quitter le processus. Un second événement de fermeture ne lance pas un second shutdown concurrent.
La race Start/Stop est désormais définie : un Stop ciblé reçu pendant `Starting` marque la réservation `stop_requested` au lieu de répondre `not_active`. Si le Worker est ensuite activé, son Stop est demandé avant publication de l'acknowledgement ; si le Start échoue avant activation, le rollback conserve un terminal logique `Stopped`, ce qui permet au Stop concurrent de terminer sans inventer de Worker. Les délais de cleanup Desk sont alignés sur les drains Worker bornés afin de ne pas signaler prématurément un échec pendant un arrêt coopératif valide.
La revalidation Start conserve la génération d'inventaire sous verrou pendant toute la reconstruction synchrone Config/Transport, puis libère explicitement ce verrou avant le premier `await`. L'admission shutdown est vérifiée avant la préparation et de nouveau atomiquement lors de la réservation runtime ; un Start déjà en vol ne peut donc pas franchir silencieusement une fermeture applicative.
Les DTO Start/Stop refusent maintenant les champs JSON inconnus et bornent le seul identifiant libre `profile_id`. Le bridge de logging frontend refuse également les champs inconnus, borne niveau/target/message avant parsing et rejette les caractères de contrôle ; le frontend borne lui-même le message technique avant IPC avec une marge sûre vis-à-vis de l'encodage UTF-8. Les erreurs Tauri continuent à journaliser uniquement `domain/code`, jamais le payload hostile ni une ressource physique.
Aucun module de production supplémentaire, aucune dépendance lower-layer et aucune seconde pipeline ne sont introduits. Les comportements Config, Transport, Store, Worker et Common RAW restent inchangés.
Budget cible : une tranche hardening.

View File

@@ -1,5 +1,5 @@
<!-- file: docs/validation/032-V0_3_15_RAW_TRANSACTION_INGEST_DESK.md -->
<!-- version: 21 -->
<!-- version: 22 -->
# Validation v0.3.15 — Raw Transaction Ingest Desk
@@ -743,3 +743,55 @@ pre_011_frontend_supervision_closes_planned_ui_without_backend_module_growth
```
Aucune modification Config, Transport, Store, Worker ou Common RAW n'est introduite par `pre.011`. Le module Rust de production du Desk reste exactement celui de `pre.010`; la tranche suivante `pre.012` reste dédiée aux races/shutdown/sécurité IPC.
### `pre.012` — races Start/Stop, shutdown applicatif et sécurité IPC
Base : `0.3.15-pre.011-fix.001`, validée par le gate opérateur du 16 septembre 2026. Les audits, `cargo check --workspace`, Clippy strict, les suites Desk/Worker/workspace et le scénario live multi-route passent ; Yellowstone et HTTP Block Polling restent manipulables simultanément sous charge et le Store partagé ferme seulement après la dernière route.
Périmètre `pre.012` : hardening du contrôle Desk uniquement, sans modification des stratégies d'acquisition.
```text
shutdown application
CloseRequested main window intercepté et empêché temporairement
admission de nouveaux Start fermée une seule fois
Stop coopératif demandé à tous les Workers actifs
réservations Starting marquées stop_requested
attente bornée routes + Store avant app_handle.exit
second CloseRequested n'engendre aucun second shutdown
race Start / Stop
Stop sur Starting => marque stop_requested puis attend le cleanup
activation ultérieure => request_stop avant acknowledgement
échec avant activation => rollback retient un terminal logique Stopped
cleanup Desk borné et compatible avec le drain Worker borné
stale inventory / Start
génération sous verrou pendant la préparation synchrone
reconstruction complète Config/Transport à chaque Start
verrou libéré explicitement avant le premier await
admission shutdown revérifiée atomiquement pendant reserve
IPC hostile
StartRequest / StopRequest : deny_unknown_fields
profile_id : non vide, <= 256 octets, sans trim implicite ni contrôle
FrontendLogPayload : deny_unknown_fields
level / target <= 16 octets
message <= 8192 octets et sans caractères de contrôle
frontend : message technique borné à 1024 code units avant IPC
erreurs Tauri : projection domain/code uniquement
```
Canaris ajoutés/étendus :
```text
pre_012_route_requests_reject_unknown_fields_and_bound_free_form_profile_identity
pre_012_frontend_log_ipc_rejects_unknown_fields_and_unbounded_or_control_messages
pre_012_stop_racing_start_marks_the_reservation_for_cooperative_stop
pre_012_application_shutdown_is_one_shot_and_marks_starting_routes_before_activation
pre_012_window_shutdown_and_start_stop_races_are_bounded_backend_owned
pre_012_hostile_ipc_is_shape_strict_bounded_and_safely_projected
pre_012_race_shutdown_and_ipc_hardening_adds_no_production_module_or_lower_layer_growth
```
Non-claims : `pre.012` ne modifie ni Config, ni Transport, ni Store, ni `ksp-worker-raw-transaction-ingest-lib`, ni Common RAW. Il n'ajoute aucune orchestration Backfill, aucun scheduler, aucune route et aucune nouvelle donnée frontend. `pre.013` reste propriétaire de la fermeture completeness/security cross-layer.