Skip to content
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
807e5e4
feat: add Docker containerization and parallel multi-agent execution
mtgibbs Feb 13, 2026
75e9a1d
fix: volume-based auth, --project flag, and smoke test fixes
mtgibbs Feb 13, 2026
0c4418b
feat: add --image flag for custom Docker images
mtgibbs Feb 13, 2026
cee3b3d
fix: claim_story stdout pollution and set -e crash on retry
mtgibbs Feb 13, 2026
f7f879d
fix: add jsr.io and deno.land to builder firewall whitelist
mtgibbs Feb 13, 2026
b36bef3
security: fix token exposure, hardcoded platform, and firewall generi…
mtgibbs Feb 13, 2026
538c478
fix: handle new branch push and pull in agent-loop
mtgibbs Feb 13, 2026
2c82c08
feat: auto-detect Dockerfile.ralph in project directory
mtgibbs Feb 13, 2026
991e2b9
fix: address PR review feedback
mtgibbs Feb 13, 2026
bd54904
Fix double-claiming: script claims story, injects ID into prompt
mtgibbs Feb 14, 2026
d651eff
fix: prevent story hoarding and release claims on auth failure
mtgibbs Feb 17, 2026
904afc1
feat: verifier agents and docker labels for container tracking
mtgibbs Feb 17, 2026
b3dcc25
fix: complete fetch-before-verify and clean dirty trees between itera…
mtgibbs Feb 20, 2026
be73a93
fix: exponential backoff and max retry limit for auth failures
mtgibbs Feb 20, 2026
21abddb
fix: force-push bare repo sync and clean stale branches on launch
mtgibbs Feb 20, 2026
82e8165
Merge pull request #1 from mtgibbs/fix/retro-agent-bugs
mtgibbs Feb 20, 2026
cd0fecd
feat: configurable git author identities via .ralph/friends.json
mtgibbs Feb 21, 2026
06c578a
feat: story dependencies via dependsOn field for parallel execution c…
mtgibbs Feb 21, 2026
fb037c6
feat: halt orchestrator on agent auth failure (exit code 2)
mtgibbs Feb 21, 2026
28566bc
fix: use extended regex for bare repo branch cleanup on macOS
mtgibbs Feb 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,8 @@ progress.txt

#Claude
.claude/

# Parallel mode state
.ralph/
agent_logs/
progress-agent-*.txt
11 changes: 11 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,14 @@ npm run dev
- Memory persists via git history, `progress.txt`, and `prd.json`
- Stories should be small enough to complete in one context window
- Always update AGENTS.md with discovered patterns for future iterations

## Parallel Mode

Ralph supports running multiple agents in parallel via Docker containers. See `parallel/README.md` for details.

- Parallel scripts live in `parallel/` — orchestrator, status, stop
- Docker image and container entrypoint live in `docker/`
- Agents claim stories via `claimed_by` field in prd.json using git atomic push
- Each agent writes to its own `progress-<agent-id>.txt` to avoid merge conflicts
- Builder agents have restricted network access (Claude API + npm only)
- Researcher agents have full internet access
56 changes: 56 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ Ralph will:
| `skills/ralph/` | Skill for converting PRDs to JSON (works with Amp and Claude Code) |
| `.claude-plugin/` | Plugin manifest for Claude Code marketplace discovery |
| `flowchart/` | Interactive visualization of how Ralph works |
| `docker/` | Dockerfile and container scripts for parallel mode |
| `parallel/` | Parallel mode orchestrator, status, and stop scripts |

## Flowchart

Expand Down Expand Up @@ -232,6 +234,60 @@ After copying `prompt.md` (for Amp) or `CLAUDE.md` (for Claude Code) to your pro

Ralph automatically archives previous runs when you start a new feature (different `branchName`). Archives are saved to `archive/YYYY-MM-DD-feature-name/`.

## Parallel Mode (Docker)

Ralph includes a parallel mode that runs N containerized Claude Code agents simultaneously against the same PRD. Each agent runs in a Docker container with:

- **Network restrictions** — builder agents can only reach Claude API and npm registry
- **Resource limits** — configurable memory and CPU caps per container
- **Story claiming** — agents claim stories via git atomic push to avoid duplicate work
- **Automatic recovery** — stale claims are cleared, crashed containers are restarted

### Prerequisites (Parallel Mode)

- Docker installed and running
- A Claude Code auth token (env var, file, or 1Password)
- `jq` installed

### Quick Start (Parallel Mode)

```bash
# Set your Claude auth token
export RALPH_CLAUDE_TOKEN='<your-token>'

# Run 3 agents in parallel
./parallel/ralph-parallel.sh --agents 3

# Check status
./parallel/status.sh

# Graceful shutdown
./parallel/stop.sh
```

### Options

```bash
./parallel/ralph-parallel.sh \
--agents 3 \ # number of builder agents (default: 2)
--model claude-sonnet-4-5-20250929 \ # model (default: sonnet)
--memory 4g \ # per-container memory limit
--cpus 2 \ # per-container CPU limit
--researcher 1 \ # researcher agents with full internet access
[max_iterations] # per-agent iteration cap (default: 0 = until PRD complete)
```

### Auth Token

Priority order (first wins):
1. `RALPH_CLAUDE_TOKEN` environment variable
2. `.ralph/token` file in the project directory
3. 1Password via `op read` (interactive, startup only)

To refresh the token mid-run without stopping, write a new token to `.ralph/token_refresh`. The orchestrator picks it up within 30 seconds and restarts all containers.

See [parallel/README.md](parallel/README.md) for full documentation.

## References

- [Geoffrey Huntley's Ralph article](https://ghuntley.com/ralph/)
Expand Down
41 changes: 41 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
FROM node:20-slim

# System deps for networking, git, and general tooling
RUN apt-get update && apt-get install -y --no-install-recommends \
git \
iptables \
ipset \
iproute2 \
dnsutils \
jq \
curl \
sudo \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# Install claude-code globally
RUN npm install -g @anthropic-ai/claude-code

# Create non-root agent user (UID 1001 since node:20-slim uses 1000 for 'node')
RUN useradd -m -s /bin/bash -u 1001 agent

# Allow agent to run firewall init scripts via sudo (no password)
RUN echo "agent ALL=(root) NOPASSWD:SETENV: /opt/ralph/init-firewall-builder.sh, /opt/ralph/init-firewall-researcher.sh" \
> /etc/sudoers.d/agent-firewall && chmod 0440 /etc/sudoers.d/agent-firewall

# Copy scripts
COPY agent-loop.sh /opt/ralph/agent-loop.sh
COPY init-firewall-builder.sh /opt/ralph/init-firewall-builder.sh
COPY init-firewall-researcher.sh /opt/ralph/init-firewall-researcher.sh
RUN chmod +x /opt/ralph/agent-loop.sh /opt/ralph/init-firewall-builder.sh /opt/ralph/init-firewall-researcher.sh

# Workspace for cloned repo
RUN mkdir -p /workspace && chown agent:agent /workspace

# Claude config directory
RUN mkdir -p /home/agent/.claude && chown agent:agent /home/agent/.claude

USER agent
WORKDIR /workspace

ENTRYPOINT ["/opt/ralph/agent-loop.sh"]
Loading