feat(m7-amend2): implicit lifecycle — writes drive state, no workflow UI

User: «Enlève également le workflow d'un test, quand on saisit des
informations côtés redteam cela signifie qu'il a été exécuté et donc
en attente d'une review blueteam.»

Backend (update_mission_test_fields)
- At the end of every PUT, inspect the touched-field set:
  - any red write on state in {pending, skipped, blocked} → state=executed
    + auto-stamp executed_at=now() if absent
  - any blue write on state=executed → state=reviewed_by_blue
- /transition endpoint kept for back-fill/admin use, not called from UI.

Frontend MissionTestPage
- Removed the transition-buttons header block and the `transition`
  mutation. State pill stays as a passive indicator.
- New labels: "Not started" / "Awaiting review" / "Reviewed" describe
  the implicit lifecycle, no longer exposing the state-machine concept.

E2E
- The SPA test that clicked `transition-executed` now verifies the
  implicit promotion: typing red fields and saving flips the pill from
  "Not started" → "Awaiting review", no button click required.

Spec
- §4 reword: "Cycle de vie implicite, piloté par les écritures" replaces
  the old "Workflow par test instance" bullet.

Tests
- 3 new pytest: red_command-alone implicit execute + auto-stamp,
  blue write promotes executed→reviewed, blue write on pending no-op.
- 142 pytest + 49 Playwright green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Knacky
2026-05-15 16:09:26 +02:00
parent 40114d041b
commit 28b8855e88
7 changed files with 141 additions and 70 deletions

View File

@@ -53,7 +53,7 @@ Remplace l'aller-retour Excel actuel par une UI partagée temps réel, multi-rô
- Saisie des résultats red (texte uniquement : commande, output, commentaires) avec horodatage auto au clic « Marquer exécuté » + override manuel.
- Saisie des preuves blue : multi-fichiers (PNG/JPG/PDF/TXT/LOG/JSON/CSV/EVTX/ZIP, max 25 Mo/fichier, SHA256 stocké) + commentaires markdown + niveau de détection (taxonomie custom paramétrable par admin, seed par défaut : `detected_blocked / detected_alert / logged_only / not_detected`).
- **Saisie côté blue — fiche de review étendue (amendement 2026-05-15)** : en plus du commentaire et du niveau de détection, la fiche de review d'un test capture les 5 champs additionnels que la blue maintenait en Excel — **`log_source`** (texte court : Firewall / NDR / Proxy / AV / EDR / …), **`siem_logs`** (texte long, extrait brut de logs collectés au SIEM), **sous-record cyber-incident** `(incident_at: timestamptz, incident_number: texte court, incident_recipient_email: email)` qui matérialise l'alerte envoyée à l'équipe SOC. Tous ces champs sont blue-side et gated par `mission.write_blue_fields`.
- Workflow par test instance : `pending executed reviewed_by_blue` + voies `skipped / blocked`.
- **Cycle de vie d'un test instance — implicite, piloté par les écritures (amendement 2026-05-15 bis)** : aucun bouton de transition exposé en UI. La colonne `state` du DB reste (`pending / executed / reviewed_by_blue / skipped / blocked`) mais elle est **auto-promue** par le service à chaque PUT : (1) toute écriture côté red sur un test `pending|skipped|blocked` fait passer à `executed` et auto-stamp `executed_at = now()` si absent ; (2) toute écriture côté blue sur un test `executed` fait passer à `reviewed_by_blue`. Une écriture blue sur un test `pending` n'auto-promote pas (seule la red implique l'exécution). L'endpoint `/transition` est conservé pour back-fill admin mais n'est plus appelé par l'UI.
- Visibilité mission : whitebox totale pour la blue team dès la création (pas de masquage des procédures).
- Édition concurrente : last-write-wins + indicateur « modifié par X il y a Ns » via polling léger. Conflits red/blue impossibles par construction (champs disjoints).
- Notifications in-app uniquement (badge + liste), pas de SMTP.