Skip to content

Commit e14f4c5

Browse files
Document Ralph loop implementation details
1 parent d5c33fd commit e14f4c5

File tree

2 files changed

+88
-11
lines changed

2 files changed

+88
-11
lines changed

docs/features/memory.md

Lines changed: 64 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ Set `baseUrl` to point at any OpenAI-compatible self-hosted service (vLLM, Ollam
138138
| `ralph.defaultAudit` | Run auditor after each coding iteration | `true` |
139139
| `ralph.model` | Model override for Ralph sessions (`provider/model`), falls back to `executionModel` ||
140140
| `ralph.minAudits` | Minimum audit iterations required before completion | `1` |
141+
| `ralph.stallTimeoutMs` | Watchdog stall detection timeout (ms) | `60000` |
141142
| `auditorModel` | Model override for the auditor agent (`provider/model`). When set, overrides the auditor agent's default model. When not set, the auditor uses the platform default. ||
142143

143144
---
@@ -505,10 +506,11 @@ The Ralph loop is an iterative development system that alternates between coding
505506
1. A new session is created (in a worktree or in-place)
506507
2. The Code agent receives the task prompt and works on it
507508
3. When the session goes idle, the Ralph handler checks the phase:
508-
- **Coding phase** → If auditing is enabled, switches to auditing phase and runs the Auditor agent as a subtask
509-
- **Auditing phase** → Processes audit findings, switches back to coding phase, and sends a continuation prompt with the findings
510-
4. The loop repeats until one of these conditions is met:
511-
- **Completion**: The `completionPromise` phrase is detected in `<promise>` tags AND `minAudits` (default 1) audit iterations have been performed. Without a `completionPromise`, the loop does not auto-complete.
509+
- **Coding phase** → If auditing is enabled, switches to auditing phase and invokes the Auditor agent as a subtask with a focused review prompt
510+
- **Auditing phase** → Extracts the auditor's full response as findings, switches back to coding phase, and sends a continuation prompt with the findings
511+
4. **Session rotation** — The current session is destroyed and a fresh one is created. The original task prompt and any audit findings are re-injected as a continuation prompt. This keeps each iteration's context window small and prioritizes speed.
512+
5. The loop repeats until one of these conditions is met:
513+
- **Completion**: The `completionPromise` phrase is detected in `<promise>` tags AND `minAudits` (default 1) audit iterations have been performed
512514
- **Max iterations**: Reached `maxIterations` limit (if > 0)
513515
- **Error limit**: 3 consecutive failures (`MAX_RETRIES`)
514516
- **Stall timeout**: 5 consecutive stalls detected by the watchdog (`MAX_CONSECUTIVE_STALLS`)
@@ -523,6 +525,57 @@ The Ralph loop is an iterative development system that alternates between coding
523525
| Worktree (default) | Isolated git worktree | Yes, on completion | Worktree removed, branch preserved | File ops scoped to worktree, git push denied |
524526
| In-place (`inPlace: true`) | None — runs in current directory | No | None | Git push denied only |
525527

528+
#### Session Rotation
529+
530+
Each iteration runs in a **fresh session**. After each phase completes (coding or auditing), the current session is destroyed and a new one is created. This design keeps the context window small across many iterations, reducing token costs and improving speed.
531+
532+
The rotation flow:
533+
534+
1. Create a new session targeting the worktree directory (or current directory for in-place)
535+
2. Update internal session-to-worktree mappings
536+
3. Reset the watchdog stall timer
537+
4. Delete the old session (fire-and-forget)
538+
5. Send a **continuation prompt** to the new session containing:
539+
- The iteration number and completion signal instructions
540+
- The original task prompt (verbatim)
541+
- Audit findings from the previous iteration (if any), with a mandatory instruction to fix all bugs and convention violations
542+
543+
No context is lost — the task and findings are re-injected each iteration. The tradeoff is that the agent loses awareness of its own prior implementation steps, but the code on disk (and any audit findings) provide sufficient continuity.
544+
545+
#### Review Finding Persistence
546+
547+
Audit findings survive session rotation via the **KV store**. This ensures issues are tracked across iterations even as sessions are destroyed and recreated.
548+
549+
**Storage flow** (auditor writes findings):
550+
551+
After each review, the Auditor stores every **bug** and **warning** finding (not suggestions) using `memory-kv-set`:
552+
553+
- **Key:** `review-finding:<file_path>:<line_number>`
554+
- **Value:** JSON object with severity, file, line, description, scenario, status, date, and branch
555+
- The KV store uses upsert semantics — storing the same key updates the existing entry
556+
- Findings expire after 7 days automatically
557+
558+
**Retrieval flow** (auditor reads past findings):
559+
560+
At the start of every review, before analyzing the diff:
561+
562+
1. Retrieve all entries with `memory-kv-list` (prefix `review-finding:`)
563+
2. Match findings against files in the current diff
564+
3. Include unresolved findings under a "Previously Identified Issues" heading
565+
4. Delete resolved findings via `memory-kv-delete`
566+
567+
!!! note
568+
Finding persistence is enforced via the auditor's system prompt, not application code. The auditor is instructed to use KV tools for storage and retrieval as part of its review workflow.
569+
570+
#### Watchdog and Stall Detection
571+
572+
A watchdog timer monitors each Ralph loop for stalls — situations where the session stops producing `session.idle` events within the expected timeframe.
573+
574+
- **`stallTimeoutMs`** (default `60000`): If no activity is detected within this window, the watchdog fires
575+
- On each stall, the watchdog checks the session status and re-triggers the appropriate phase handler
576+
- **`MAX_CONSECUTIVE_STALLS`** (`5`): After 5 consecutive stalls without progress, the loop terminates with reason `stall_timeout`
577+
- The stall counter resets whenever a successful `session.idle` event is processed
578+
526579
#### Tool Blocking
527580

528581
During a Ralph loop, certain tools are blocked to keep the agent focused:
@@ -540,6 +593,12 @@ Blocking is enforced via `tool.execute.before` (throws error) with `tool.execute
540593
| `ralph.model` | Model for Ralph coding sessions | `executionModel` → platform default |
541594
| `auditorModel` | Model for the auditor agent | Platform default (no fallback chain) |
542595

596+
#### Model Fallback on Error
597+
598+
If the configured model produces a provider, auth, or API error during a Ralph iteration, the loop automatically falls back to the platform default model for all remaining iterations. This prevents the loop from exhausting retries on a misconfigured or unavailable model.
599+
600+
The fallback is permanent within a loop — once triggered, the `modelFailed` flag is set on the loop state and is never reset. The error count is incremented on each model failure; after 3 consecutive failures (`MAX_RETRIES`), the loop terminates regardless of fallback.
601+
543602
#### Slash Commands
544603

545604
| Command | Description |
@@ -612,7 +671,7 @@ The Auditor agent is a read-only subagent invoked by other agents via the Task t
612671

613672
The agent can read memory (`memory-read`) but cannot write, edit, or delete memories. It also cannot execute plans — `memory-plan-execute`, `memory-plan-ralph`, `memory-health`, `memory-write`, `memory-edit`, and `memory-delete` are excluded.
614673

615-
The Auditor persists review findings to the KV store (key pattern: `review-finding:<file_path>:<line_number>`) and retrieves past findings at the start of every review for continuity.
674+
The Auditor persists review findings to the KV store (key pattern: `review-finding:<file_path>:<line_number>`) and retrieves past findings at the start of every review for continuity. Each finding is a JSON object containing severity, file, line, description, scenario, status, date, and branch. Only bugs and warnings are persisted — suggestions are not stored. Resolved findings are deleted during subsequent reviews. See [Review Finding Persistence](#review-finding-persistence) for the full lifecycle.
616675

617676
The `/review` slash command triggers this agent as a subtask with the template: "Review the current code changes."
618677

packages/memory/README.md

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ The local embedding model downloads automatically on install. For API-based embe
3434
- **Compaction Context Injection** - Injects conventions and decisions into session compaction for seamless continuity
3535
- **Automatic Memory Injection** - Injects relevant project memories into user messages via semantic search with distance filtering and caching
3636
- **Project KV Store** - Ephemeral key-value storage with TTL management for project state
37-
- **Bundled Agents** - Ships with Code, Architect, and Librarian agents preconfigured for memory-aware workflows
37+
- **Bundled Agents** - Ships with Code, Architect, Auditor and Librarian agents preconfigured for memory-aware workflows
3838
- **CLI Tools** - Export, import, list, stats, cleanup, upgrade, status, and cancel commands via `ocm-mem` binary
3939
- **Dimension Mismatch Detection** - Detects embedding model changes and guides recovery via reindex
4040

@@ -51,7 +51,8 @@ The plugin bundles four agents that integrate with the memory system:
5151

5252
The auditor agent is a read-only subagent (`temperature: 0.0`) that can read memory but cannot write, edit, or delete memories or execute plans. It is invoked by other agents via the Task tool to review code changes against stored project conventions and decisions.
5353

54-
The architect agent operates in read-only mode (`temperature: 0.0`, all edits denied) with additional message-level read-only enforcement via the `experimental.chat.messages.transform` hook. After the user approves a plan, it calls `memory-plan-execute` which creates a new code session with the full plan as context.
54+
The architect agent operates in read-only mode (`temperature: 0.0`, all edits denied) with additional message-level read-only enforcement via the `experimental.chat.messages.transform` hook. After the user approves a plan you can choose to execute the plan in the same session with your execution model (less advanced model needed for cost / speed), new session, ralph loop in the same branch or in external worktree.
55+
5556

5657
## Tools
5758

@@ -361,15 +362,32 @@ See the [full workflow guide](https://chriswritescode-dev.github.io/opencode-man
361362

362363
The Ralph loop is an iterative development system that alternates between coding and auditing phases:
363364

364-
1. **Coding phase** — The Code agent works on the task
365-
2. **Auditing phase** — The Auditor agent reviews changes against project conventions
366-
3. **Repeat** — Findings from the audit feed back into the next coding iteration
365+
1. **Coding phase** — A Code session works on the task
366+
2. **Auditing phase** — The Auditor agent reviews changes against project conventions and stored review findings
367+
3. **Session rotation** — A fresh session is created for the next iteration
368+
4. **Repeat** — Audit findings feed back into the next coding iteration
369+
370+
### Session Rotation
371+
372+
Each iteration runs in a **fresh session** to keep context small and prioritize speed. After each phase completes, the current session is destroyed and a new one is created. The original task prompt and any audit findings are re-injected into the new session as a continuation prompt, so no context is lost while keeping the window clean.
373+
374+
### Review Finding Persistence
375+
376+
Audit findings survive session rotation via the **KV store**. The auditor stores each bug and warning as a KV entry with key `review-finding:<file>:<line>` containing severity, description, and status. At the start of each audit:
377+
378+
- Existing findings are retrieved via `memory-kv-list` with prefix `review-finding:`
379+
- Resolved findings are deleted
380+
- Unresolved findings are carried forward into the review
381+
382+
This ensures review findings are never lost between iterations, even as sessions rotate.
383+
384+
### Completion and Termination
367385

368386
The loop completes when the Code agent outputs the completion promise. It auto-terminates after `maxIterations` (if set) or after 3 consecutive errors.
369387

370388
By default, Ralph loops run in an isolated git worktree. Set `inPlace: true` to run in the current directory instead (skips worktree creation, auto-commit, and cleanup).
371389

372-
See the [full documentation](https://chriswritescode-dev.github.io/opencode-manager/features/memory/#ralph-loop) for details on the Ralph loop system.
390+
See the [full documentation](https://chriswritescode-dev.github.io/opencode-manager/features/memory/#ralph-loop) for details on worktree management, model configuration, and termination conditions.
373391

374392
## Documentation
375393

0 commit comments

Comments
 (0)