User reported two issues on the scenario table:
1. After filling only red_command + executed_at, the pill read
"Reviewed" instead of "Awaiting review". Cause: the auto-promotion
was gated on `state in {pending, skipped, blocked}`, so a test that
blue had already reviewed stayed in `reviewed_by_blue` after a red
edit. That contradicts the implicit lifecycle (red modifying a
reviewed test invalidates the review).
2. The state pill lived inside the Commentaires column, polluting a
cell meant for blue-team comments.
Fixes
- backend/app/services/mission_tests.py: any red-side write now lands
the state on `executed` unconditionally (including from
`reviewed_by_blue`). Same-PUT red+blue still flows
executed → reviewed_by_blue.
- frontend/src/pages/MissionScenarioTable.tsx: state pill moves from
CommentairesCell to the Test column (top of the row, above the
snapshot name + MITRE chips). Commentaires now holds only the
detection_level pill + blue_comment_md.
Tests
- New pytest: `test_red_write_on_reviewed_reverts_to_executed` —
reviewed_by_blue + red edit ⇒ executed. 143 pytest green.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Metamorph frontend
Vite + React 18 + TypeScript + TailwindCSS. Design tokens from ../tasks/design.md are in tailwind.config.ts.
Local dev
npm install
npm run dev # http://localhost:5173 (proxies /api/* to http://localhost:8000)
Build
npm run build # outputs to dist/
npm run preview # serves dist/ on http://localhost:8080
Quality
npm run typecheck
npm run lint
npm run format
Layout
src/
├── App.tsx # M0 home page (health check + design tokens demo)
├── main.tsx
├── index.css # Tailwind base + tinted-accent utilities
├── components/ui/ # RTOps design primitives: Card, Tag, SectionHeader, FlowNode, Button
├── lib/
│ ├── api.ts # fetch wrapper (M2 will replace with auth-aware client)
│ └── cn.ts # classnames + ACCENTS palette
└── vite-env.d.ts