ralph-claude-code icon indicating copy to clipboard operation
ralph-claude-code copied to clipboard

[P3] Phase 3.9: Implement backup and rollback system

Open frankbria opened this issue 3 months ago โ€ข 3 comments

Description

Implement automatic backup and rollback functionality for Ralph loops.

Implementation Tasks

  • [ ] Create create_backup() function in ralph_loop.sh
  • [ ] Create backup git branches before each loop
  • [ ] Commit current state with descriptive message
  • [ ] Implement rollback_to_backup() function
  • [ ] Add --backup flag to CLI parser

Backup Strategy

  • Branch naming: ralph-backup-loop-{N}-{timestamp}
  • Commit message: "Ralph backup before loop #{N}"
  • Only create backups when --backup flag is enabled
  • Only backup if in git repository

Testing Tasks

  • [ ] Write 5 tests for backup/rollback
  • [ ] Test backup branch creation
  • [ ] Test backup commits
  • [ ] Test rollback functionality
  • [ ] Test --backup flag
  • [ ] Test graceful handling when not in git repo

Code Locations

  • create_backup(): Before execute_claude_code() (around line 300)
  • rollback_to_backup(): After circuit breaker section (around line 450)
  • CLI flag: ralph_loop.sh CLI parser (around line 720)

Acceptance Criteria

  • [ ] Backups created before each loop (when enabled)
  • [ ] Rollback works correctly
  • [ ] Handles non-git directories gracefully
  • [ ] All tests pass
  • [ ] Documented in README

References

  • Implementation Plan: Week 6, Day 3

frankbria avatar Jan 01 '26 00:01 frankbria

๐Ÿ“ CodeRabbit Plan Mode

Generate an implementation plan and prompts that you can use with your favorite coding agent.

  • [ ] Create Plan
Examples

๐Ÿ”— Related PRs

frankbria/ralph-claude-code#66 - feat(session): add session lifecycle management with auto-reset triggers [closed]


๐Ÿงช Issue enrichment is currently in open beta.

You can configure auto-planning by selecting labels in the issue_enrichment configuration.

To disable automatic issue enrichment, add the following to your .coderabbit.yaml:

issue_enrichment:
  auto_enrich:
    enabled: false

๐Ÿ’ฌ Have feedback or questions? Drop into our discord!

coderabbitai[bot] avatar Jan 01 '26 00:01 coderabbitai[bot]

Plan

Observations

The codebase already has git integration in file:lib/response_analyzer.sh for detecting file changes. The main file:ralph_loop.sh file has a well-structured architecture with clear sections for functions (around lines 300-450) and CLI parsing (around line 630-691). The project uses BATS testing framework with helper utilities in file:tests/helpers/test_helper.bash and follows a pattern of checking command availability before use. The implementation plan (Week 6, Day 3) provides clear specifications for backup branch naming and commit message format.

Approach

The implementation will add two new functions to file:ralph_loop.sh: create_backup() before the execute_claude_code() call and rollback_to_backup() after the circuit breaker section. A --backup flag will be added to the CLI parser to enable the feature opt-in. The backup system will only operate when in a git repository and when the flag is enabled, following the existing pattern of graceful degradation. Tests will be written using BATS framework following the established patterns in file:tests/unit/test_rate_limiting.bats and file:tests/unit/test_exit_detection.bats.

Implementation Steps

1. Add Backup Configuration Variables

Location: file:ralph_loop.sh (Configuration section, around line 14-28)

Add the following configuration variables after the existing configuration:

ENABLE_BACKUP=false  # Default: backups disabled

2. Implement create_backup() Function

Location: file:ralph_loop.sh (Before execute_claude_code(), around line 300)

Create a new function that:

  • Checks if git repository exists using git rev-parse --git-dir
  • Checks if ENABLE_BACKUP flag is enabled
  • Creates backup branch with naming pattern: ralph-backup-loop-{N}-{timestamp}
  • Stages all changes with git add -A
  • Commits with message: "Ralph backup before loop #{N}"
  • Uses --allow-empty flag to handle cases with no changes
  • Logs backup creation status using log_status()
  • Handles errors gracefully without breaking the loop

Key Implementation Details:

  • Use $(date +%s) for Unix timestamp in branch name
  • Use 2>/dev/null || true pattern to suppress git errors
  • Return silently if not in git repo or backup disabled
  • Store backup branch name in a variable for potential rollback reference

3. Implement rollback_to_backup() Function

Location: file:ralph_loop.sh (After circuit breaker section, around line 450)

Create a new function that:

  • Checks if git repository exists
  • Lists recent backup branches matching pattern ralph-backup-loop-*
  • Provides interactive selection of backup point (or accepts branch name as parameter)
  • Performs git checkout to the selected backup branch
  • Logs rollback action with timestamp and branch name
  • Handles errors with clear error messages
  • Confirms successful rollback to user

Key Implementation Details:

  • Use git branch --list "ralph-backup-loop-*" to find backups
  • Sort branches by timestamp (newest first)
  • Provide option to abort rollback
  • Warn about uncommitted changes before checkout
  • Consider adding --force option for emergency rollback

4. Integrate Backup Call in Main Loop

Location: file:ralph_loop.sh (Main loop, around line 495-530)

