---
name: step-03-execute
description: Orchestrate code creation via existing skills and MCP tools
model: opus
prev_step: steps/step-02-plan.md
next_step: steps/step-04-examine.md
---

# Step 3: Execute — Orchestrator

**ULTRA THINK about the full execution context. Before dispatching layers, verify: are we creating a NEW module or UPDATING an existing one? This is critical for Layer 1 (seed data) — existing seed files must be MODIFIED, not recreated or skipped.**

/apex ORCHESTRATES. It does not write SmartStack code directly.
All code goes through skills (/controller, /application, /ui-components, /efcore) or MCP tools.

**This step dispatches to layer-specific sub-steps.** Each sub-step is loaded sequentially.

## LOAD CONDITIONALLY

> CONTEXT REUSE: `smartstack-api.md` (loaded in step-01) and `smartstack-layers.md` (loaded in step-02) are already in context. Do not re-read them.

- Read `references/core-seed-data.md` — comprehensive seed data templates (needed for Layer 1, released after)
- Defer `references/smartstack-frontend.md` until Layer 3 — lazy loading, i18n, page structure, CSS variables, EntityLookup (sections 1-6)
- Defer `references/smartstack-frontend-compliance.md` until Layer 3 — documentation, form testing, compliance gates (sections 7-9)
- If NOT `{economy_mode}` AND a layer has multi-entity work: read `references/parallel-execution.md`
- If build failure during execution: read `references/error-classification.md` — error diagnosis categories A-F

---

## Foundation Mode Detection

**IF `{foundation_mode}` == true:**
Execute ONLY Layer 0 (domain entities + EF configs + migration). Skip all other layers.
After Layer 0 completes: commit `chore(foundation): entities for {module_code}`, jump to step-04.

**IF `{foundation_mode}` == false:**
Execute all layers (Layer 0 → Layer 1 → Layer 2 → Layer 3 → Layer 4).

---

## Context Recovery Protocol

> **Run this check BEFORE each layer** to survive context compression.

```
BEFORE starting Layer N:
  Verify these variables are still accessible:
    {app_name}, {module_code}, {sections}, {entities}, {code_patterns}
    IF delegate_mode: also verify {delegate_prd_path}, {specification_loading_plan}

  IF any variable is missing or empty:
    1. Read .claude/output/apex/{task_id}/state.json (if exists)
    2. IF state.json has delegate context:
       - {delegate_prd_path} = state.delegate_prd_path
       - {delegate_mode} = state.delegate_mode
       - Re-read PRD at {delegate_prd_path} to rebuild specification_loading_plan:
         const prd = readJSON(delegate_prd_path);
         if (prd.specificationFiles) {
           specification_loading_plan = {
             layer0_domain:   [prd.specificationFiles.entities],
             layer1_seed:     [prd.specificationFiles.entities, prd.specificationFiles.permissions],
             layer2_backend:  [prd.specificationFiles.rules, prd.specificationFiles.usecases],
             layer3_frontend: [prd.specificationFiles.screens, prd.specificationFiles.usecases]
           };
         }
       - {app_name} = state.app_name || prd.project?.application || prd.metadata?.applicationCode
       - {module_code} = state.module_code || prd.project?.module || prd.metadata?.moduleCode
    3. IF state.json missing OR no delegate context → re-derive from filesystem:
       - {app_name}: Glob("docs/business/*/") → first directory name
       - {module_code}: Glob("src/**/Domain/Entities/*/") → target module directory
       - {entities}: Glob("src/**/Domain/Entities/{module_code}/*.cs") → entity names
       - {sections}: Glob("src/**/Seeding/Data/{module_code}/*NavigationSeedData.cs") → parse
       - {code_patterns}: Read state.json or re-derive from DependencyInjection.cs
    4. IF recovered: verify consistency with naming derivation rules (step-00 §4f)
    5. IF Layer N-1 already completed: skip to Layer N directly

  Cost: ~5-8 tool calls. Only triggered if context was compressed.
```

