# Resume and Recovery Logic

> **Reference for:** step-00-init.md sections 4 (Resume Mode) and 4a (Auto-Recovery)
> **Purpose:** Handle resumption of interrupted loops and auto-recovery from BA artifacts

---

## Resume Mode

If `{resume_mode} = true` (user passed `-r` flag):

```javascript
// Check PRD exists
if (!fileExists('.ralph/prd.json')) {
  console.error('ERROR: -r flag set but .ralph/prd.json not found');
  STOP;
}

const prd = readJSON(currentPrdPath);

// Detect format
let resumeValid = false;
if (prd.$version === '3.0.0') {
  // v3 unified — native format
  resumeValid = true;
  console.log('Resume: v3.0.0 unified PRD');
} else if (prd.$version === '2.0.0') {
  // v2 legacy — OK to resume
  resumeValid = true;
  console.log('Resume: v2.0.0 legacy PRD');
} else if (prd.project && prd.requirements && !prd.$version) {
  // FORMAT A deprecated — warn but transform
  console.warn('⚠ DEPRECATED: FORMAT A prd.json detected during resume');
  console.warn('Re-run `ss business-analyse-handoff` to generate v3 format');
  // NOTE: Transformation happens in step-01, not here
  resumeValid = true;
} else {
  console.error('ERROR: .ralph/prd.json format not recognized');
  STOP;
}

if (resumeValid) {
  // Check branch consistency
  const branch = prd.metadata?.branch || 'unknown';
  const currentBranch = getCurrentBranch();
  if (branch !== currentBranch) {
    console.warn(`⚠ Branch mismatch: PRD from ${branch}, currently on ${currentBranch}`);
    console.warn('Continuing anyway — verify this is intentional');
  }

  // Restore state
  {current_iteration} = prd.config?.current_iteration || 1;
  {completion_promise} = prd.config?.completion_promise || null;
  {max_iterations} = prd.config?.max_iterations || 50;

  // Restore multi-module state if present
  if (fileExists('.ralph/modules-queue.json')) {
    {modules_queue} = readJSON('.ralph/modules-queue.json');
    {current_module} = {modules_queue}.modules[{modules_queue}.currentIndex]?.code;
    console.log(`Multi-module resume: ${{current_module}} (${{modules_queue}.currentIndex + 1}/${{modules_queue}.totalModules})`);
  }

  console.log(`Resuming from iteration ${{current_iteration}}`);
  // Continue to step-01
}
```

### Ralph State Recovery (context compression defense)

> **When context compression occurs mid-execution**, conversation variables are lost.
> `ralph-state.json` tracks the current position and is written before each major transition.
> This section reads it back to recover position.

```javascript
// ALWAYS attempt to read ralph-state.json on resume — regardless of -r flag
// This file is written by: step-00 init, step-02 execute, compact-loop, module-transition
const statePath = '.ralph/ralph-state.json';
if (fileExists(statePath)) {
  const state = readJSON(statePath);

  console.log(`Ralph state recovered: step=${state.currentStep}, module=${state.currentModule}, ` +
    `iteration=${state.iteration || '?'}, reason=${state.reason || 'normal'}`);

  // Restore conversation variables from state
  if (state.currentModule) {
    {current_module} = state.currentModule;
  }
  if (state.iteration) {
    {current_iteration} = state.iteration;
  }
  if (state.prdVersion) {
    {prd_version} = state.prdVersion;
  }

  // Route to the correct step based on saved state
  // This replaces the default "always go to step-01" behavior
  const stepRouting = {
    'step-01-task':   'steps/step-01-task.md',
    'step-02-execute': 'steps/step-02-execute.md',
    'step-03-commit':  'steps/step-03-commit.md',
    'step-04-check':   'steps/step-04-check.md',
    'compact-loop':    'steps/step-04-check.md',  // compact-loop re-enters via step-04
    'step-05-report':  'steps/step-05-report.md'
  };

  const targetStep = stepRouting[state.currentStep] || 'steps/step-01-task.md';

  // Special case: module transition — go to step-01 to detect module-changed.json
  if (state.reason === 'module-transition') {
    console.log(`Module transition recovery: ${state.fromModule} → ${state.currentModule}`);
    console.log('Routing to step-01-task.md to detect module-changed.json');
    // targetStep stays 'steps/step-01-task.md'
  }

  console.log(`Recovery routing: → ${targetStep}`);
  // The calling code (step-00) should load targetStep instead of the default step-01
}
```

**IMPORTANT:** This recovery is triggered BEFORE the default "Proceed to step-01" routing in step-00-init.md. If ralph-state.json provides a different target step, that step should be loaded instead.

---

## Auto-Recovery: BA Artifacts Without PRD

If no PRD files exist (neither `.ralph/prd-*.json` nor `.ralph/prd.json`):

```javascript
const masterFeature = findFile('docs/business/**/business-analyse/**/feature.json');

if (!masterFeature) {
  // No BA artifacts found — start fresh
  console.log('No existing PRD or BA artifacts — starting new loop');
  return;
}

const master = readJSON(masterFeature);
const handoffStatus = master.status || master.handoff?.status || null;

if (handoffStatus === 'handed-off') {
  // BA handoff completed — auto-derive PRDs
  console.log('BA artifacts detected without PRD — auto-recovering...');

  // Call ss business-analyse-handoff to generate PRD files
  // Flag: --feature (path to feature.json) — matches ss business-analyse-handoff CLI convention
  // See also: step-05c-ralph-readiness.md section 2 "Fix: ss business-analyse-handoff --feature {path} --output ..."
  const result = exec(`ss business-analyse-handoff --feature ${masterFeature}`);

  if (result.exitCode !== 0) {
    console.error('ss business-analyse-handoff failed — cannot auto-recover');
    STOP;
  }

  const newPrds = glob('.ralph/prd-*.json');
  if (newPrds.length === 0) {
    console.error('ss business-analyse-handoff did not create any PRD files');
    STOP;
  }

  console.log(`Auto-recovered ${newPrds.length} PRD file(s): ${newPrds.map(f => f.split('/').pop()).join(', ')}`);
  // Continue to detect multi-module (section 4b)
} else {
  // BA handoff NOT complete
  console.warn(`⚠ BA handoff status: "${handoffStatus}" (expected "handed-off")`);
  console.warn('Cannot auto-recover PRD files without complete handoff');
  console.warn('Run /business-analyse-handoff to generate the handoff, then retry /business-analyse-develop');
  STOP;
}
```

---

## State After Recovery

After resume or auto-recovery:

```javascript
// If PRD now exists (either resumed or recovered):
// - Continue to section 4b (Detect Multi-Module)
// - Initialize modules-queue.json if 2+ PRD files found
// - Set {modules_queue} and {current_module} appropriately
// - Proceed to step-01 to load tasks
```
