---
name: step-03-commit
description: Commit changes, update prd.json v2 with full tracking
next_step: steps/step-04-check.md
---

# Step 3: Commit Changes

> **CONTEXT OPTIMIZATION:** Read ONCE (first iteration). Subsequent iterations use compact-loop.md.

## YOUR TASK:

Commit changes, finalize task tracking in prd.json, append to history.

---

## EXECUTION SEQUENCE:

### 0. Pre-Commit Validation (BLOCKING)

```bash
# Backend: build must pass
if [ "{current_task_category}" != "frontend" ] && [ "{current_task_category}" != "i18n" ]; then
  dotnet build --no-restore --verbosity quiet
fi

# Frontend: typecheck must pass
if [ "{current_task_category}" = "frontend" ]; then
  npm run typecheck
fi

# Tests: full suite if test project exists
TEST_PROJECT="tests/$(basename $(pwd)).Tests.Unit"
if [ -d "$TEST_PROJECT" ]; then
  dotnet test "$TEST_PROJECT" --no-build --verbosity minimal
  if [ $? -ne 0 ]; then
    echo "COMMIT BLOCKED: tests failing. Fix before committing."
    STOP — return to step-02
  fi
fi
```

### 1. Stage and Commit

```bash
git add {files_created} {files_modified} .ralph/prd.json
git commit -m "$(cat <<'EOF'
{PREFIX}({scope}): {current_task_description}

Task {current_task_id}/{tasks_total} - Iteration {current_iteration}
Category: {current_task_category}
{current_module ? "Module: " + current_module : ""}

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
EOF
)"

COMMIT_HASH=$(git rev-parse --short HEAD)
```

**Prefix mapping:**

| Category | Prefix |
|----------|--------|
| domain, application, api, frontend | `feat` |
| infrastructure | `db` |
| i18n | `chore` |
| test | `test` |
| validation, other | `chore` |

### 2. Finalize Task in prd.json

```javascript
const prd = readJSON('.ralph/prd.json');
const task = prd.tasks.find(t => t.id === {current_task_id});
const now = new Date().toISOString();

if (task.status !== 'failed') task.status = 'completed';
task.completed_at = now;
task.iteration = prd.config.current_iteration;
task.commit_hash = COMMIT_HASH;

prd.history.push({
  iteration: prd.config.current_iteration, task_id: task.id,
  action: task.status, timestamp: now, commit_hash: COMMIT_HASH,
  duration_seconds: Math.round((new Date(now) - new Date(task.started_at)) / 1000),
  notes: "{What was accomplished}"
});

prd.config.current_iteration++;
prd.updated_at = now;

const allDone = prd.tasks.every(t => t.status === 'completed' || t.status === 'skipped');
prd.status = allDone ? 'completed' : prd.tasks.some(t => t.status === 'failed' || t.status === 'blocked') ? 'partial' : 'in_progress';

writeJSON('.ralph/prd.json', prd);
```

### 3. Update progress.txt

Append iteration learnings (compact):
```markdown
## Iteration {iteration} — [{id}] {description}
Status: {status} | Commit: {hash} | Files: {count}
Learnings: {what was learned}
```

### 4. Commit Progress Files

```bash
git add .ralph/prd.json .ralph/progress.txt
[ -f .ralph/modules-queue.json ] && git add .ralph/modules-queue.json
git commit -m "chore(ralph): progress — task {id}/{total}"
```

### 5. Verify

```bash
git log -2 --oneline
```

---

## ERROR HANDLING:

- **Commit fails (pre-commit hook):** Fix issue, stage, create NEW commit (don't amend)
- **Task failed in step-02:** Still commit partial progress, status stays "failed"

---

## NEXT STEP:

After commit, proceed to `./step-04-check.md`
