---
name: step-05-report
description: Generate final report from prd.json structured data
next_step: null
---

# Step 5: Generate Report

## YOUR TASK:

Generate a comprehensive feature report using structured data from prd.json.

---

## 1. Load Data

```javascript
const prd = readJSON('.ralph/prd.json');
const stats = {
  feature: prd.feature, status: prd.status,
  iterations_used: prd.config.current_iteration - 1,
  tasks: {
    total: prd.tasks.length,
    completed: prd.tasks.filter(t => t.status === 'completed').length,
    failed: prd.tasks.filter(t => t.status === 'failed').length,
    blocked: prd.tasks.filter(t => t.status === 'blocked').length
  }
};

// Aggregate files from all tasks (populated by apex during execution)
const filesCreated = [...new Set(prd.tasks.flatMap(t => t.files_changed?.created || []))];
const filesModified = [...new Set(prd.tasks.flatMap(t => t.files_changed?.modified || []))];
const totalDuration = prd.history.reduce((sum, h) => sum + (h.duration_seconds || 0), 0);
```

### 1b. Multi-Module Aggregation

```javascript
const queuePath = '.ralph/modules-queue.json';
let moduleStats = null;
if (fileExists(queuePath)) {
  const queue = readJSON(queuePath);
  moduleStats = { totalModules: queue.totalModules, completedModules: queue.completedModules, modules: [] };
  for (const mod of queue.modules) {
    const modPrd = readJSON(mod.prdFile);
    moduleStats.modules.push({
      code: mod.code, status: mod.status,
      tasks: { total: modPrd.tasks.length, completed: modPrd.tasks.filter(t => t.status === 'completed').length, failed: modPrd.tasks.filter(t => t.status === 'failed').length },
      filesCreated: [...new Set(modPrd.tasks.flatMap(t => t.files_changed?.created || []))].length,
      commits: [...new Set(modPrd.tasks.filter(t => t.commit_hash).map(t => t.commit_hash))].length
    });
  }
}
```

### 1c. Test Metrics (from PRD)

> **Note:** Apex already ran tests and recorded results. Source metrics from PRD task data.

```javascript
const testTasks = prd.tasks.filter(t => t.category === 'test');
const testsPassed = testTasks.filter(t => t.status === 'completed').length;
const testsFailed = testTasks.filter(t => t.status === 'failed').length;
```

## 2. Generate Report

Write to `.ralph/reports/{feature-slug}.md`:

```markdown
# Feature Report: {feature}

## Summary
| Field | Value |
|-------|-------|
| Status | {status} |
| Iterations | {iterations_used} / {max} |
| Branch | {branch} |
| Duration | {totalDuration}s ({min} min) |
| Execution | Delegated to /apex |

## Tasks
| # | Task | Category | Status | Commit |
|---|------|----------|--------|--------|
{for each task:}
| {id} | {description} | {category} | {status_emoji} | {commit_hash} |

**{completed}/{total} completed, {failed} failed, {blocked} blocked**

{if moduleStats:}
## Modules
| Module | Status | Tasks | Completed | Failed | Files | Commits |
|--------|--------|-------|-----------|--------|-------|---------|
{for each mod:}
| {code} | {status} | {total} | {completed} | {failed} | {filesCreated} | {commits} |

**{completedModules}/{totalModules} modules completed**
{end if}

{if prd._sectionSplit?.enabled:}
## Section Split Execution
| Phase | Type | Section | Entities | Status |
|-------|------|---------|----------|--------|
{for each phase:}
| {phase} | {type} | {sectionCode || '-'} | {entities.length} | {status} |

{end if}

## Test Metrics
| Metric | Value |
|--------|-------|
| Test Tasks | {testTasks.length} |
| Passed | {testsPassed} |
| Failed | {testsFailed} |

## Failed Tasks
{table of failed tasks with error messages, or "None"}

## Files
- Created: {filesCreated.length}
- Modified: {filesModified.length}

## Commits
{unique commits list}

---
*Auto-generated by Ralph Loop — SmartStack CLI*
```

## 3. Finalize

```javascript
// Clean up section-split temporary files
if (prd._sectionSplit?.enabled) {
  for (const phase of prd._sectionSplit.phases) {
    if (fileExists(phase.prdFile) && phase.prdFile !== '.ralph/prd.json') {
      deleteFile(phase.prdFile);
    }
  }
  delete prd._sectionSplit;
}

prd.updated_at = new Date().toISOString();
writeJSON('.ralph/prd.json', prd);
```

## 4. Display Summary

```
RALPH LOOP COMPLETE
Feature: {feature} | Status: {status}
Iterations: {n} | Tasks: {completed}/{total}
{moduleStats ? `Modules: ${completedModules}/${totalModules}` : ""}
Files: {created} created, {modified} modified
Report: .ralph/reports/{slug}.md
```

## 5. Completion Promise (if applicable)

```
<promise>{completion_promise}</promise>
```

## 6. Next Steps

```
1. Review report: .ralph/reports/{slug}.md
2. Run full test suite: dotnet test
3. Create PR: /gitflow pr
4. Clean up: rm -rf .ralph/ (optional)
```

---

Ralph loop complete. No more steps.
