Skip to content
SaaS4Builders
Claude Code

Workplan Execution

The workplan and Work Unit pattern for structured AI-driven feature development: planning, dependency management, implementation, and progress tracking.

The workplan system is the execution backbone for AI-assisted feature development. It breaks complex features into small, dependency-ordered Work Units (WUs) that an AI agent can implement one at a time, with clear acceptance criteria and verification commands.

This is how every major feature in SaaS4Builders was built — from the first migration to the billing engine to the teams system. The pattern scales from a single API endpoint to a multi-week, multi-stack feature.


The Pattern at a Glance

The workplan execution cycle has five steps:

  1. Plan — Write a workplan with dependency graph and Work Unit specifications
  2. Initialize — Create a tracking file with all WUs listed as pending
  3. Execute — Implement WUs in dependency order, one at a time
  4. Track — Update the tracking file after each WU is completed
  5. Cascade — Proceed to the next WU whose dependencies are now met
flowchart LR
    A["Workplan<br/>(plan)"] --> B["Tracking<br/>(init)"]
    B --> C["Execute<br/>(WU-B01)"]
    C --> D["Update<br/>tracking"]
    C --> E["Execute<br/>(WU-B02)"]
    D --> E
    E --> F["repeat"]

Each Work Unit is self-contained — code compiles and tests pass after completion. This means you can stop after any WU and the project remains in a working state.


Workplan Structure

A workplan is a Markdown document that specifies everything an AI agent needs to implement a feature. It lives in the docs/workplans/ directory.

Every workplan starts with a header that identifies the milestone and scoping:

# M{id} — {Feature Title} Workplan

> **Phase:** M{id} — {Feature Title}
> **Duration:** {estimated time}
> **Work Units Backend:** {count}
> **Work Units Frontend:** {count}
> **Prerequisites:** {list of completed milestones, or "None"}

The milestone ID (e.g., M4, M5, M6) uniquely identifies the workplan. Backend Work Units use the WU-B prefix, frontend Work Units use WU-F.

Context and Objectives

After the header, the workplan establishes what will be built and — critically — what will NOT:

## Context

**Problem:** {What problem does this feature solve?}

**Objective:** {One-sentence goal}

**Non-Goals:**
- {Feature or scope item explicitly excluded}
- {Another excluded item}
- {A third excluded item}
The Non-Goals section is the primary defense against scope creep. When an AI agent encounters an edge case during implementation, it checks the non-goals list before building a solution. If the edge case falls outside scope, the agent reports it and moves on instead of gold-plating.

Dependency Graph

The dependency graph shows which Work Units must be completed before others can start. Dependencies follow the architecture layers — domain primitives before business logic, business logic before HTTP layer:

flowchart TD
    A["LAYER 1 — Domain Primitives<br/>WU-B01: Models, migrations, factories, enums, DTOs"] --> B["LAYER 2 — Business Logic<br/>WU-B02: Actions / WU-B03: Queries"]
    B --> C["LAYER 3 — HTTP Layer<br/>WU-B04: Controllers, Requests, Resources, routes"]
    C --> D["LAYER 4 — Integration Tests<br/>WU-B05: End-to-end API tests, tenant isolation tests"]

Dependencies flow downward only. A WU in Layer 2 can depend on WUs in Layer 1, but never on Layer 3 or 4. This mirrors the architecture — Actions depend on Models, not on Controllers.

Individual Work Unit Specification

Each WU in the workplan includes everything the agent needs to implement it:

## WU-B01: Domain Primitives

**Objective:** Create foundational models, migrations, factories, enums,
and DTOs for the notifications feature.

**Files (8):**
- `database/migrations/2026_01_15_000001_create_notifications_table.php` (new)
- `app/Domain/Notification/Enums/NotificationType.php` (new)
- `app/Domain/Notification/Enums/NotificationChannel.php` (new)
- `app/Models/Notification.php` (new)
- `database/factories/NotificationFactory.php` (new)
- `app/Application/Notification/DTO/CreateNotificationData.php` (new)
- `tests/Unit/Domain/Notification/Enums/NotificationTypeTest.php` (new)
- `tests/Unit/Domain/Notification/Enums/NotificationChannelTest.php` (new)

**Dependencies:** None

### Implementation Details

- Migration: UUID primary key, `tenant_id` FK (indexed), `user_id` FK,
  `type` enum, `channel` enum, `data` JSON, timestamps, soft deletes
- Model: `BelongsToTenant` trait, `HasUuids`, `HasFactory`, `SoftDeletes`
- Factory: realistic states for each notification type
- Enums: include helper methods (`isTransient()`, `requiresDelivery()`)

### Acceptance Criteria
- [ ] Migration creates `notifications` table with UUID PK and tenant_id FK
- [ ] Model uses `BelongsToTenant`, `HasUuids`, `HasFactory`
- [ ] Factory includes states for each notification type
- [ ] 2 enums with helper methods
- [ ] `docker compose exec php vendor/bin/pint --dirty` passes
- [ ] 8 tests passing

### Verification Commands
```bash
docker compose exec php php artisan test --compact --filter=Notification
docker compose exec php vendor/bin/pint --dirty
docker compose exec php vendor/bin/phpstan analyse --memory-limit=1G

Key rules for WU specifications:

- **Each WU should be completable in a single session** — if it requires multiple sessions, split it
- **Tests are part of the WU**, not a separate WU — implementation and testing happen together
- **File paths are explicit** — not "create a migration" but the exact migration filename
- **Acceptance criteria are objectively verifiable** — "8 tests passing" not "good test coverage"

---

## Progress Tracking

A companion tracking file records the actual implementation of each Work Unit. It mirrors the workplan structure but captures what was actually built, not what was planned.

### Initial State

When a milestone begins, the tracking file is initialized:

```markdown
# Current Work Unit Progress — M{id}

**Milestone:** M{id} — {Feature Title}
**Last Updated:** 2026-03-27

---

(Work units will be documented here as they are completed.)

After a Work Unit Is Completed

Each completed WU gets a section with implementation details:

## WU-B01: Domain Primitives

**Status:** Completed

### Overview
Created foundational models, migrations, factories, and enums for the
notifications feature. Includes 2 enums with helper methods, 1 model
with tenant scoping, and 1 factory with type-specific states.

### Files Created
| File | Purpose |
|------|---------|
| `database/migrations/..._create_notifications_table.php` | Notifications table with UUID PK, tenant_id FK |
| `app/Domain/Notification/Enums/NotificationType.php` | Enum: email, push, sms with `isTransient()` helper |
| `app/Models/Notification.php` | Eloquent model with BelongsToTenant, HasUuids |
| `database/factories/NotificationFactory.php` | Factory with states per notification type |
| `app/Application/Notification/DTO/CreateNotificationData.php` | Input DTO for notification creation |

### Files Modified
| File | Changes |
|------|---------|
| None | — |

### Test Coverage
| Test File | Tests | Description |
|-----------|-------|-------------|
| `NotificationTypeTest.php` | 5 | Enum values, helpers, edge cases |
| `NotificationChannelTest.php` | 3 | Channel validation and properties |

### Verification Commands
```bash
docker compose exec php php artisan test --compact --filter=Notification
docker compose exec php vendor/bin/pint --dirty

Acceptance Criteria

  • Migration creates notifications table with UUID PK and tenant_id FK
  • Model uses BelongsToTenant, HasUuids, HasFactory
  • Factory includes states for each notification type
  • 2 enums with helper methods
  • Pint passes
  • 8 tests passing

This creates a complete audit trail: what was built, how it was verified, what tests cover it. When you return to the project weeks later — or when a different developer picks up the next milestone — the tracking file shows exactly where things stand.

---

## The /implement-wu Workflow

The [`/implement-wu`](/docs/ai-assisted-development/claude-code/skills-system) skill automates the execution of individual Work Units. It follows a strict five-phase process.

### Phase 1 — Context (Read Only)

The agent reads before it writes:

1. Parses the arguments to identify the target milestone and WU (e.g., `M6 WU-B03`)
2. Reads the **tracking file** to check if the WU is already completed
3. Reads the **workplan** to extract the full WU specification
4. Checks the **dependency graph** — if any prerequisite WU is not completed, the agent stops and reports
5. Loads **project conventions** (CLAUDE.md, API contracts) based on WU scope

::callout{type="warning"}
Phase 1 is not optional. The agent never writes code before reading the workplan and verifying dependencies. If a dependency is unmet, it reports the blocker instead of proceeding.
::

### Phase 2 — Plan (User Validation)

The agent presents a plan and waits for your approval:

1. Lists all files to create and modify, with purposes
2. Finds **reference patterns** — existing similar files in the codebase to match structure and conventions
3. Identifies **test scenarios** from the acceptance criteria
4. Presents the full plan including any concerns or questions

The agent does **not** proceed to implementation until you explicitly validate the plan. This is your last chance to catch misunderstandings before code is written.

### Phase 3 — Implementation

With the plan approved, the agent implements:

1. Reads each reference pattern file identified in Phase 2
2. Implements following the same structure and conventions
3. Writes **tests in parallel with code** — not after. For each piece of functionality, the implementation file and its test are created together.
4. Adds **translations** in all 4 locales (en, fr, es, it) if the WU introduces user-facing strings

### Phase 4 — Quality Gate

Before marking the WU as complete, the agent runs all relevant checks:

::code-group
```bash [Backend]
# Code formatting
docker compose exec php vendor/bin/pint --dirty

# Static analysis
docker compose exec php vendor/bin/phpstan analyse --memory-limit=1G

# Targeted tests
docker compose exec php php artisan test --compact --filter=<RelevantTest>
Frontend
# Type checking
docker compose exec node pnpm typecheck

# Linting
docker compose exec node pnpm lint

# Tests
docker compose exec node pnpm test -- --run

::

The agent then verifies each acceptance criterion one by one, describing how it was verified (test name, command output, or manual check). If a criterion cannot be verified, it is reported explicitly — never silently checked off.

