The Ralph Loop has completely changed how I write software. For over a decade, my workflow for implementing a feature looked like this:

  • Step 1: write a tech spec (maybe informal; maybe just a Markdown file in Vimwiki).
  • Step 2: add a few TODO tasks (obvious, low-hanging fruit that I should pick up next).
# Implement 2FA with SMS

- links to third-party SMS provider |
- links to Figma designs            |<- my understanding on day 1
- functional requirement 1          |
- functional requirement 2          |


# TODO
- [ ] Add a `user_sms` table + migration |
- [ ] Add a `POST /v1/sms/pin` API       |<- low-hanging fruit
  • Step 3: implement the TODO items.
  • Step 4: think about what to do next.

Go back to step 3 and repeat until the project is complete.

The way I use the Ralph Loop now isn’t too different from that approach; the key difference is that the TODOs are done by LLMs (GPT-5.2 (xhigh) or Opus 4.5 (max)).

RalphLoop start Start prd Write PRD (tech-spec) start->prd todos Add TODO tasks (low-hanging fruit) prd->todos llm LLM implements TODO item todos->llm more More steps? llm->more think Think about next steps more->think yes done Done more->done no think->todos

I use OpenCode with a script to automate most of step 3 (implementing the TODO items).

ralph.ts    # it's somewhere on my PATH
ralph.md    # the system prompt for the Ralph Loop

# <current project files>
.opencode/
├── opencode.json # OpenCode permission/settings
├── log-sms.md    # append-only log for the LLM
└── prd-sms.md    # the PRD file

The setup is dead simple. I run ralph.ts <iterations> .opencode/prd-<name>.md. The script takes the ralph.md system prompt, inlines the paths to .opencode/prd-<name>.md and .opencode/log-<name>.md, and runs a new OpenCode session. It’s basically a for loop. The system prompt (ralph.md) instructs the LLM to mark the TODO item as complete, append progress to .opencode/log-<name>.md, and commit the changes.

Here is the full prompt ralph.md:

# Ralph Agent Instructions

You are an autonomous coding agent responsible for executing tasks within a software project.

## Your Task Pipeline

1.  **Contextual Review:**
    * Read the PRD at `RALPH_PRD_PATH`.
    * Read the progress log at `RALPH_LOG_PATH`.
2.  **Incremental Planning:**
    * Decide on a single, granular step to move the project closer to the full PRD implementation.
    * Steps need not be sequential, pick the one that feels right as the next step.
3.  **Execution:**
    * Implement that single step -- this is where you will spend most of your time.
4.  **Validation:**
    * Do everything that is available to verify that the changes are correct.
5.  **Version Control:**
    * Commit code changes with the message: `feat: [Item Title]`.
    * *Note: Skip `.opencode/` folder changes and any existing untracked files.*

## Progress Log Format
*Append-only. Information density is key.*

\`\`\`md
[short commit hash]
- informative (not prescriptive) notes to future self;
  such as learnings, patterns, gotchas, and/or useful snippets.
\`\`\`

> **Note:** The "Learnings" section is vital for helping future iterations pick up the next steps effectively.

---

## After Completing the Step

* Mark the step as complete in the `# Suggested Next Steps` section of `RALPH_PRD_PATH`.
* If there aren't enough steps left, add a new step to find more steps.
    * The goal is to include a dedicated step where you act as a slow, deliberate, and analytical thinker: an experienced architect and a rigorous QA specialist, to identify future steps.
* Improve existing steps, remove those that no longer apply (if any), and sort them by readiness to be picked up.

## Core Principles

* **Atomic Progress:** Work on **ONE** step at a time and commit frequently.
* **Excellence:** Strive for high-quality implementation in every iteration.
RalphInternal cluster_inputs Inputs cluster_iteration One Iteration prd prd-*.md prompt ralph.md prompt template prd->prompt log log-*.md log->prompt pick Pick one TODO step prompt->pick implement Implement pick->implement validate Validate implement->validate commit git commit validate->commit update Update PRD + Progress Log commit->update check All done? update->check check->prompt no complete COMPLETE check->complete yes

The .opencode/prd-sms.md might look something like this:

We are building SMS authentication with provider XYZ.
You can read the docs at http://xyz.com/docs/sms/api

Use the Figma MCP to inspect these node IDs: 110-5501 110-5729 290-8616

# Suggested Next Steps

- [ ] Add a `user_sms` table + migration
- [ ] Add a `POST /v1/sms/pin` API
- [ ] Study what needs to be done next and add a few more suggested steps.

And the ralph.ts script is the glue that runs the loop, plus a few extra niceties like opening the OpenCode web UI so I can inspect progress more easily.

Here is the full ralph.ts click to download.

RalphRunner cluster_loop Loop (max N iterations) start ralph.ts parse Parse args (port, iterations, PRD) start->parse fzf fzf: select model (GPT-5.2 / Opus 4.5) parse->fzf web Start opencode web server fzf->web session Create session + open browser web->session inject Inject PRD/log paths into ralph.md session->inject run opencode run inject->run check COMPLETE? run->check check->session no done Done check->done yes maxed Max iterations reached check->maxed limit

I hope you find this useful. This has significantly changed how I write code in 2026.
The PRD becomes of utmost importance: I spend a lot of time manually editing it to make sure it’s solid. I gave a short example above, but usually instead of instructions like “read this URL” or “use the Figma MCP”, I do those ahead of time and put the materials somewhere on the filesystem so they’re easily accessible to the LLM. We want to avoid extra cognitive overhead for the LLM (this is called context rot).

Of course, not everything is sunshine and rainbows after the loops are done. I find myself adding a few more TODO items just to clean the slop; or, at worst, manually editing the code. I’d say slop cleanup takes about 60% of my time, but it’s still worth it because I’m 2x to 3x faster and much less mentally exhausted at the end of the day.