Modify the main loop to call create_backup():

  • Call create_backup() before execute_claude_code() (around line 528)
  • Pass current loop count as parameter: create_backup "$loop_count"
  • Ensure backup happens after rate limit check but before execution
  • No error handling needed (function handles errors internally)

5. Add --backup Flag to CLI Parser

Location: file:ralph_loop.sh (CLI parser section, around line 630-691)

Add new flag handling:

  • Add case for -b|--backup flag
  • Set ENABLE_BACKUP=true when flag is present
  • Update show_help() function to document the new flag
  • Add example usage in help text

Help Text Addition:

-b, --backup            Enable automatic backups before each loop (requires git)

6. Add Rollback Command Option

Location: file:ralph_loop.sh (CLI parser section, around line 630-691)

Add new command option:

  • Add case for --rollback [branch] flag
  • Call rollback_to_backup() function
  • Exit after rollback completes
  • Document in help text

7. Update README.md Documentation

Location: file:README.md

Add documentation sections:

  • Add backup feature to Features list (around line 51-66)
  • Add backup usage examples in Configuration section (around line 200-268)
  • Add rollback instructions in Monitoring and Debugging section (around line 376-419)
  • Update command reference with --backup flag (around line 538-559)
  • Add troubleshooting entry for backup/rollback issues

Example Documentation:

### Backup and Rollback

Ralph can automatically create git backups before each loop iteration:

```bash
# Enable automatic backups
ralph --backup --monitor

# Rollback to a previous backup
ralph --rollback

# Rollback to specific backup branch
ralph --rollback ralph-backup-loop-5-1704123456

Backups are only created when:

  • The --backup flag is enabled
  • The project is in a git repository
  • Each backup creates a branch: ralph-backup-loop-{N}-{timestamp}

### 8. Create Test File for Backup/Rollback

**Location:** Create new file `file:tests/unit/test_backup_rollback.bats`

Write 5 comprehensive tests following BATS patterns:

**Test 1:** Backup branch creation
- Setup: Initialize git repo, set ENABLE_BACKUP=true
- Execute: Call `create_backup(1)`
- Assert: Branch `ralph-backup-loop-1-*` exists

**Test 2:** Backup commit creation
- Setup: Initialize git repo, create test files
- Execute: Call `create_backup(1)`
- Assert: Commit message matches "Ralph backup before loop #1"

**Test 3:** Rollback functionality
- Setup: Create multiple backup branches
- Execute: Call `rollback_to_backup()` with specific branch
- Assert: Current branch matches rollback target

**Test 4:** Graceful handling when not in git repo
- Setup: Non-git directory
- Execute: Call `create_backup(1)`
- Assert: Function returns without error, no branches created

**Test 5:** Backup disabled by default
- Setup: Git repo, ENABLE_BACKUP=false
- Execute: Call `create_backup(1)`
- Assert: No backup branch created

**Additional Test Considerations:**
- Test backup with no file changes (--allow-empty)
- Test backup branch naming with different loop counts
- Test rollback with uncommitted changes
- Test rollback branch selection
- Test CLI flag parsing for `--backup`

### 9. Update IMPLEMENTATION_PLAN.md

**Location:** `file:IMPLEMENTATION_PLAN.md` (Week 6, Day 3 section, around line 432-454)

Mark tasks as complete:
- Check off "Create `create_backup()` function"
- Check off "Create backup git branches before each loop"
- Check off "Commit current state with descriptive message"
- Check off "Implement `rollback_to_backup()` function"
- Check off "Add `--backup` flag to CLI parser"
- Check off all testing tasks when tests are written
- Update test count in success metrics table

### 10. Update IMPLEMENTATION_STATUS.md

**Location:** `file:IMPLEMENTATION_STATUS.md` (Week 6 section, around line 178-196)

Update status:
- Move "Backup & Rollback" from "Not Completed" to "Completed"
- Update test count totals
- Update coverage percentage estimate
- Add completion date

## Sequence Diagram

```mermaid
sequenceDiagram
    participant User
    participant CLI as CLI Parser
    participant Main as Main Loop
    participant Backup as create_backup()
    participant Git as Git Repository
    participant Execute as execute_claude_code()
    
    User->>CLI: ralph --backup --monitor
    CLI->>CLI: Set ENABLE_BACKUP=true
    CLI->>Main: Start main loop
    
    loop Each Loop Iteration
        Main->>Main: Check rate limits
        Main->>Backup: create_backup(loop_count)
        Backup->>Git: Check if git repo exists
        Git-->>Backup: Repository found
        Backup->>Git: Create branch ralph-backup-loop-N-timestamp
        Backup->>Git: git add -A
        Backup->>Git: git commit -m "Ralph backup before loop #N"
        Backup-->>Main: Backup created
        Main->>Execute: execute_claude_code(loop_count)
        Execute-->>Main: Execution complete
    end
    
    User->>CLI: ralph --rollback
    CLI->>Backup: rollback_to_backup()
    Backup->>Git: List backup branches
    Git-->>Backup: ralph-backup-loop-* branches
    Backup->>User: Display backup options
    User->>Backup: Select backup branch
    Backup->>Git: git checkout selected-branch
    Git-->>Backup: Rollback complete
    Backup-->>User: Success message