Phase 5 — Tracking

The agent updates the tracking file with the completed WU entry:

  • Status set to completed
  • Files created and modified listed with purposes
  • Test coverage table with file names and test counts
  • Verification commands recorded
  • All acceptance criteria checked off
  • "Last Updated" header updated with the current date and WU description

Creating Your Own Workplans

Using /create-workplan

The /create-workplan skill provides an interactive, guided process:

Phase 1 — Discovery: The agent asks you questions step by step — feature name, technical scope (backend/frontend/full-stack), impacted domains, new models and tables, API endpoints, frontend pages, prerequisites, and non-goals.

Phase 2 — Codebase Analysis: The agent scans the actual codebase to find reference patterns, verify that models and tables don't already exist, and identify integration points with existing features.

Phase 3 — WU Decomposition: Based on your answers and the codebase analysis, the agent breaks the feature into ordered Work Units following the layer decomposition pattern.

Phase 4 — File Generation: The agent writes the workplan file and initializes the tracking file, ready for /implement-wu execution.

The /create-workplan skill scans docs/workplans/ to find the next available milestone ID and suggests it automatically. You can accept or override the suggestion.

Manual Workplan Writing

For smaller features or modifications to existing code, you may prefer to write workplans manually. Key rules:

  • Be explicit about file paths — not "create a migration" but database/migrations/2026_03_27_000001_create_notifications_table.php
  • Include real code patterns — reference existing files as examples, not pseudocode
  • Set acceptance criteria as verifiable checkboxes — "8 tests passing (24 assertions)" not "good test coverage"
  • Keep WUs small — each should be completable in a single session
  • Include verification commands — the exact docker compose exec commands to run

Layer Decomposition Pattern

When breaking a feature into Work Units, follow the architecture layers:

Backend:

  1. Domain Primitives — Models, migrations, factories, enums, DTOs
  2. Business Logic — Actions (mutations) and Queries (reads)
  3. Infrastructure — External provider integrations, mappers
  4. HTTP Layer — Controllers, Requests, Resources, routes
  5. Integration Tests — End-to-end API tests, tenant isolation tests

Frontend:

  1. Data Layer — Zod schemas, TypeScript types
  2. API Module — API client composable with Zod validation
  3. State and Logic — Composables wrapping API calls and reactive state
  4. Components — Vue components consuming composables
  5. Pages — Page-level components with routing and middleware
Follow the dependency order. An Action that depends on a Model cannot be implemented before the Model exists. A composable that calls an API module cannot be implemented before the API module exists. The layer pattern encodes these dependencies naturally.

Tips for Effective AI-Driven Development

Seven practices that make workplan execution more reliable:

1. Start with the Dependency Graph

The most common failure mode is implementing a WU before its prerequisites are ready. Always define the dependency graph first. If WU-B03 depends on WU-B01 and WU-B02, the agent cannot start WU-B03 until both are completed.

2. Include Code Examples, Not Pseudocode

An AI agent follows concrete patterns better than abstract descriptions. Instead of "create a DTO with the notification fields," show:

// Reference: app/Application/Billing/DTO/CreateSubscriptionData.php
final readonly class CreateNotificationData
{
    public function __construct(
        public string $tenantId,
        public string $userId,
        public NotificationType $type,
        public NotificationChannel $channel,
        public array $data,
    ) {}
}

The agent will match the structure, naming, and conventions of the example.

3. Set Verifiable Acceptance Criteria

Not "tests pass" but:

- [ ] 8 tests passing (24 assertions) covering happy path, validation, and tenant isolation
- [ ] `docker compose exec php vendor/bin/pint --dirty` produces no changes
- [ ] `docker compose exec php vendor/bin/phpstan analyse` passes at level 9

The agent can objectively verify each criterion. There is no ambiguity about what "done" means.

4. Use Non-Goals Aggressively

Every feature that is NOT in scope should be listed explicitly. This prevents the agent from gold-plating or adding "nice to have" features:

**Non-Goals:**
- Email notifications (future milestone)
- Notification preferences UI
- Notification batching or digest
- WebSocket real-time delivery (use polling in V1)

5. Review Phase 2 Output Carefully

The plan that /implement-wu presents in Phase 2 is your last chance to catch misunderstandings before code is written. Check that:

  • File paths match your project structure
  • Reference patterns are from the right domain (not an unrelated feature)
  • Test scenarios cover the acceptance criteria
  • No scope creep — the agent is not adding features beyond the WU specification

6. One Work Unit Per Session

Each Work Unit is designed to be completable in a single Claude Code session. If a WU spans multiple sessions, it is too large — split it into smaller WUs. A good WU creates 3-8 files, writes 5-15 tests, and has 4-8 acceptance criteria.

7. Trust the Quality Gate

Do not skip Phase 4. The formatting checks (Pint, ESLint), static analysis (PHPStan level 9, TypeScript strict), and test runs catch issues that are expensive to find later. If the quality gate fails, the agent fixes the issue before marking the WU as complete.


What's Next