From 196f4e32e7f446569e3d4936362c399a716394cf Mon Sep 17 00:00:00 2001
From: Kasper Junge
Date: Mon, 8 Jun 2026 19:08:46 +0200
Subject: [PATCH] docs: surface args so users can parameterize ralph loops
Highlight the args frontmatter field across the README and docs entry
points, and reframe a ralph as a directory conforming to the open ralph
loops format (ralphloops.io) rather than a lone RALPH.md file.
Co-Authored-By: Claude Opus 4.8
---
README.md | 23 +++++++-
docs/diary/2026-06-08-surface-args-in-docs.md | 55 +++++++++++++++++++
docs/getting-started.md | 21 ++++++-
docs/index.md | 4 +-
4 files changed, 99 insertions(+), 4 deletions(-)
create mode 100644 docs/diary/2026-06-08-surface-args-in-docs.md
diff --git a/README.md b/README.md
index c9923e6..5a6b685 100644
--- a/README.md
+++ b/README.md
@@ -60,7 +60,7 @@ Everything in ralphify is one of these five jobs. That's the whole tool.
### 1. Write a ralph
-A ralph is a directory with a `RALPH.md` file. Scaffold one:
+A ralph is a *directory* containing a `RALPH.md` file — that file is the only requirement, and its shape is defined by the open [ralph loops format](https://ralphloops.io/). Scaffold one:
```bash
ralph scaffold my-ralph
@@ -77,6 +77,27 @@ Read TODO.md, pick the top unfinished task, implement it fully, commit, then sto
One task per iteration. No placeholder code.
```
+The format has three frontmatter fields — `agent`, `commands` (live data, see below), and `args` (user arguments that parameterize the loop). `args` lets one ralph be reused with different inputs:
+
+```markdown
+---
+agent: claude -p --dangerously-skip-permissions
+commands:
+ - name: tests
+ run: uv run pytest -x
+args:
+ - focus
+---
+
+Refactor the code under {{ args.focus }}. Keep tests green.
+
+{{ commands.tests }}
+```
+
+```bash
+ralph run my-ralph --focus src/auth # {{ args.focus }} → src/auth
+```
+
### 2. Feed it live data
`commands` run before each iteration. Their output replaces `{{ commands. }}` in the prompt, so the agent always sees the current state — test results, coverage, git log, lint output:
diff --git a/docs/diary/2026-06-08-surface-args-in-docs.md b/docs/diary/2026-06-08-surface-args-in-docs.md
new file mode 100644
index 0000000..42a0ae2
--- /dev/null
+++ b/docs/diary/2026-06-08-surface-args-in-docs.md
@@ -0,0 +1,55 @@
+# Diary: Surface the `args` feature and tighten the ralph-directory framing in docs
+
+The README and docs explained `agent` and `commands` thoroughly but never showed the third frontmatter field, `args`, so the parameterization story was invisible to a first-time reader. Separately, several surfaces described a ralph as just "a `RALPH.md`" when it's really a *directory* containing one, whose format is defined by the open spec at [ralphloops.io](https://ralphloops.io/). This task fixes both across the README and the docs site.
+
+## Step 1: Add args illustrations and tighten directory/spec framing
+
+**Author:** main
+
+### Prompt Context
+
+**Verbatim prompt:** "Okay so a couple of things for the documentation: - You mentioned that the only thing a Ralph loop for Ralphify needs is a ralph.md but it's not entirely true. It's a directory with ralph.md in it and linked to the format specification on Ralph loops that I owe. - In the README you do not highlight the args feature of the loop or of Ralph loops' format. - It would be nice to also have an example where it shows you can actually add arguments to the Ralph loops so you can actually parameterize them. You show the commands and you show the agent but also show the args. Is this clear? Do you have any clarifying questions?"
+
+**Interpretation:** Correct the "all you need is a RALPH.md" framing to "a directory containing a RALPH.md" and link the format spec; make `args` visible in the README; add an illustration showing how `args` parameterizes a loop alongside `agent` and `commands`.
+
+**Inferred intent:** New readers should understand that a ralph conforms to an open, portable format (not an ad-hoc file), and should discover that loops are parameterizable — a key reuse capability that was effectively hidden.
+
+### What I did
+
+Asked two clarifying questions up front via `AskUserQuestion`. The user clarified they did **not** want a real-world worked example — just a minimal snippet that demonstrates the *format* using `args` — and that changes should land in both the README and the docs site.
+
+Then made docs-only edits:
+
+- `/README.md` — "Write a ralph" job now states a ralph is a *directory* containing `RALPH.md` and links the [ralph loops format](https://ralphloops.io/). Added a minimal frontmatter illustration showing all three fields together (`agent` + `commands` + `args`) with a `ralph run my-ralph --focus src/auth` invocation.
+- `/docs/index.md` — Reworded the hero to "a directory whose one required file is `RALPH.md`"; the "Write a ralph" card now mentions `args` / `{{ args. }}`.
+- `/docs/getting-started.md` — Manual-setup intro reframed as a directory and links the spec; added a "Parameterize a ralph with `args`" tip box with a minimal snippet, CLI invocation, and a cross-link to the CLI reference's user-arguments section.
+
+Verified with `uv run mkdocs build --strict` (passes) and `uv run pytest -q` (627 passed, 1 xpassed).
+
+### Why
+
+The user owns the ralph loops format spec and wants the docs to consistently frame a ralph as a directory conforming to that open format, not a lone file. And `args` is a first-class format field that enables reuse, so it deserves visibility next to `agent` and `commands`.
+
+### What worked
+
+Clarifying first paid off — the initial instinct was to feature the untracked `ralphs/example/` research ralph, but the user wanted a *minimal format illustration*, not a real example. That steered the edits toward tight, copy-pasteable snippets rather than a heavier worked example.
+
+### What didn't work
+
+`uv run mkdocs build --strict` prints an alarming red block ("No migration path exists", "Closed contribution model", etc.). On inspection this is mkdocs-material's unrelated April-Fools "MkDocs 2.0" marketing banner printed to stderr, not a build warning. The build itself reports "Documentation built" with no strict failures.
+
+### What I learned
+
+The docs already had extensive `args` coverage in the reference pages (`cli.md`, `quick-reference.md`, `how-it-works.md`, `cookbook.md`) — the gap was purely in the *entry-point* surfaces (README, index hero, getting-started manual setup) where a newcomer first forms their mental model.
+
+### What was tricky
+
+The README is structured around a fixed "five things you do with ralphify" framing, so adding `args` couldn't introduce a sixth job. Folding the args illustration into job #1 ("Write a ralph") — since `args` is a format field, not a separate activity — kept the structure intact.
+
+### What warrants review
+
+Check that the three new snippets are internally consistent (they all use `{{ args.focus }}` with `--focus src/auth`) and that the cross-link `cli.md#user-arguments` resolves. Confirm the directory/spec framing reads naturally in each location rather than feeling repetitive across README and index hero.
+
+### Future work
+
+The untracked `ralphs/example/` directory (a research ralph using `agent` + `commands` + `args`) was left in place but not referenced. Decide whether to keep it as a shipped example, move it into the cookbook, or remove it.
diff --git a/docs/getting-started.md b/docs/getting-started.md
index fce2bde..16e84c5 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -67,7 +67,7 @@ Or create the file manually as shown below.
### Manual setup
-Create a ralph directory and `RALPH.md` with the agent field — this is the only required frontmatter:
+A ralph is a *directory* containing a `RALPH.md` file — the file's shape is defined by the open [ralph loops format](https://ralphloops.io/). Create the directory and a `RALPH.md` with the agent field — this is the only required frontmatter:
```markdown
---
@@ -89,6 +89,25 @@ implement it fully, then mark it done.
- Mark the completed task in TODO.md
```
+!!! tip "Parameterize a ralph with `args`"
+ Declare `args` in the frontmatter to make one ralph reusable with different inputs. Each name becomes a `{{ args. }}` placeholder filled from the CLI:
+
+ ```markdown
+ ---
+ agent: claude -p --dangerously-skip-permissions
+ args:
+ - focus
+ ---
+
+ Refactor the code under {{ args.focus }}. One module per iteration.
+ ```
+
+ ```bash
+ ralph run my-ralph --focus src/auth
+ ```
+
+ See the [CLI reference](cli.md#user-arguments) for named vs. positional args.
+
!!! info "What does `--dangerously-skip-permissions` do?"
Claude Code normally asks for your approval before running shell commands, editing files, or making git commits. The `--dangerously-skip-permissions` flag disables these interactive prompts so the agent can work autonomously without waiting for input. The `-p` flag enables non-interactive ("print") mode, which reads the prompt from stdin instead of opening a chat session.
diff --git a/docs/index.md b/docs/index.md
index 74883b2..f6c3d44 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -14,7 +14,7 @@ hide:
Ralphify runs ralph loops.
-A **ralph loop** is a portable directory that defines an autonomous agent loop — a prompt, the commands to run between iterations, and any files the agent needs. It's an open format ([ralphloops.io](https://ralphloops.io/)): one required file, `RALPH.md`. **Ralphify** is the CLI that runs it.
+A **ralph loop** is a portable directory that defines an autonomous agent loop — a prompt, the commands to run between iterations, and any files the agent needs. It's an open format ([ralphloops.io](https://ralphloops.io/)): a directory whose one required file is `RALPH.md`. **Ralphify** is the CLI that runs it.
```
grow-coverage/
@@ -82,7 +82,7 @@ Everything in ralphify is one of these five jobs. That's the whole tool.
---
- Scaffold a directory with a `RALPH.md` — YAML frontmatter for config, a markdown body for the prompt. The only required field is `agent`.
+ Scaffold a directory with a `RALPH.md` — YAML frontmatter for config, a markdown body for the prompt. The only required field is `agent`; add `args` to parameterize the loop with `{{ args. }}`.
```bash
ralph scaffold my-ralph