Testing Strategy

Test Category Test Count Coverage Focus
Unit Tests 5 Backup creation, rollback logic, git detection
Integration Tests 3 Full loop with backup, CLI flag parsing, error handling
Edge Cases 2 Non-git directories, empty commits, concurrent backups

Test Execution:

bats tests/unit/test_backup_rollback.bats

Acceptance Criteria Verification

  • โœ… Backups created before each loop when --backup flag enabled
  • โœ… Backup branch naming follows pattern: ralph-backup-loop-{N}-{timestamp}
  • โœ… Commit messages follow format: "Ralph backup before loop #{N}"
  • โœ… Rollback function allows restoration to previous state
  • โœ… Graceful handling when not in git repository (no errors, silent skip)
  • โœ… All 5+ tests pass with 100% success rate
  • โœ… Documentation updated in README.md
  • โœ… CLI flag --backup properly parsed and functional
  • โœ… Implementation plan and status documents updated

Risk Considerations

Low Risk:

  • Git operations are isolated and don't affect main loop execution
  • Backup is opt-in via flag, no impact on existing workflows
  • Graceful degradation when git is unavailable

Mitigation:

  • All git commands use error suppression (2>/dev/null || true)
  • Backup failures log warnings but don't halt execution
  • Clear documentation about git repository requirement

Import In IDE

VSCode Icon Cursor Icon Windsurf Icon

๐Ÿค– Prompt for AI Agents
## Observations

The codebase already has git integration in `file:lib/response_analyzer.sh` for detecting file changes. The main `file:ralph_loop.sh` file has a well-structured architecture with clear sections for functions (around lines 300-450) and CLI parsing (around line 630-691). The project uses BATS testing framework with helper utilities in `file:tests/helpers/test_helper.bash` and follows a pattern of checking command availability before use. The implementation plan (Week 6, Day 3) provides clear specifications for backup branch naming and commit message format.

## Approach

The implementation will add two new functions to `file:ralph_loop.sh`: `create_backup()` before the `execute_claude_code()` call and `rollback_to_backup()` after the circuit breaker section. A `--backup` flag will be added to the CLI parser to enable the feature opt-in. The backup system will only operate when in a git repository and when the flag is enabled, following the existing pattern of graceful degradation. Tests will be written using BATS framework following the established patterns in `file:tests/unit/test_rate_limiting.bats` and `file:tests/unit/test_exit_detection.bats`.

## Implementation Steps

### 1. Add Backup Configuration Variables

**Location:** `file:ralph_loop.sh` (Configuration section, around line 14-28)

Add the following configuration variables after the existing configuration:

```bash
ENABLE_BACKUP=false  # Default: backups disabled
```

### 2. Implement `create_backup()` Function

**Location:** `file:ralph_loop.sh` (Before `execute_claude_code()`, around line 300)

Create a new function that:
- Checks if git repository exists using `git rev-parse --git-dir`
- Checks if `ENABLE_BACKUP` flag is enabled
- Creates backup branch with naming pattern: `ralph-backup-loop-{N}-{timestamp}`
- Stages all changes with `git add -A`
- Commits with message: "Ralph backup before loop #{N}"
- Uses `--allow-empty` flag to handle cases with no changes
- Logs backup creation status using `log_status()`
- Handles errors gracefully without breaking the loop

**Key Implementation Details:**
- Use `$(date +%s)` for Unix timestamp in branch name
- Use `2>/dev/null || true` pattern to suppress git errors
- Return silently if not in git repo or backup disabled
- Store backup branch name in a variable for potential rollback reference

### 3. Implement `rollback_to_backup()` Function

**Location:** `file:ralph_loop.sh` (After circuit breaker section, around line 450)

Create a new function that:
- Checks if git repository exists
- Lists recent backup branches matching pattern `ralph-backup-loop-*`
- Provides interactive selection of backup point (or accepts branch name as parameter)
- Performs `git checkout` to the selected backup branch
- Logs rollback action with timestamp and branch name
- Handles errors with clear error messages
- Confirms successful rollback to user

**Key Implementation Details:**
- Use `git branch --list "ralph-backup-loop-*"` to find backups
- Sort branches by timestamp (newest first)
- Provide option to abort rollback
- Warn about uncommitted changes before checkout
- Consider adding `--force` option for emergency rollback

### 4. Integrate Backup Call in Main Loop

**Location:** `file:ralph_loop.sh` (Main loop, around line 495-530)

Modify the main loop to call `create_backup()`:
- Call `create_backup()` before `execute_claude_code()` (around line 528)
- Pass current loop count as parameter: `create_backup "$loop_count"`
- Ensure backup happens after rate limit check but before execution
- No error handling needed (function handles errors internally)

### 5. Add `--backup` Flag to CLI Parser

**Location:** `file:ralph_loop.sh` (CLI parser section, around line 630-691)

Add new flag handling:
- Add case for `-b|--backup` flag
- Set `ENABLE_BACKUP=true` when flag is present
- Update `show_help()` function to document the new flag
- Add example usage in help text

**Help Text Addition:**
```
-b, --backup            Enable automatic backups before each loop (requires git)
```

### 6. Add Rollback Command Option

