- CHANGELOG: sprint 4 entry under [Unreleased] (covers all 9 US: dark mode, MITRE matrix overhaul, tactic_ids, done read-only + Reopen, engagement auto-status, UI polish, design-reviewer agent, PR helper, screenshots mandatory). Sprint 3 moved to its own [Sprint 3] section.
- README: status bump, test counts refreshed (193/92/158).
- tasks/lessons.md: 7 sprint-4 lessons captured (git status before sprint close, endpoint round-trip mismatch caught only by e2e, ink vs slab token split, structural row layout > class tweaks, hardcoded paths in migration tests, screenshots with auth, builder cross-context summaries as accidental re-dispatch).
- 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>
Remove test.fail annotation from AC-21.6 "Apply from modal includes
tactic in result". GET /api/mitre/matrix now returns tactic_id in TA-format
("TA0007") so the PATCH succeeds and the tactic chip appears.
Update button selector in both AC-21.6 tests from title*="discovery"
to title*="TA0007" to match the fixed matrix response format.
Suite: 158 passed, 0 failed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- mitre.py: add _SLUG_TO_TA_ID reverse map; _build_matrix() now emits tactic_id
as TA-id (e.g. "TA0007") so frontend can send it back verbatim in PATCH tactic_ids
- test_mitre.py: update all matrix assertions to use TA-ids; add
test_get_matrix_tactic_id_is_ta_format regression guard
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- test_engagement_lifecycle.py, test_simulations_techniques.py: replace hardcoded
absolute paths with Path(__file__).parent.parent / migrations/... (portable)
- simulation_workflow.py: remove dead branch in transition() — the IN_PROGRESS
hook was unreachable since _ALLOWED_TRANSITIONS only targets review_required/done
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- btn-ink: replace inline background-color #111827 with @apply bg-slab (and add
slab-hover token #1f2937 for the hover state) so the token system is consistent
- EngagementsListPage: header button "+ New" → "+ New engagement" to match
empty-state CTA label
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- bump dark hairline from #374151 → #4b5563 for visible table borders
- topbar header bg-canvas → bg-paper for dark-mode lift vs canvas body
- UsersAdminPage create-form: Option A structural 3-row grid (labels / inputs / hints)
to fix AC-17.3 alignment; removes FormField wrapper that caused row-height misalignment
- EngagementsListPage: replace text "+ New" with lucide Plus icon per design spec
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add fixed slab/slab-text/slab-muted tokens so utility strip and footer never
invert to near-white in dark mode (root token split: ink is themed text,
slab is fixed dark surface)
- btn-ink uses fixed#111827 so confirm dialogs stay dark-on-dark readable
- Toast error surface switched to slab; success uses text-white (not text-ink-on)
- StatusBadge active and SimulationStatusBadge review_required/done use text-white
instead of text-canvas/text-ink-on (prevents near-black text on colored pill
in dark mode)
- Modal backdrops (MitreMatrixModal, ConfirmDialog) switched to .modal-backdrop
class (fixed rgba(0,0,0,0.6)) instead of bg-ink/60 which turned near-white
- Card shadow lifted in dark mode via .dark .card-product override
- MitreMatrixModal panel uses shadow-floating-dark in dark mode
- UsersAdminPage form: items-start + explicit label-height spacer on button
column for pixel-perfect baseline alignment (AC-17.3 structural fix)
92/92 tests passing, typecheck and lint clean.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
US-24 — Process hygiene UI:
- New .claude/agents/design-reviewer.md (model: opus, read-only) — visual + design-system reviewer that runs after frontend-builder and before code-reviewer. Audits alignment, DESIGN.md tokens, light/dark consistency, typo hierarchy, whitespace rhythm, responsive sanity at 1280x720, button convention, V1 a11y. Output format mirrors code-reviewer.
- Updated .claude/agents/frontend-builder.md DoD: screenshots are MANDATORY (one per feature/state introduced or modified, light+dark when theming is in scope). Hard block on "Dev server not started" — must be flagged explicitly. Screenshots feed the design-reviewer step.
US-25 — PR helper:
- scripts/open-pr.sh wraps `POST /api/v1/repos/{owner}/{repo}/pulls`. Detects host/owner/repo from `git remote get-url origin`, reads basic-auth credentials from `~/.git-credentials` (same source as `git push`, no token in env), uses jq to compose the multiline-safe payload. Validates args, prints PR URL on success, exits non-zero with the server message on failure.
- Makefile target `open-pr TITLE="..." BODY=path/to/body.md [BASE=main]` wraps the script with the same arg validation.
- README.md "Make targets" table extended.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- tasks/todo.md: sprint 4 plan with 9 user stories (US-17 → US-25), 9 décisions arrêtées
- SPEC.md § Fonctionnement: Done is terminal, Reopen returns to review_required (open to all roles); engagement auto-flips planned → active when any simulation hits in_progress, no auto-rollback
- SPEC.md § Référentiel MITRE: sprint 3 multi-tech + sprint 4 tactic_ids separated field
- SPEC.md § UI/UX (new): theming light/dark/system with system default, button convention (icon + ≤8-char label), modal focus trap V1
- SPEC.md § Workflows: design-reviewer inserted between frontend-builder and code-reviewer; PR via make open-pr
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The sprint 3 plan §0 updated SPEC.md § Simulation to reflect multi-techniques
(plural + autocomplete + matrix modal + sub-techniques). That edit sat in the
sprint 3 worktree but was never committed, so PR #6 merged the multi-tech
code without the corresponding spec text. Applying it here at the start of
sprint 4 so SPEC and main are aligned again.
Lesson captured in tasks/lessons.md for sprint 4 wrap-up: always
git status before declaring sprint complete.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>