---
name: step-02-export
description: Generate PRD files, verify integrity, output progress tracker and manifest
model: sonnet
---

> **Context files:** `references/prd-generation.md` | `templates/tpl-progress.md`

# Step 02: Export (PRD + Verification)

## MANDATORY EXECUTION RULES

- **ALWAYS** generate PRD via `ss derive-prd` CLI command (deterministic, never LLM)
- **ALWAYS** verify PRD structure: $version=3.0.0, implementation.filesToCreate, 8 categories
- **ALWAYS** verify file counts match between PRD and handoff
- **ALWAYS** generate progress.txt from template
- **ALWAYS** update BA manifest (docs/index.json)
- **NEVER** skip POST-CHECK validation

## YOUR TASK

For each module, generate PRD files via CLI, verify integrity, create progress tracker, update manifest, and display completion summary.

---

## EXECUTION SEQUENCE

### 1. Generate PRD Files

For EACH module:

**Option A — Flat-file BA (recommended):**

```bash
# Single module:
ss derive-prd --ba-dir {moduleBaDir} --output .ralph/prd-{moduleCode}.json

# All modules from app-level index.json:
ss derive-prd --ba-app {appIndexPath}
```

**Option B — Legacy feature.json:**

```bash
ss derive-prd --feature {moduleFeaturePath} --output .ralph/prd-{moduleCode}.json
```

### 2. POST-CHECK PRD (BLOCKING)

> **Reference:** Read `references/prd-generation.md` for complete validation rules.

```javascript
const prd = readJSON(`.ralph/prd-${moduleCode}.json`);
const featureHandoff = moduleFeature.handoff.filesToCreate;

// Check 1: Version
if (prd.$version !== "3.0.0") {
  BLOCKING_ERROR("PRD version must be 3.0.0, got: " + prd.$version);
}

// Check 2: filesToCreate under implementation (not root)
if (prd.filesToCreate && !prd.implementation?.filesToCreate) {
  BLOCKING_ERROR("prd.json has filesToCreate at ROOT — not from ss derive-prd");
  STOP;
}

// Check 3: All 8 categories present
const categories = ['domain', 'application', 'infrastructure', 'api', 'frontend', 'seedData', 'tests', 'documentation'];
const missingCategories = categories.filter(cat => !prd.implementation.filesToCreate[cat]);
if (missingCategories.length > 0) {
  BLOCKING_ERROR("Missing categories: " + missingCategories.join(', '));
}

// Check 4: File counts match
for (const cat of categories) {
  const prdCount = prd.implementation.filesToCreate[cat]?.length ?? 0;
  const featureCount = featureHandoff[cat]?.length ?? 0;
  if (prdCount !== featureCount) {
    BLOCKING_ERROR(`${cat}: prd=${prdCount} but feature=${featureCount}`);
  }
}
```

Display verification table showing all 8 categories match between module JSON files and prd.json.

### 3. Generate modules-queue.json (if 2+ modules)

```json
{
  "queue": [
    { "moduleCode": "{code}", "order": 1, "dependencies": [], "complexity": "simple" },
    { "moduleCode": "{code}", "order": 2, "dependencies": ["{dep}"], "complexity": "medium" }
  ],
  "totalModules": {count},
  "strategy": "topological"
}
```

Write to: `.ralph/modules-queue.json`

### 4. Generate progress.txt

> **Template:** Read `templates/tpl-progress.md` for complete structure.
> **Data source:** Populate with module-specific data from index.json.

- One section per module in topological order
- CORE SeedData: 5 entries (mandatory)
- Business SeedData: per module (varies)
- Hierarchical task structure (module -> layer -> tasks)
- Each task: checkbox, description, effort, dependencies
- Summary with totals across all modules
- Cross-module tasks IF multi-module

Write to: `.ralph/progress.txt`

### 5. Update BA Manifest (docs/index.json)

**Schema:**

```json
{
  "version": "1.0",
  "updatedAt": "{ISO timestamp}",
  "analyses": [
    {
      "appCode": "{app_code}",
      "appName": "{application_name}",
      "moduleCode": null | "{module_code}",
      "moduleName": "{module_name}",
      "version": "{version}",
      "status": "handed-off",
      "featureDescription": "{description}",
      "path": "{app_code}/business-analyse/v{version}/index.json",
      "updatedAt": "{ISO timestamp}"
    }
  ]
}
```

**Update logic:**

1. Read existing manifest (or create empty)
2. **PROJECT MODE:** Add/update project entry + all app entries + all module entries per app
3. **SINGLE-APP MODE:** Update app entry + module entries for this app
4. Write manifest back with updated timestamp
5. Display: "BA manifest updated: docs/index.json ({total} entries)"

### 6. Display Completion Summary

```
══════════════════════════════════════════════════════════════
  DERIVE-PRD COMPLETE — {application_name}
══════════════════════════════════════════════════════════════

Modules: {count} ({names})
Complexity: {simple|medium|complex}
Files: {total across all modules}
Tasks: {total}

Readiness Scores:
┌──────────────┬────────────┬──────────────┐
│ Module       │ Blocking   │ Files        │
├──────────────┼────────────┼──────────────┤
│ {module1}    │ 100%       │ {count}      │
│ {module2}    │ 100%       │ {count}      │
└──────────────┴────────────┴──────────────┘

Artifacts generated:
  .ralph/prd-{module}.json      — Task breakdown per module
  .ralph/progress.txt           — Progression tracker
  .ralph/modules-queue.json     — Module execution order (if multi-module)
  docs/index.json               — BA manifest (status: handed-off)

[NEXT] Development:
  1. Run /ralph-loop to begin implementation
  2. Modules will be processed in topological order
  3. Each module PRD contains {total_files} files across 8 categories

══════════════════════════════════════════════════════════════
```

---

## SELF-VERIFICATION (BEFORE COMPLETION)

1. `.ralph/prd-{module}.json` exists for ALL modules (>100 bytes each)
2. `.ralph/progress.txt` exists (>500 bytes)
3. `.ralph/modules-queue.json` exists (if 2+ modules)
4. `docs/index.json` updated with correct entry count and status "handed-off"
5. All PRD files have $version=3.0.0, implementation.filesToCreate, 8 categories
6. File counts match between PRD and handoff for all categories

**IF any check fails -> fix before completing.**
