While Component
Repeats child components while condition remains true, persisting iteration state in SQLite for crash-resume. Core primitive for review loops, convergence workflows, polling, and iterative refinement.API
Usage
Retry Until Success
Review-Fix Loop
Polling Loop
Props
Stable identifier for component identity across restarts. Used to build iteration scope IDs.Scope ID format:
root.while.{id}.{iteration}Examples:"fix-and-retry"- Descriptive, stable"review-loop"- Indicates purpose- ❌ Random UUID - Breaks resumability
{scopeId}.while.{id}.iteration- Current iteration number{scopeId}.while.{id}.status- pending/running/complete
Function evaluated before each iteration. Loop continues while true.Evaluation points:
- Start of While (iteration 0) - decides if loop starts
- After each iteration completes - decides if next iteration runs
Maximum iterations before forcing loop exit.Prevents infinite loops from buggy condition functions.Completion reason: When max reached,
onComplete called with reason=‘max’.Set to high value for long-running convergence loops:Components executed each iteration under isolated scope.Scoping: Each iteration gets ExecutionBoundary with unique scopeId:
- Iteration 0:
root.while.fix-tests.0 - Iteration 1:
root.while.fix-tests.1 - Iteration N:
root.while.fix-tests.N
Callback fired when each iteration starts (after condition evaluates true).Use cases:
- Logging/observability
- Updating external state
- Progress reporting
Callback when loop exits.Parameters:
iterations- Total iterations executedreason- Why loop ended:'condition'- Condition returned false (success)'max'- Hit maxIterations limit (potentially incomplete)
Implementation Status
1
Core Implementation
While component with condition evaluation, iteration state persistence, and WhileIterationContext.
2
SQLite State
Iteration count and status persisted in
state table with keys while.{id}.iteration and while.{id}.status.3
Context Provider
useWhileIteration() hook provides iteration number and signalComplete() for child components.4
Testing
Additional test coverage for edge cases (crash-resume, max iterations, nested While loops).
Design Rationale
State Machine
Why Ralph Should Wrap While
Current Ralph behavior: Loops until no pending tasks remain. Equivalent While expression:- Single loop primitive - all iteration logic in one place
- Testable - While easier to test in isolation
- Composable - Ralph becomes configuration
- Less code - remove duplicate iteration logic from SmithersProvider
Scoping for Re-execution
Without scoping, phases/steps can’t re-execute:- Iteration 0:
root.while.fix-tests.0→ phase “Attempt Fix” in this scope - Iteration 1:
root.while.fix-tests.1→ different scope, phase can re-execute
Plan Output
Examples of Use Cases
Use Case 1: Convergence Loop
Use Case 2: Nested While Loops
root.while.outer.N.while.inner.M
Use Case 3: Timeout-Based Polling
Related
While Component Issue
Full design with state machine, scoping requirements, Ralph refactor plan
Control Flow Components
Parent issue covering ExecutionBoundary, scoping infrastructure shared by If/While/Switch
If Component
Conditional execution - shares scoping and execution gating with While
Ralph Component
Will be refactored to wrap While after implementation
Alternatives Considered
- Loop via React state: Loses crash-resume, no plan visibility
- Recursive Phase calls: Not supported by reconciler
- Manual iteration with Step index: Requires user to manage state, error-prone
- Ralph-only loops: Not flexible enough for custom conditions