**Location:** `file:ralph_loop.sh` (CLI parser section, around line 630-691)

Add new command option:
- Add case for `--rollback [branch]` flag
- Call `rollback_to_backup()` function
- Exit after rollback completes
- Document in help text

### 7. Update README.md Documentation

**Location:** `file:README.md`

Add documentation sections:
- Add backup feature to Features list (around line 51-66)
- Add backup usage examples in Configuration section (around line 200-268)
- Add rollback instructions in Monitoring and Debugging section (around line 376-419)
- Update command reference with `--backup` flag (around line 538-559)
- Add troubleshooting entry for backup/rollback issues

**Example Documentation:**
```markdown
### Backup and Rollback

Ralph can automatically create git backups before each loop iteration:

```bash
# Enable automatic backups
ralph --backup --monitor

# Rollback to a previous backup
ralph --rollback

# Rollback to specific backup branch
ralph --rollback ralph-backup-loop-5-1704123456
```

Backups are only created when:
- The `--backup` flag is enabled
- The project is in a git repository
- Each backup creates a branch: `ralph-backup-loop-{N}-{timestamp}`
```

### 8. Create Test File for Backup/Rollback

**Location:** Create new file `file:tests/unit/test_backup_rollback.bats`

Write 5 comprehensive tests following BATS patterns:

**Test 1:** Backup branch creation
- Setup: Initialize git repo, set ENABLE_BACKUP=true
- Execute: Call `create_backup(1)`
- Assert: Branch `ralph-backup-loop-1-*` exists

**Test 2:** Backup commit creation
- Setup: Initialize git repo, create test files
- Execute: Call `create_backup(1)`
- Assert: Commit message matches "Ralph backup before loop #1"

**Test 3:** Rollback functionality
- Setup: Create multiple backup branches
- Execute: Call `rollback_to_backup()` with specific branch
- Assert: Current branch matches rollback target

**Test 4:** Graceful handling when not in git repo
- Setup: Non-git directory
- Execute: Call `create_backup(1)`
- Assert: Function returns without error, no branches created

**Test 5:** Backup disabled by default
- Setup: Git repo, ENABLE_BACKUP=false
- Execute: Call `create_backup(1)`
- Assert: No backup branch created

**Additional Test Considerations:**
- Test backup with no file changes (--allow-empty)
- Test backup branch naming with different loop counts
- Test rollback with uncommitted changes
- Test rollback branch selection
- Test CLI flag parsing for `--backup`

### 9. Update IMPLEMENTATION_PLAN.md

**Location:** `file:IMPLEMENTATION_PLAN.md` (Week 6, Day 3 section, around line 432-454)

Mark tasks as complete:
- Check off "Create `create_backup()` function"
- Check off "Create backup git branches before each loop"
- Check off "Commit current state with descriptive message"
- Check off "Implement `rollback_to_backup()` function"
- Check off "Add `--backup` flag to CLI parser"
- Check off all testing tasks when tests are written
- Update test count in success metrics table

### 10. Update IMPLEMENTATION_STATUS.md

**Location:** `file:IMPLEMENTATION_STATUS.md` (Week 6 section, around line 178-196)

Update status:
- Move "Backup & Rollback" from "Not Completed" to "Completed"
- Update test count totals
- Update coverage percentage estimate
- Add completion date

## Sequence Diagram

```mermaid
sequenceDiagram
    participant User
    participant CLI as CLI Parser
    participant Main as Main Loop
    participant Backup as create_backup()
    participant Git as Git Repository
    participant Execute as execute_claude_code()
    
    User->>CLI: ralph --backup --monitor
    CLI->>CLI: Set ENABLE_BACKUP=true
    CLI->>Main: Start main loop
    
    loop Each Loop Iteration
        Main->>Main: Check rate limits
        Main->>Backup: create_backup(loop_count)
        Backup->>Git: Check if git repo exists
        Git-->>Backup: Repository found
        Backup->>Git: Create branch ralph-backup-loop-N-timestamp
        Backup->>Git: git add -A
        Backup->>Git: git commit -m "Ralph backup before loop #N"
        Backup-->>Main: Backup created
        Main->>Execute: execute_claude_code(loop_count)
        Execute-->>Main: Execution complete
    end
    
    User->>CLI: ralph --rollback
    CLI->>Backup: rollback_to_backup()
    Backup->>Git: List backup branches
    Git-->>Backup: ralph-backup-loop-* branches
    Backup->>User: Display backup options
    User->>Backup: Select backup branch
    Backup->>Git: git checkout selected-branch
    Git-->>Backup: Rollback complete
    Backup-->>User: Success message
```

## Testing Strategy

| Test Category | Test Count | Coverage Focus |
|--------------|-----------|----------------|
| Unit Tests | 5 | Backup creation, rollback logic, git detection |
| Integration Tests | 3 | Full loop with backup, CLI flag parsing, error handling |
| Edge Cases | 2 | Non-git directories, empty commits, concurrent backups |

**Test Execution:**
```bash
bats tests/unit/test_backup_rollback.bats
```

## Acceptance Criteria Verification

