docs: sprint 2 wrap-up — README + CHANGELOG + lessons + plan final
- README: status bump to sprint 2, blueprints + workflow + MITRE section, test counts refreshed (131/63/68) - CHANGELOG: sprint 2 entry under [Unreleased]; sprint 1 moved to its own [Sprint 1] section - tasks/lessons.md: 5 lessons captured (3 frontend testing gotchas, agent-reuse via SendMessage, e2e refresh on placeholder supersession) - tasks/todo.md: status flipped to 🟢 SPRINT COMPLET, execution sequence ticks updated with commit hashes Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
34
CHANGELOG.md
34
CHANGELOG.md
@@ -6,7 +6,39 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added — Sprint 1 (Auth + CRUD Engagement)
|
||||
### Added — Sprint 2 (Simulations + MITRE ATT&CK)
|
||||
|
||||
**Backend** (Flask + SQLAlchemy, 131 pytest passing)
|
||||
- `Simulation` model with redteam-side (`name`, `mitre_technique_id`, `mitre_technique_name`, `description`, `commands`, `prerequisites`, `executed_at`, `execution_result`) and SOC-side (`log_source`, `logs`, `soc_comment`, `incident_number`) fields, plus `status` enum (`pending` / `in_progress` / `review_required` / `done`), FK to `Engagement` (cascade delete) and `User` (creator).
|
||||
- Alembic migration `0002_add_simulations.py`.
|
||||
- 7 new endpoints: `GET/POST /api/engagements/<eid>/simulations`, `GET/PATCH/DELETE /api/simulations/<sid>`, `POST /api/simulations/<sid>/transition`, `GET /api/mitre/techniques?q=`.
|
||||
- `simulation_workflow` service: field-level RBAC (SOC blocked when status ∈ {pending, in_progress}; SOC rejected if payload contains a redteam field), state machine (only forward transitions, validated by role), and auto-transition `pending → in_progress` when admin/redteam saves any non-empty redteam field.
|
||||
- `mitre` service: STIX 2.1 Enterprise bundle loaded at boot, indexed by T-id + name + tactic. Ranked search (`exact-id > prefix-id > substring-name`), max 20 results. Includes sub-techniques (`T1059.001`). Boot-safe: missing/corrupt bundle logs a warning and the endpoint returns 503 instead of crashing the app.
|
||||
- `make update-mitre` is now a real target — fetches the upstream STIX bundle and restarts the container if running. Bundle is committed at `backend/data/mitre/enterprise-attack.json` (~46 MB) so `make build` stays self-contained.
|
||||
- Upfront validation of `executed_at` (no partial mutation on parse failure).
|
||||
|
||||
**Frontend** (React + TanStack Query, 63 vitest passing)
|
||||
- `SimulationList` component rendered inside `EngagementDetailPage` (replaces the Sprint 1 placeholder). Columns: name, MITRE id, status badge, executed_at. Row click → SPA navigation via `useNavigate` (no full reload).
|
||||
- `SimulationFormPage` (`/engagements/:eid/simulations/new` and `/engagements/:eid/simulations/:sid/edit`): single role-aware page with two cards ("Red Team" / "SOC"). Redteam/admin can edit all fields; SOC sees the redteam card as read-only and the SOC card disabled (with an explanatory banner) until status reaches `review_required`. Footer surfaces context-appropriate transition buttons ("Marquer en revue" / "Clôturer") and a confirmation modal for delete.
|
||||
- `MitreTechniquePicker`: debounced (200 ms) autocomplete input with keyboard navigation (↑↓ / Enter / Escape), listbox accessibility, and an inline 503 error path. Selection populates both `mitre_technique_id` and `mitre_technique_name`. A `hasHydratedFromProps` ref prevents the input from being wiped mid-stroke when the parent emits `onChange(null, null)`.
|
||||
- `SimulationStatusBadge`: 4 variants mapped to DESIGN.md tokens (`bg-fog`, `bg-primary-soft`, `bg-bloom-coral`, `bg-storm-deep`). Sibling of the existing `StatusBadge` rather than a forked generic — the two badges share visual scaffolding but their enums diverge.
|
||||
- `ConfirmDialog`: generic modal used by the delete flow.
|
||||
- TanStack Query hooks: `useEngagementSimulations`, `useSimulation`, `useCreateSimulation`, `useUpdateSimulation`, `useDeleteSimulation`, `useTransitionSimulation`, `useMitreSearch`. Mutations invalidate both the simulation detail key and the engagement-scoped list key.
|
||||
|
||||
**Acceptance tests** (Playwright, 68 specs)
|
||||
- 6 new spec files (one per user story US-7 → US-12), 32 tests, all green.
|
||||
- `us4-engagements.spec.ts` AC-4.9 assertion refreshed: the Sprint 1 placeholder text was correctly replaced by the new `SimulationList` (the test now asserts the new heading + "Nouvelle simulation" link).
|
||||
- 5 pre-existing failures in `us1-bootstrap-admin.spec.ts` and `us6-deployment.spec.ts` remain — they hard-code `docker` in the test body and fail in dev environments that only have `podman`. The fixtures already support `MIMIC_CONTAINER_CMD`; the test bodies don't yet. Out of scope for Sprint 2 — to be picked up later.
|
||||
|
||||
### Changed
|
||||
- 2026-05-26 — `make update-mitre` upgraded from no-op placeholder to a real `curl` + optional container restart (Sprint 1 marker resolved).
|
||||
- 2026-05-26 — `EngagementDetailPage` no longer renders the "Simulations à venir au Sprint 2" placeholder; it embeds `<SimulationList>` instead.
|
||||
|
||||
---
|
||||
|
||||
## [Sprint 1] — Auth + CRUD Engagement (merged 2026-05-26)
|
||||
|
||||
### Added
|
||||
|
||||
**Backend** (Flask + SQLAlchemy + SQLite, 63 pytest passing)
|
||||
- `User` model with `admin / redteam / soc` enum, argon2 password hashing.
|
||||
|
||||
Reference in New Issue
Block a user