---

## Layer Dispatch

> **CRITICAL RULES — LAYER EXECUTION GUARANTEE**
>
> - **NEVER** stop between layers. NEVER ask the user. NEVER present numbered options between layers.
> - The pipeline is sequential and mandatory: **0 → 1 → 2 → 3 → 4 → step-04**, with **ZERO pauses**.
> - After each sub-step completes, IMMEDIATELY load the next one. No summary, no confirmation request.
> - Stopping between layers is a **VIOLATION** of the execution guarantee defined in SKILL.md.

Load each sub-step sequentially:

| Layer | Sub-step | Content |
|-------|----------|---------|
| 0 | `steps/step-03a-layer0-domain.md` | Domain entities, EF configs, migration |
| 1 | `steps/step-03b-layer1-seed.md` | Seed data (navigation, permissions, roles) |
| 2 | `steps/step-03c-layer2-backend.md` | Services, controllers, backend tests |
| 3 | `steps/step-03d-layer3-frontend.md` | Pages, i18n, routes, frontend tests |
| 4 | `steps/step-03e-layer4-devdata.md` | Development test data (optional) |

**FIRST ACTION:** Load `steps/step-03a-layer0-domain.md`

---

## PRD State Update (delegate mode only)

> **After completing EACH layer**, update the PRD file so `/business-analyse-develop` can track progress.

```
IF delegate_mode:
  After each layer completes successfully:
    Read {delegate_prd_path}
    For each task executed in this layer:
      task.status = 'completed'  (or 'failed' if errors)
      task.completed_at = new Date().toISOString()
      task.iteration = 1  (delegate mode = single iteration)
      task.commit_hash = $(git rev-parse --short HEAD)
      task.files_changed = { created: [...], modified: [...] }
      task.validation = "APEX_PASS" (or error details)
    prd.updated_at = new Date().toISOString()
    Write back to {delegate_prd_path}
```

---

## Commits Per Layer

```
Layer 0: feat({module}): [domain+infra] {short description}
Layer 1: feat({module}): [seed] navigation, permissions, roles
Layer 2: feat({module}): [app+api] {short description}
Layer 2: test({module}): backend unit and integration tests
Layer 3: feat({module}): [frontend] pages, routes, i18n, documentation
Layer 3: test({module}): frontend form tests
Layer 4: feat({module}): [devdata] test data for development  # if applicable
```

**Maximum 7 commits per module.**

---

## State Auto-Save (after each layer)

> **Automatic** — not dependent on `-s` flag. Enables reliable resume after context loss.
> **CRITICAL (audit ba-003):** Delegate context MUST be persisted for resume to work in delegate mode.

After each layer's build gate passes, write state to `.claude/output/apex/{task_id}/state.json`:

```json
{
  "step": 3, "layer": 2,
  "completed_layers": [0, 1, 2],
  "completed_entities": ["Employee", "Department"],
  "files_created": ["Employee.cs", "EmployeeConfiguration.cs", "..."],
  "build_gates": { "layer0": "pass", "layer1": "pass", "layer2": "pass" },
  "commits": ["abc1234", "def5678", "ghi9012"],
  "timestamp": "2026-03-06T14:30:00Z",
  "delegate_mode": true,
  "delegate_prd_path": ".ralph/prd-employees.json",
  "app_name": "HumanResources",
  "module_code": "employee-management",
  "sections": ["employees", "departments"],
  "entities": ["Employee", "Department"]
}
```

> **Fields `delegate_mode`, `delegate_prd_path`, `app_name`, `module_code`, `sections`, `entities`**
> are persisted so that Context Recovery Protocol (above) can restore the full execution context
> after context compression or resume (`-r`). The `specification_loading_plan` is rebuilt from the
> PRD file at `delegate_prd_path` — no need to serialize it directly.

---

## Save Output (if save_mode)

Write to `{output_dir}/03-execute.md` with execution log per layer.

---

## NEXT STEP

Load `steps/step-04-examine.md`
