Skip to content

feat(ralph): Scope isolation to prevent drift during overnight execution #89

@aleparreira

Description

@aleparreira

Summary

When running Ralph overnight or unattended, external changes to the backlog during execution can cause unexpected behavior:

  1. New tasks picked up mid-run - without plan review gate
  2. Removed tasks - cause selector confusion
  3. Modified specs - invalidate assumptions from re-anchoring

This proposal adds opt-in scope isolation to freeze the task list at the start of execution.

Current Behavior

Ralph starts → selects task → implements → selects next task → ...
                                              ↑
                              External user adds/removes/modifies tasks
                              Ralph picks up changes mid-run

Problems This Causes

Scenario Impact
Task added mid-run Executes without plan review, may conflict with in-progress work
Task removed mid-run Selector may get confused, incomplete work
Spec modified mid-run Re-anchoring reads stale assumptions, implementation diverges

Proposed Solution

New opt-in config options:

FREEZE_SCOPE=1           # Capture task list + spec hashes at start
STOP_ON_SCOPE_CHANGE=1   # Halt if scope changes during execution

Implementation

freeze_scope() - Called once at start:

  • Saves task IDs to $RUN_DIR/scope_task_ids.txt
  • Computes MD5 hash of each spec file → $RUN_DIR/scope_spec_hashes.txt
  • Full JSON snapshot → $RUN_DIR/scope.json

check_scope_integrity() - Called each iteration:

  • Compares current task IDs vs frozen list
  • Compares current spec hashes vs frozen hashes
  • Detects: additions, removals, content modifications
  • Allows: status changes (todo→done) - normal progression
freeze_scope() at start
        ↓
     iteration
        ↓
check_scope_integrity()
        ↓
    ┌───┴───┐
    │       │
 unchanged  changed
    │       │
 continue   STOP (if STOP_ON_SCOPE_CHANGE=1)

Files Created in $RUN_DIR/

File Content
scope.json Full task list snapshot from flowctl
scope_task_ids.txt Sorted task IDs (for diff)
scope_spec_hashes.txt task_id:md5hash pairs

Detection Types

Change Type Detection Method Outcome
Task added comm -13 on task IDs SCOPE_CHANGED
Task removed comm -23 on task IDs SCOPE_CHANGED
Spec modified MD5 hash comparison SCOPE_CHANGED
Status change (todo→done) Not tracked Allowed (normal)

Use Case

Production system running overnight. Requirements:

  • Only planned work executes
  • No surprise tasks from concurrent planning sessions
  • Clean audit trail of what was in scope
  • Safe to leave running unattended

Backwards Compatibility

  • Default: FREEZE_SCOPE=0 - behavior unchanged
  • Opt-in: Users enable when they need deterministic execution

Implementation Status

Already working in our production fork. Happy to submit PR if there's interest.

Questions for Maintainers

  1. Should this be opt-in (proposed) or opt-out?
  2. Any preference on where scope files are stored?
  3. Should we also track epic-level changes, or task-level is sufficient?

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions