Files
mimic-big/tasks/todo.md
ux-frontend b505a654f8 fix(frontend): address M1-M3 polish from code-reviewer
M1 — Single SessionProvider via nested router.
  The previous router had two route entries with `path: '/'`
  (Navigate, AppShell) plus a separate `/login` entry, each wrapped in
  its own RootLayout. That instantiated SessionProvider three times,
  forking state the moment session writes diverged across siblings.
  Replaced by one Root route with SessionProvider + <Outlet />, and
  index/login/AppShell-children nested underneath. RootLayout (the
  per-tree wrapper) is now obsolete and deleted; the new Root component
  lives in src/routing/Root.tsx (addresses NIT N4 as a side effect).

M2 — Typo: "pollign" → "polling" in LiveCockpitPage masthead.

M3 — Replace asymmetric `?? 'rt_operator'` / `?? 'soc_analyst'`
  fallbacks in LiveCockpitPage with an explicit `if (!user) return null;`
  guard placed after all hooks (rules-of-hooks). AppShell already
  redirects unauthenticated visitors to /login, so the guard documents
  the invariant rather than introducing one.

NITs N1-N3, N5-N7 recorded in tasks/todo.md as sprint 1+ follow-ups.
2026-05-21 20:44:32 +02:00

4.6 KiB

Sprint 0 — Mimic

Repo skeleton + foundational modules. Nothing that depends on PR1/PR2/PR3.

Backend (backend)

  • B0.1 — backend/ Python project: pyproject.toml (ruff, mypy strict, pytest, coverage), Makefile, Dockerfile, docker-compose.yml for Postgres dev DB.
  • B0.2 — Alembic init + complete initial migration covering the §8 schema (incl. c2_credential, user, group, user_group, permission, group_permission, soc_session, audit_log with write-only Postgres role). No ttp_version table (D-009). Seed groups rt_operator, rt_lead, soc_analyst with F11 permissions (D-008).
  • B0.3 — SQLAlchemy 2 typed mapped classes for every table + repositories scaffold.
  • B0.4 — C2Connector ABC + dataclasses (Payload, TaskHandle, TaskResult) + enum payload_type + factory keyed on c2_type. No real implementation.
  • B0.5 — Jinja2 SandboxedEnvironment + regex_extract filter via google-re2 + {{outputs.text}} and {{outputs.blob(key)}} accessors with 10 MB cap.
  • B0.6 — Local auth (login/password bcrypt + Flask server-side sessions) + RBAC group-based decorators + F11 permission matrix declared in code.
  • B0.7 — Flat CRUD endpoints (engagements, hosts, TTPs, scenarios) — no orchestration, no WebSocket, no reporting yet.
  • B0.8 — pytest baseline: unit (SQLite) + integration scaffold (testcontainers Postgres).

Frontend (ux-frontend)

  • F0.1 — frontend/ Vite + React + TypeScript strict + Tailwind 4 + TanStack Query 5, eslint strict + prettier, Playwright skeleton.
  • F0.2 — Design system provisional: semantic tokens in theme.css (status colors, RT accent, data mono / UI sans), dark-first palette, placeholder logo.
  • F0.3 — Wireframes (via frontend-design skill) on mock data: Login + engagement selection, Live cockpit, Scenario composer, Report + MITRE matrix, TTP library + import.
  • F0.4 — Routing skeleton + role-aware layout shell (no real auth wired yet).
  • F0.5 — Push feature/frontend-skeleton, open PR for code-reviewer.
  • F0.6 — Polish M1-M3 from code-review (single SessionProvider, typo, fallback removal).

Frontend follow-ups (sprint 1+, non-blocking, from review NITs)

  • N1 — Tighten readMockSession payload validation when real auth wires up (currently checks only role; should validate the full SessionUser shape).
  • N2 — Replace the UI-side recomposition of the MIMIC-RUN: marker in the cockpit's "Resolved command" panel with resolvedCommandText returned by the backend (run_step_cleanup.resolved_command_text for cleanup, equivalent field for steps when exposed).
  • N3 — Wire StatusRail.linkState to the real WebSocket connection state once Flask-SocketIO is reachable (currently hardcoded 'up').
  • N4 — Unify router.tsx and any future router helpers under src/routing/ (single naming, no split between root file and folder). Addressed in F0.6: src/routing/Root.tsx introduced; router.tsx left at top level as the app-level entry that other code imports — split kept minimal.
  • N5 — Actually import Recharts somewhere (likely the MITRE matrix or a latency chart) since it's declared in README + package.json but not yet used.
  • N6 — When vendoring IBM Plex woff2 into public/fonts/, add public/fonts/LICENSE.txt (OFL-1.1) for license compliance.
  • N7 — Add frontend/.env.example exposing VITE_API_BASE_URL and VITE_WS_URL once the backend publishes endpoints.

Spec / Docs (spec-analyst)

  • S0.1 — Cross-check the data model in B0.2 against §8 of the spec; report deltas before merge.
  • S0.2 — Cross-check the RBAC matrix in B0.6 against F11; report deltas before merge.
  • S0.3 — Maintain tasks/spec-decisions.md as new arbitrations land.
  • S0.4 — Open docs/architecture.md once backend layout is committed.

Review (code-reviewer)

  • R0.1 — Review each PR per the published charter; block on security/OPSEC violations.
  • R0.2 — Verify mypy strict and ruff clean before approving any backend PR.
  • R0.3 — Verify TS strict, no useEffect(fetch), exhaustive deps before approving any frontend PR.

Conventions

  • Branches: feature/<scope>, fix/<scope>, docs/<scope>, chore/<scope>. Long-lived: main.
  • Commits: Conventional Commits (feat:, fix:, chore:, docs:, test:, refactor:).
  • PRs: each branch → review (code-reviewer) → team-lead merges.
  • No direct push to main.