Skip to content
Development
Skill

/ralph-loop

The iterative plan-driven advancement pattern John runs on. Read PLAN.md, advance one phase, update PLAN.md, repeat. Adapted from snarktank/ralph for John's longer-horizon, multi-half, subagent-fanout scope.

From plugin
joharnessburg
928 skills5 agents5 commands

Claude Code

$ npx -y skills add kitchen-engineer42/joharnessburg --skill ralph-loop --agent claude-code

SKILL.md

ralph-loop.SKILL.md
name: ralph-loop
description: The iterative plan-driven advancement pattern John runs on. Read PLAN.md, advance one phase, update PLAN.md, repeat. Adapted from snarktank/ralph for John's longer-horizon, multi-half, subagent-fanout scope.
metadata:
  triggers:
    - advance the plan
    - next phase
    - next iteration
    - continue the loop
    - ralph loop
    - resume work
    - phase boundary
    - mark phase done
    - what's the next unit of work
    - one unit of work

ralph-loop

The loop is simple. The discipline is the work.

Every iteration of substantive work in a John session takes the same shape:

1. **Read `<project>/PLAN.md`.** Re-read. Don't trust your memory of it from earlier in the session — context drifts, plans get edited by the user between iterations, and compaction may have happened. 2. **Find the next incomplete unit of work.** Usually the next phase whose "Done criteria" aren't met. Within a phase, the next work unit in its subagent matrix. 3. **Plan exactly that unit.** Not the whole project. Not the next two phases. The single next unit. 4. **Do the work.** Inline for things that fit one context window. Via subagent for things that don't or that benefit from parallelism — see [[subagent-dispatch]]. 5. **Update PLAN.md.** Mark the unit done. Append decisions to the Log section. If something blocked you, write it as an open question for the user. 6. **Stop or loop.** Stop at phase boundaries (clean compaction points, low risk of midway corruption). Loop within a phase if there's clearly more work and you're below ~50% context utilization.

That's it. The rest of this skill is failure modes and nuance.

**Templates may override this pattern.** The active template can define its own iteration model — substitute different phases, run a different loop shape, override what counts as "one unit." If a template ships loop instructions in `project_addon.md`, the active provider appendix, or a sibling skill, follow them. This skill is John's default; templates shape the variation. Always check PLAN.md plus the provider memory file (`CLAUDE.md` or `AGENTS.md`) before assuming the default applies.

Why this loop

Three reasons it works for John:

  • **PLAN.md is the durable contract.** When context compacts, the session restarts, or the user opens a fresh John-equipped session tomorrow, PLAN.md carries state forward. The loop's first step makes that contract real.
  • **One unit per iteration prevents drift.** Trying to plan-then-execute three things at once is where agents lose coherence. One unit, finish it, write it down, move on.
  • **The Log section converts "I got stuck" from session-ending failure into a checkpoint.** Writing the blocker out is more valuable than burning context retrying.

When NOT to use this pattern

  • **Trivial single-tool tasks.** If the user asks "rename this variable," don't read PLAN.md. The loop is for project work, not editor-level operations.
  • **Pure conversation / clarification.** When the user is exploring an idea with you, you're not in the loop yet. Move to the loop when work begins.
  • **The plan doesn't exist yet.** First write it ([[plan-md-authoring]]). The loop runs the plan; you can't loop without one.

Subagent fan-out inside an iteration

Many phases (especially in the knowledge phases) have hundreds of similar work units — one per chunk, one per knowledge entry. Don't loop on these serially. Within step 3-4 of the main loop:

  • Decide the work units (e.g., the list of chunks).
  • Fan out to subagents — one per unit, or batched if units are tiny. See [[subagent-dispatch]].
  • Subagents emit events to `<project>/.john/events/<phase>/...` — see [[event-log-and-reducer]].
  • Wait for fan-out to complete. Run the reducer. Inspect the canonical state.
  • Then update PLAN.md to reflect the phase result.

This is the horizontal/vertical matrix in practice. Main loop is horizontal; per-phase fan-out is vertical.

A fan-out phase is one workflow run

When the fan-out is large and uniform (dozens-to-thousands of units), the right engine for step 3-4 is a **dynamic workflow**: a script you author that fans the units out off your context, adversarially cross-checks the workers, and returns a compact summary while the per-entry events land on disk. One **fan-out phase = one workflow run**; the **phase boundary is the sign-off seam between runs** (workflows take no user input mid-run, so review, PLAN.md updates, and user questions happen *between* runs, never inside). The loop becomes:

> launch the phase workflow → wait → run `reduce_events.py` → read the checkpoint → update PLAN.md → advance.

The loop is **engine-agnostic** below this line: whether the units were dispatched by a workflow or inline, you still run the reducer and read the checkpoint — that's truth, not the workflow's return value. If the session isn't workflow-capable, dispatch inline; everything else is identical. The mechanics and the John-shaped stages are in [[vertical-workflows]].

The phase-boundary gate

At the end of any fan-out phase that produces knowledge entries, run the reducer **gated** — pass the phase's expected entry count (or range) from PLAN.md:

python3 "${CLAUDE_PLUGIN_ROOT}/scripts/reduce_events.py" extract --expect-entries 35-50 --verify-knowledge

Exit code 3 means **far short** (under ~90% of the expected minimum): the phase is NOT done, no matter how complete the work *feels*. Don't mark it done — surface the actual-vs-expected delta in PLAN.md's Log, find what was missed (crashed subagents? skipped chunks? a workflow agent whose events never landed?), and re-dispatch. This gate is deterministic — it exists precisely because both you and an LLM auditor can sincerely believe a truncated phase is complete. `--verify-knowledge` warnings (orphans / missing-on-disk) are report-only; read them before advancing, but they don't block.

**The rush signal.** Not every phase ends at a counted gate — but the same trap applies wi

Read more
@kitchen-engineer42
Ships withjoharnessburg

中文版: README_ZH.md John turns unstructured source material into a working knowledge-dense app. It keeps knowledge engineering and app building in one durable run, coordinates large per-entry fan-outs, and leaves auditable events and checkpoints on disk.

928 skills5 agents
Get the whole plugin

Stars on GitHub

Momentum

stars in total
9
Star history of kitchen-engineer42/joharnessburg on GitHub, a chart by star-history.com

Other skills on joharnessburg.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc11d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about ralph-loop.

Which coding agents can use ralph-loop?
ralph-loop installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.