# Tdd Dart Workflow

> Rules, constraints, boundaries, and best practices for the multi-agent Python to Dart porting workflow.

- Skill: `flutter/tdd-dart-workflow` (Agent Skill)
- Install (CLI): `npx skillmds@latest add flutter/tdd-dart-workflow`
- Raw SKILL.md: https://api.skillmd.com/api/skills/flutter/tdd-dart-workflow/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: flutter (https://skillmd.com/u/flutter)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/flutter/tdd-dart-workflow

---


# Python to Dart Porting Implementation Rules

These rules govern the development, design, and TDD workflow of porting a Python library to Dart. All agents running in this workspace must adhere strictly to these guidelines.

---

## 1. Multi-Agent TDD Workflow

Development proceeds in structured TDD cycles coordinated by the parent agent:

### Phase 0: Discovery & Architecture Blueprinting
* **Objective**: The Architect maps Python paradigms to Dart and produces `<dart_package_dir>/specs/architecture_blueprint.md`.
* **Gate**: The User must explicitly approve the blueprint before TDD cycles begin.

### Phase 1: Design Specification
* **Objective**: The Architect writes a targeted spec sheet under `<dart_package_dir>/specs/` (e.g. `<dart_package_dir>/specs/<module_name>_spec.md`) describing the interfaces, types, behaviors, and expected test cases for a single module.

### Phase 2: Write Failing Tests & Skeleton (Red Phase)
* **Step 2a (Tester)**: Writes unit tests in `<dart_package_dir>/test/` based on the spec (compilation errors targeting missing classes are expected here).
  * **Rule (Test Fakes vs Stubs)**: Label fakes/mocks kept permanently inside the test file as `// TEST UTILITIES - KEEP PERMANENTLY`. Label temporary stub classes that will be moved to `lib/` as `// SKELETON STUBS FOR COMPILATION - DELETE ONCE SKELETON IS IMPLEMENTED`.
* **Step 2b (Coder)**: Creates a skeleton (stub implementation) in `<dart_package_dir>/lib/src/` defining all required classes, constructors, methods, and properties, but returning dummy values or throwing `UnimplementedError()`.
* **Verification**: The Coordinator runs `dart test` and verifies the test compiles successfully and fails on execution due to `UnimplementedError` or assertion failure, NOT syntax or import errors.
  * **Clean Up**: Once the Coder implements the skeleton, the Coordinator removes the compilation stubs from the test file while preserving the permanent test utilities.

### Phase 3: Implement & Make Pass (Green Phase)
* **Objective**: The Coder reads the spec and test, and updates the library implementation in `<dart_package_dir>/lib/` to make all tests pass.
* **Verification**: The Coordinator runs `dart test` and verifies the tests pass successfully.

### Phase 4: Commit & Record
* **Objective**: The Coordinator stages and commits both the new test and the code.

### Phase 5 & 6: Integration & Documentation
* Port Python examples to `<dart_package_dir>/example/` (Treated as Integration Tests) and create the developer-facing skill documentation in `<dart_package_dir>/skills/`.

---

## 2. Agent Constraints & Boundaries

To preserve strict roles, agents are restricted to write to specific directories:

| Agent Role | Allowed Read Path | Allowed Write Path | Forbidden Actions |
|---|---|---|---|
| **Coordinator (Parent)** | Anywhere | Anywhere | Direct code modifications (delegates to Coder/Tester instead) |
| **Architect** | Anywhere | `<dart_package_dir>/specs/`, `skills/` | Cannot write to `<dart_package_dir>/lib/`, `<dart_package_dir>/test/`, or `<dart_package_dir>/example/` |
| **Tester** | Anywhere | `<dart_package_dir>/test/`, `<dart_package_dir>/example/` | Cannot write to `<dart_package_dir>/lib/` or `<dart_package_dir>/specs/` |
| **Coder** | Anywhere | `<dart_package_dir>/lib/`, `<dart_package_dir>/example/` | Cannot write to `<dart_package_dir>/test/` or `<dart_package_dir>/specs/` |

*Note: The Coordinator is the only agent allowed to execute Git operations or run arbitrary tests in the shell.*

---

## 3. Git Commit Rules

- **Execution**: Only the Coordinator agent (or the user) runs Git commands. Subagents have no Git permissions.
- **Timing**: Commits are made only when a TDD cycle is successfully completed (tests are Green) or a refactoring pass is verified. No commits of broken code.
- **Formatting**: Must adhere to the `git-commit-workflow` rules:
  - Capitalize the first word.
  - Keep under 60 characters.
  - Pithy, paratactic descriptions (e.g., `Add AgentConfig properties, write unit tests`).

---

## 4. Dart Best Practices

- **Strict Types**: Always use explicit type annotations for public APIs (no raw `dynamic` unless required by external JSON parsing). Avoid `dynamic` collections (use generics or shared interface classes).
- **Asynchrony**: Use Dart `Future` for async values and `Stream` for streaming data (e.g. async event stream).
- **Unit Testing**: Use `package:test` for writing tests. Place tests in `<dart_package_dir>/test/` mirroring the structure of `<dart_package_dir>/lib/src/`.
- **Formatting & Analysis**: Run `dart format .` and `dart analyze` inside `<dart_package_dir>/` before verifying implementations.
- **Code Generation**: Use `package:json_serializable` or `freezed` via `build_runner` for serialization. Avoid writing custom JSON parser logic unless necessary.
- **Mocking**: Use structured mocking libraries like `package:mocktail` or `package:mockito` instead of patching dynamic properties.
- **Abstract Interface Pattern**: Instead of dynamic property/method checks (`hasattr`), use Dart `abstract interface class` definitions, or explicit callback delegates to achieve same results type-safely.
- **Iterable Custom Builders**: If a custom builder class represents a list or collection of items that Python would unpack/spread, make the class implement `Iterable<T>` (forwarding its iterator to the underlying list) or expose an explicit collection getter (e.g. `.transitions`, `.items`) so that Dart's spread operator (`...`) can be used cleanly in configurations.

