No description
Find a file
2026-05-11 14:32:46 +00:00
systemd phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00
.gitignore phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00
AGENTS.md phase 1: verify primitives — confirmed opencode run flags and network layout 2026-04-25 09:42:17 +00:00
fix_plan.md phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00
PLAN.md phase 1: verify primitives — confirmed opencode run flags and network layout 2026-04-25 09:42:17 +00:00
prd.json.example phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00
prd.schema.json phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00
progress.txt phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00
PROMPT.md feat: Playwright tests + Puppeteer MCP checks per iteration 2026-05-11 14:32:46 +00:00
ralph.sh feat: Playwright tests + Puppeteer MCP checks per iteration 2026-05-11 14:32:46 +00:00
README.md phase 2+3: ralph.sh, PROMPT.md, schemas, systemd unit, README 2026-04-25 09:43:46 +00:00

ralph-opencode

Plug Ralph's autonomous loop methodology into OpenCode.

The 1st principle

One thing per loop. Only one thing.

Ralph is deterministically bad in a non-deterministic world: a dumb while :; do opencode run --file PROMPT.md; done loop where every turn starts with a fresh context window, re-loads the same stack (specs + prd.json + progress.txt + AGENTS.md), picks the single highest-priority unmet story, does only that, commits, and loops. State lives in files and git — never in RAM.

Anti-patterns: multi-agent choreography, retry logic that hides failures, doing two things in one loop.

Quick start

# 1. Copy this template into your project
cp -r ~/apps/ralph-opencode/. ~/apps/ralph-projects/my-project/
cd ~/apps/ralph-projects/my-project
git init && git commit --allow-empty -m "init"

# 2. Write specs
mkdir specs
# Edit specs/my-feature.md

# 3. Generate prd.json (in OpenCode browser)
# /ralph-prd <feature description>
# /ralph-plan <feature name>

# 4. Add feedback loops to AGENTS.md, then run
MAX=30 ./ralph.sh

Environment variables

Variable Default Description
MAX 50 Max iterations before giving up
ATTACH http://localhost:9051 OpenCode backend address
PROMPT PROMPT.md Prompt file path
SLEEP 2 Seconds between iterations
ALLOW_DIRTY 0 Set to 1 to skip git clean check

Kill switch

touch STOP   # loop exits cleanly after current iteration
rm STOP      # resume

Run as a systemd service (survives SSH disconnect)

mkdir -p ~/.config/systemd/user ~/apps/ralph-projects/my-project
cp systemd/ralph-opencode@.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user start ralph-opencode@my-project
journalctl --user -xeu ralph-opencode@my-project -f

Tuning

Ralph is tuned by editing PROMPT.md:

  • Loops doing >1 thing → tighten rule 1 and "Hard constraints"
  • Loops re-implementing existing code → strengthen rule 2 (search first)
  • AGENTS.md filling with status updates → tighten rule 9
  • Commits not passing tests → strengthen rules 45

File layout

ralph.sh            loop driver
PROMPT.md           the prompt (tune this)
prd.json            task list with passes:bool per story
prd.json.example    schema example
prd.schema.json     JSON Schema draft-07
progress.txt        append-only inter-loop learnings
fix_plan.md         out-of-scope bugs logged by the agent
AGENTS.md           build/run knowledge; self-updated by agent
specs/              human-authored spec files
runs/               per-iteration logs (gitignored)
archive/            completed PRDs moved here on COMPLETE
systemd/            ralph-opencode@.service template

Network layout (this server)

  • localhost:9050 — python3 TCP proxy, public; auto-starts backend
  • localhost:9051 — opencode backend (direct); use this for --attach