Where it lives

After npx -y @specdrive/mcp setup --stack <stack>, open .specdrive/coding-style.md in your app. MCP generation bundles include this file as steering context.

Flutter — Clean Architecture + BLoC

Blocking rules for production Flutter PRs:

  • Layers: presentation / domain / data — UI → BLoC → UseCase → Repository
  • Dumb widgets: no filtering, pricing, or API calls in build()
  • Domain purity: entities have no JSON; repositories are interfaces only
  • BLoC: sealed states (Initial/Loading/Loaded/Error), complete Equatable props, descriptive events
  • SOLID: depend on abstractions; one use case per operation; no god-BLoCs
  • UI: const, extract long builds, ListView.builder, mounted after async, no print
  • Tests: every new bloc/usecase/helper needs _test.dart

Full Flutter standards (markdown)

Next.js — App Router + feature modules

  • Thin page.tsx; feature modules with domain/ + data/
  • Server Components by default; 'use client' only when required
  • No DTOs in UI; mappers in data/
  • URL/server/Zustand slices — no business filters in JSX
  • Vitest + Testing Library for domain/hooks

Full Next.js standards (markdown)

React Native — Expo + feature modules

  • Screens compose hooks/stores — no fetch in JSX
  • Discrete status unions, not boolean soup
  • FlatList/FlashList with stable keys
  • Domain has zero RN imports; DTOs stay in data/
  • A11y labels on CTAs; platform diffs in design.md

Full React Native standards (markdown)

How SpecDrive enforces this

  1. setup writes stack-specific coding-style.md + structure.md + tech-stack.md
  2. MCP generate_* bundles include those steering files
  3. tasks.md must tag UI vs logic so Design2Code never owns BLoC/state/tests
  4. review_code / host AI should reject PRs that violate layer boundaries