Summary
When running Ralph overnight or unattended, external changes to the backlog during execution can cause unexpected behavior:
- New tasks picked up mid-run - without plan review gate
- Removed tasks - cause selector confusion
- 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
- Should this be opt-in (proposed) or opt-out?
- Any preference on where scope files are stored?
- Should we also track epic-level changes, or task-level is sufficient?
Summary
When running Ralph overnight or unattended, external changes to the backlog during execution can cause unexpected behavior:
This proposal adds opt-in scope isolation to freeze the task list at the start of execution.
Current Behavior
Problems This Causes
Proposed Solution
New opt-in config options:
Implementation
freeze_scope()- Called once at start:$RUN_DIR/scope_task_ids.txt$RUN_DIR/scope_spec_hashes.txt$RUN_DIR/scope.jsoncheck_scope_integrity()- Called each iteration:Files Created in
$RUN_DIR/scope.jsonscope_task_ids.txtscope_spec_hashes.txttask_id:md5hashpairsDetection Types
comm -13on task IDscomm -23on task IDsUse Case
Production system running overnight. Requirements:
Backwards Compatibility
FREEZE_SCOPE=0- behavior unchangedImplementation Status
Already working in our production fork. Happy to submit PR if there's interest.
Questions for Maintainers