- โœ… Backups created before each loop when `--backup` flag enabled
- โœ… Backup branch naming follows pattern: `ralph-backup-loop-{N}-{timestamp}`
- โœ… Commit messages follow format: "Ralph backup before loop #{N}"
- โœ… Rollback function allows restoration to previous state
- โœ… Graceful handling when not in git repository (no errors, silent skip)
- โœ… All 5+ tests pass with 100% success rate
- โœ… Documentation updated in README.md
- โœ… CLI flag `--backup` properly parsed and functional
- โœ… Implementation plan and status documents updated

## Risk Considerations

**Low Risk:**
- Git operations are isolated and don't affect main loop execution
- Backup is opt-in via flag, no impact on existing workflows
- Graceful degradation when git is unavailable

**Mitigation:**
- All git commands use error suppression (`2>/dev/null || true`)
- Backup failures log warnings but don't halt execution
- Clear documentation about git repository requirement

Execution Information

Branch: main Commit: 870181bd0269dc21f6c9f5a403dba9e8022b3f1c


:bulb: Tips

Supported Commands (Inside Comments)

  • Use @traycerai generate to iterate on the previous version of the implementation plan.

Supported Commands (Inside Description)

  • Add @traycerai ignore anywhere in the ticket description to prevent this ticket from being processed.
  • Add @traycerai branch:<branch-name> anywhere in the ticket description to specify the target branch for the implementation plan.

Community

  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

traycerai[bot] avatar Jan 01 '26 00:01 traycerai[bot]

I have updated the Implementation Plan to reflect the recent changes in the ticket.

New Plan

Observations

The codebase already has git integration in file:lib/response_analyzer.sh for detecting file changes. The main file:ralph_loop.sh file has a well-structured architecture with clear sections for functions (around lines 300-450) and CLI parsing (around line 630-691). The project uses BATS testing framework with helper utilities in file:tests/helpers/test_helper.bash and follows a pattern of checking command availability before use. The implementation plan (Week 6, Day 3) provides clear specifications for backup branch naming and commit message format.

Approach

The implementation will add two new functions to file:ralph_loop.sh: create_backup() before the execute_claude_code() call and rollback_to_backup() after the circuit breaker section. A --backup flag will be added to the CLI parser to enable the feature opt-in. The backup system will only operate when in a git repository and when the flag is enabled, following the existing pattern of graceful degradation. Tests will be written using BATS framework following the established patterns in file:tests/unit/test_rate_limiting.bats and file:tests/unit/test_exit_detection.bats.

Implementation Steps

1. Add Backup Configuration Variables

Location: file:ralph_loop.sh (Configuration section, around line 14-28)

Add the following configuration variables after the existing configuration:

ENABLE_BACKUP=false  # Default: backups disabled

2. Implement create_backup() Function

Location: file:ralph_loop.sh (Before execute_claude_code(), around line 300)

Create a new function that:

  • Checks if git repository exists using git rev-parse --git-dir
  • Checks if ENABLE_BACKUP flag is enabled
  • Creates backup branch with naming pattern: ralph-backup-loop-{N}-{timestamp}
  • Stages all changes with git add -A
  • Commits with message: "Ralph backup before loop #{N}"
  • Uses --allow-empty flag to handle cases with no changes
  • Logs backup creation status using log_status()
  • Handles errors gracefully without breaking the loop

Key Implementation Details:

  • Use $(date +%s) for Unix timestamp in branch name
  • Use 2>/dev/null || true pattern to suppress git errors
  • Return silently if not in git repo or backup disabled
  • Store backup branch name in a variable for potential rollback reference

3. Implement rollback_to_backup() Function

Location: file:ralph_loop.sh (After circuit breaker section, around line 450)

Create a new function that:

  • Checks if git repository exists
  • Lists recent backup branches matching pattern ralph-backup-loop-*
  • Provides interactive selection of backup point (or accepts branch name as parameter)
  • Performs git checkout to the selected backup branch
  • Logs rollback action with timestamp and branch name
  • Handles errors with clear error messages
  • Confirms successful rollback to user

Key Implementation Details:

  • Use git branch --list "ralph-backup-loop-*" to find backups
  • Sort branches by timestamp (newest first)
  • Provide option to abort rollback
  • Warn about uncommitted changes before checkout
  • Consider adding --force option for emergency rollback

4. Integrate Backup Call in Main Loop

Location: file:ralph_loop.sh (Main loop, around line 495-530)

Modify the main loop to call create_backup():

  • Call create_backup() before execute_claude_code() (around line 528)
  • Pass current loop count as parameter: create_backup "$loop_count"
  • Ensure backup happens after rate limit check but before execution
  • No error handling needed (function handles errors internally)

5. Add --backup Flag to CLI Parser

Location: file:ralph_loop.sh (CLI parser section, around line 630-691)

Add new flag handling:

  • Add case for -b|--backup flag
  • Set ENABLE_BACKUP=true when flag is present
  • Update show_help() function to document the new flag
  • Add example usage in help text

Help Text Addition:

-b, --backup            Enable automatic backups before each loop (requires git)

6. Add Rollback Command Option

Location: file:ralph_loop.sh (CLI parser section, around line 630-691)

Add new command option:

  • Add case for --rollback [branch] flag
  • Call rollback_to_backup() function
  • Exit after rollback completes
  • Document in help text

7. Update README.md Documentation

Location: file:README.md

Add documentation sections:

  • Add backup feature to Features list (around line 51-66)
  • Add backup usage examples in Configuration section (around line 200-268)
  • Add rollback instructions in Monitoring and Debugging section (around line 376-419)
  • Update command reference with --backup flag (around line 538-559)
  • Add troubleshooting entry for backup/rollback issues

Example Documentation:

### Backup and Rollback

Ralph can automatically create git backups before each loop iteration:

```bash
# Enable automatic backups
ralph --backup --monitor

# Rollback to a previous backup
ralph --rollback

# Rollback to specific backup branch
ralph --rollback ralph-backup-loop-5-1704123456

Backups are only created when:

  • The --backup flag is enabled
  • The project is in a git repository
  • Each backup creates a branch: ralph-backup-loop-{N}-{timestamp}

### 8. Create Test File for Backup/Rollback

**Location:** Create new file `file:tests/unit/test_backup_rollback.bats`

Write 5 comprehensive tests following BATS patterns:

**Test 1:** Backup branch creation
- Setup: Initialize git repo, set ENABLE_BACKUP=true
- Execute: Call `create_backup(1)`
- Assert: Branch `ralph-backup-loop-1-*` exists

**Test 2:** Backup commit creation
- Setup: Initialize git repo, create test files
- Execute: Call `create_backup(1)`
- Assert: Commit message matches "Ralph backup before loop #1"

**Test 3:** Rollback functionality
- Setup: Create multiple backup branches
- Execute: Call `rollback_to_backup()` with specific branch
- Assert: Current branch matches rollback target

**Test 4:** Graceful handling when not in git repo
- Setup: Non-git directory
- Execute: Call `create_backup(1)`
- Assert: Function returns without error, no branches created

**Test 5:** Backup disabled by default
- Setup: Git repo, ENABLE_BACKUP=false
- Execute: Call `create_backup(1)`
- Assert: No backup branch created

**Additional Test Considerations:**
- Test backup with no file changes (--allow-empty)
- Test backup branch naming with different loop counts
- Test rollback with uncommitted changes
- Test rollback branch selection
- Test CLI flag parsing for `--backup`

### 9. Update IMPLEMENTATION_PLAN.md

**Location:** `file:IMPLEMENTATION_PLAN.md` (Week 6, Day 3 section, around line 432-454)

Mark tasks as complete:
- Check off "Create `create_backup()` function"
- Check off "Create backup git branches before each loop"
- Check off "Commit current state with descriptive message"
- Check off "Implement `rollback_to_backup()` function"
- Check off "Add `--backup` flag to CLI parser"
- Check off all testing tasks when tests are written
- Update test count in success metrics table

### 10. Update IMPLEMENTATION_STATUS.md

**Location:** `file:IMPLEMENTATION_STATUS.md` (Week 6 section, around line 178-196)

Update status:
- Move "Backup & Rollback" from "Not Completed" to "Completed"
- Update test count totals
- Update coverage percentage estimate
- Add completion date

## Sequence Diagram

```mermaid
sequenceDiagram
    participant User
    participant CLI as CLI Parser
    participant Main as Main Loop
    participant Backup as create_backup()
    participant Git as Git Repository
    participant Execute as execute_claude_code()
    
    User->>CLI: ralph --backup --monitor
    CLI->>CLI: Set ENABLE_BACKUP=true
    CLI->>Main: Start main loop
    
    loop Each Loop Iteration
        Main->>Main: Check rate limits
        Main->>Backup: create_backup(loop_count)
        Backup->>Git: Check if git repo exists
        Git-->>Backup: Repository found
        Backup->>Git: Create branch ralph-backup-loop-N-timestamp
        Backup->>Git: git add -A
        Backup->>Git: git commit -m "Ralph backup before loop #N"
        Backup-->>Main: Backup created
        Main->>Execute: execute_claude_code(loop_count)
        Execute-->>Main: Execution complete
    end
    
    User->>CLI: ralph --rollback
    CLI->>Backup: rollback_to_backup()
    Backup->>Git: List backup branches
    Git-->>Backup: ralph-backup-loop-* branches
    Backup->>User: Display backup options
    User->>Backup: Select backup branch
    Backup->>Git: git checkout selected-branch
    Git-->>Backup: Rollback complete
    Backup-->>User: Success message

Testing Strategy

Test Category Test Count Coverage Focus
Unit Tests 5 Backup creation, rollback logic, git detection
Integration Tests 3 Full loop with backup, CLI flag parsing, error handling
Edge Cases 2 Non-git directories, empty commits, concurrent backups

Test Execution:

bats tests/unit/test_backup_rollback.bats

Acceptance Criteria Verification

  • โœ… Backups created before each loop when --backup flag enabled
  • โœ… Backup branch naming follows pattern: ralph-backup-loop-{N}-{timestamp}
  • โœ… Commit messages follow format: "Ralph backup before loop #{N}"
  • โœ… Rollback function allows restoration to previous state
  • โœ… Graceful handling when not in git repository (no errors, silent skip)
  • โœ… All 5+ tests pass with 100% success rate
  • โœ… Documentation updated in README.md
  • โœ… CLI flag --backup properly parsed and functional
  • โœ… Implementation plan and status documents updated

Risk Considerations

Low Risk:

  • Git operations are isolated and don't affect main loop execution
  • Backup is opt-in via flag, no impact on existing workflows
  • Graceful degradation when git is unavailable

Mitigation:

  • All git commands use error suppression (2>/dev/null || true)
  • Backup failures log warnings but don't halt execution
  • Clear documentation about git repository requirement

Import In IDE

VSCode Icon Cursor Icon Windsurf Icon

๐Ÿค– Prompt for AI Agents
## Observations

The codebase already has git integration in `file:lib/response_analyzer.sh` for detecting file changes. The main `file:ralph_loop.sh` file has a well-structured architecture with clear sections for functions (around lines 300-450) and CLI parsing (around line 630-691). The project uses BATS testing framework with helper utilities in `file:tests/helpers/test_helper.bash` and follows a pattern of checking command availability before use. The implementation plan (Week 6, Day 3) provides clear specifications for backup branch naming and commit message format.

## Approach

The implementation will add two new functions to `file:ralph_loop.sh`: `create_backup()` before the `execute_claude_code()` call and `rollback_to_backup()` after the circuit breaker section. A `--backup` flag will be added to the CLI parser to enable the feature opt-in. The backup system will only operate when in a git repository and when the flag is enabled, following the existing pattern of graceful degradation. Tests will be written using BATS framework following the established patterns in `file:tests/unit/test_rate_limiting.bats` and `file:tests/unit/test_exit_detection.bats`.

## Implementation Steps

### 1. Add Backup Configuration Variables

**Location:** `file:ralph_loop.sh` (Configuration section, around line 14-28)

Add the following configuration variables after the existing configuration:

```bash
ENABLE_BACKUP=false  # Default: backups disabled
```

### 2. Implement `create_backup()` Function

**Location:** `file:ralph_loop.sh` (Before `execute_claude_code()`, around line 300)

Create a new function that:
- Checks if git repository exists using `git rev-parse --git-dir`
- Checks if `ENABLE_BACKUP` flag is enabled
- Creates backup branch with naming pattern: `ralph-backup-loop-{N}-{timestamp}`
- Stages all changes with `git add -A`
- Commits with message: "Ralph backup before loop #{N}"
- Uses `--allow-empty` flag to handle cases with no changes
- Logs backup creation status using `log_status()`
- Handles errors gracefully without breaking the loop

**Key Implementation Details:**
- Use `$(date +%s)` for Unix timestamp in branch name
- Use `2>/dev/null || true` pattern to suppress git errors
- Return silently if not in git repo or backup disabled
- Store backup branch name in a variable for potential rollback reference

### 3. Implement `rollback_to_backup()` Function

**Location:** `file:ralph_loop.sh` (After circuit breaker section, around line 450)

Create a new function that:
- Checks if git repository exists
- Lists recent backup branches matching pattern `ralph-backup-loop-*`
- Provides interactive selection of backup point (or accepts branch name as parameter)
- Performs `git checkout` to the selected backup branch
- Logs rollback action with timestamp and branch name
- Handles errors with clear error messages
- Confirms successful rollback to user

**Key Implementation Details:**
- Use `git branch --list "ralph-backup-loop-*"` to find backups
- Sort branches by timestamp (newest first)
- Provide option to abort rollback
- Warn about uncommitted changes before checkout
- Consider adding `--force` option for emergency rollback

### 4. Integrate Backup Call in Main Loop

**Location:** `file:ralph_loop.sh` (Main loop, around line 495-530)

Modify the main loop to call `create_backup()`:
- Call `create_backup()` before `execute_claude_code()` (around line 528)
- Pass current loop count as parameter: `create_backup "$loop_count"`
- Ensure backup happens after rate limit check but before execution
- No error handling needed (function handles errors internally)

### 5. Add `--backup` Flag to CLI Parser

**Location:** `file:ralph_loop.sh` (CLI parser section, around line 630-691)

Add new flag handling:
- Add case for `-b|--backup` flag
- Set `ENABLE_BACKUP=true` when flag is present
- Update `show_help()` function to document the new flag
- Add example usage in help text

**Help Text Addition:**
```
-b, --backup            Enable automatic backups before each loop (requires git)
```

### 6. Add Rollback Command Option

**Location:** `file:ralph_loop.sh` (CLI parser section, around line 630-691)

Add new command option:
- Add case for `--rollback [branch]` flag
- Call `rollback_to_backup()` function
- Exit after rollback completes
- Document in help text

### 7. Update README.md Documentation

**Location:** `file:README.md`

Add documentation sections:
- Add backup feature to Features list (around line 51-66)
- Add backup usage examples in Configuration section (around line 200-268)
- Add rollback instructions in Monitoring and Debugging section (around line 376-419)
- Update command reference with `--backup` flag (around line 538-559)
- Add troubleshooting entry for backup/rollback issues

**Example Documentation:**
```markdown
### Backup and Rollback

Ralph can automatically create git backups before each loop iteration:

```bash
# Enable automatic backups
ralph --backup --monitor

# Rollback to a previous backup
ralph --rollback

# Rollback to specific backup branch
ralph --rollback ralph-backup-loop-5-1704123456
```

Backups are only created when:
- The `--backup` flag is enabled
- The project is in a git repository
- Each backup creates a branch: `ralph-backup-loop-{N}-{timestamp}`
```

### 8. Create Test File for Backup/Rollback

**Location:** Create new file `file:tests/unit/test_backup_rollback.bats`

Write 5 comprehensive tests following BATS patterns:

**Test 1:** Backup branch creation
- Setup: Initialize git repo, set ENABLE_BACKUP=true
- Execute: Call `create_backup(1)`
- Assert: Branch `ralph-backup-loop-1-*` exists

**Test 2:** Backup commit creation
- Setup: Initialize git repo, create test files
- Execute: Call `create_backup(1)`
- Assert: Commit message matches "Ralph backup before loop #1"

**Test 3:** Rollback functionality
- Setup: Create multiple backup branches
- Execute: Call `rollback_to_backup()` with specific branch
- Assert: Current branch matches rollback target

**Test 4:** Graceful handling when not in git repo
- Setup: Non-git directory
- Execute: Call `create_backup(1)`
- Assert: Function returns without error, no branches created

**Test 5:** Backup disabled by default
- Setup: Git repo, ENABLE_BACKUP=false
- Execute: Call `create_backup(1)`
- Assert: No backup branch created

**Additional Test Considerations:**
- Test backup with no file changes (--allow-empty)
- Test backup branch naming with different loop counts
- Test rollback with uncommitted changes
- Test rollback branch selection
- Test CLI flag parsing for `--backup`

### 9. Update IMPLEMENTATION_PLAN.md

**Location:** `file:IMPLEMENTATION_PLAN.md` (Week 6, Day 3 section, around line 432-454)

Mark tasks as complete:
- Check off "Create `create_backup()` function"
- Check off "Create backup git branches before each loop"
- Check off "Commit current state with descriptive message"
- Check off "Implement `rollback_to_backup()` function"
- Check off "Add `--backup` flag to CLI parser"
- Check off all testing tasks when tests are written
- Update test count in success metrics table

### 10. Update IMPLEMENTATION_STATUS.md

**Location:** `file:IMPLEMENTATION_STATUS.md` (Week 6 section, around line 178-196)

Update status:
- Move "Backup & Rollback" from "Not Completed" to "Completed"
- Update test count totals
- Update coverage percentage estimate
- Add completion date

## Sequence Diagram

```mermaid
sequenceDiagram
    participant User
    participant CLI as CLI Parser
    participant Main as Main Loop
    participant Backup as create_backup()
    participant Git as Git Repository
    participant Execute as execute_claude_code()
    
    User->>CLI: ralph --backup --monitor
    CLI->>CLI: Set ENABLE_BACKUP=true
    CLI->>Main: Start main loop
    
    loop Each Loop Iteration
        Main->>Main: Check rate limits
        Main->>Backup: create_backup(loop_count)
        Backup->>Git: Check if git repo exists
        Git-->>Backup: Repository found
        Backup->>Git: Create branch ralph-backup-loop-N-timestamp
        Backup->>Git: git add -A
        Backup->>Git: git commit -m "Ralph backup before loop #N"
        Backup-->>Main: Backup created
        Main->>Execute: execute_claude_code(loop_count)
        Execute-->>Main: Execution complete
    end
    
    User->>CLI: ralph --rollback
    CLI->>Backup: rollback_to_backup()
    Backup->>Git: List backup branches
    Git-->>Backup: ralph-backup-loop-* branches
    Backup->>User: Display backup options
    User->>Backup: Select backup branch
    Backup->>Git: git checkout selected-branch
    Git-->>Backup: Rollback complete
    Backup-->>User: Success message
```

## Testing Strategy

| Test Category | Test Count | Coverage Focus |
|--------------|-----------|----------------|
| Unit Tests | 5 | Backup creation, rollback logic, git detection |
| Integration Tests | 3 | Full loop with backup, CLI flag parsing, error handling |
| Edge Cases | 2 | Non-git directories, empty commits, concurrent backups |

**Test Execution:**
```bash
bats tests/unit/test_backup_rollback.bats
```

## Acceptance Criteria Verification

- โœ… Backups created before each loop when `--backup` flag enabled
- โœ… Backup branch naming follows pattern: `ralph-backup-loop-{N}-{timestamp}`
- โœ… Commit messages follow format: "Ralph backup before loop #{N}"
- โœ… Rollback function allows restoration to previous state
- โœ… Graceful handling when not in git repository (no errors, silent skip)
- โœ… All 5+ tests pass with 100% success rate
- โœ… Documentation updated in README.md
- โœ… CLI flag `--backup` properly parsed and functional
- โœ… Implementation plan and status documents updated

## Risk Considerations

**Low Risk:**
- Git operations are isolated and don't affect main loop execution
- Backup is opt-in via flag, no impact on existing workflows
- Graceful degradation when git is unavailable

**Mitigation:**
- All git commands use error suppression (`2>/dev/null || true`)
- Backup failures log warnings but don't halt execution
- Clear documentation about git repository requirement

Execution Information

Branch: main Commit: 870181bd0269dc21f6c9f5a403dba9e8022b3f1c

traycerai[bot] avatar Jan 09 '26 03:01 traycerai[bot]