AgentStack
SKILL verified MIT Self-run

Omh Ralph Driver

skill-witt3rd-oh-my-hermes-omh-ralph-driver · by witt3rd

Drive an omh-ralph run: dispatch, evidence, commit hygiene.

No reviews yet
0 installs
12 views
0.0% view→install

Install

$ agentstack add skill-witt3rd-oh-my-hermes-omh-ralph-driver

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Omh Ralph Driver? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

OMH Ralph Driver — orchestrator's playbook for verified execution

Load this skill alongside omh-ralph when you are the orchestrator dispatching the loop. omh-ralph is loaded by the role-tagged workers (executor / verifier / architect) — it covers the iron-law discipline inside each task's delegate_task call. This skill covers what you do as the dispatcher: plan-shape, iteration cadence, parallel batching, evidence gathering, verifier dispatch, strike handling, commit hygiene, and the final architect gate.

The two skills have different readers and different jobs. Don't merge them — worker context is precious; the dispatcher's playbook should not ride into every subagent.

This skill is the ralph-side counterpart to omh-ralplan-driver (which is the dispatcher playbook for ralplan, the design loop). The relationship is consistent: each method has a worker-side skill (used inside delegate_task) and a driver-side skill (used by the orchestrator between dispatches).

When to use ralph vs just write the code

Use ralph when:

  • You have a plan with 5+ independently-acceptable tasks (from

omh-ralplan or hand-authored).

  • Quality-via-verification matters more than wall-clock — each task's

output must be evidence-graded before the next builds on it.

  • You want clean checkpoints across many work units (no context bloat).
  • Some tasks are independent and can run in parallel batches.

Don't use ralph when:

  • The work is single-step or trivially obvious to write directly.
  • No plan exists yet — run omh-ralplan (or for an obvious goal,

omh-deep-interview first) before invoking ralph.

  • The user wants to skip verification (unusual; usually means the

work is small enough to do directly).

The arc of a ralph run

iter 1: pick eligible tasks → dispatch executors (parallel where safe)
        → gather evidence → dispatch verifiers (parallel) → mark passes/fails
        → update state → release lock → exit

iter 2: re-invoke. Read state. Pick next batch. Same cycle.

...

iter N: all tasks pass → Step 7 final architect review → mark complete.

The orchestrator's job between iterations: pick the right batch, write the right context for each executor, gather the right evidence, parse the verifier verdicts, and decide whether to retry or move on.

The five-step playbook

1. Read the plan; verify it is ralph-shaped

A ralph plan is a list of numbered tasks, each with:

  • A clear title.
  • A description tight enough that an executor with no prior context

can implement it.

  • Acceptance criteria that are testable. Generic criteria like

"implementation is complete" are rejected by ralph's planning gate.

  • Dependencies (which other tasks must be done first).
  • Files-touched (for parallel-batch planning — see step 3).

If the plan came from omh-ralplan, it is design-shaped, not ralph-shaped. The stance's "MV slice" section is your starting point; you may need to translate it to ralph's task format. Author .omh/plans/ralph-plan.md (or .omh/plans/ralplan-.md if it derives from a specific ralplan instance) with proper task structure.

The plan does not need every task pre-authored to the same depth — it can grow. Ralph's planning gate parses what's there at first invocation; new tasks discovered during execution land via the discovered: true flag in state.

2. Pick the right batch for each iteration

Each ralph iteration does ONE unit of work. A "unit" can be:

  • One task (when the next eligible task is alone, or has shared file

footprint with other eligibles)

  • A batch of 2-4 tasks (when independents are eligible and have

disjoint touch sets)

Eligibility = passes: false AND all dependencies met.

Disjoint touch sets = the tasks do not modify the same files. Read the plan's "Files to modify/create" lists. If two eligible tasks both touch bin/janus-new-being, they are NOT parallel-safe — one owns the modification. If one touches migrations/lib.py and another touches bin/_lineage.py, they are parallel-safe.

Edge case — shared imports. Even if files are disjoint, if Task A authors a helper that Task B imports, you may need Task A to land first. Surface this in dependency declarations during plan-authoring; if you miss it, the executor for B will surface the dependency mid-task.

Right batch size. 2-4 tasks. Five+ in one batch overloads orchestrator parsing of executor reports + verifier dispatch in your own context window.

3. Dispatch executors with rich context

Each executor gets a fresh subagent. Subagents have NO memory of prior iterations, prior conversations, prior tasks. Encode everything they need in the dispatch context.

The executor dispatch context must contain:

  • Project root + branch. Paths absolute, not relative.
  • Prior state. What tasks completed in earlier iterations, what

files now exist, what helpers/libraries are available to import.

  • Learnings from prior tasks that are relevant to this one. Pull

forward gotchas, naming conventions, architectural choices that the executor needs to honor.

  • The task itself. Full title, description, acceptance criteria.
  • Required reading. Absolute paths to the canonical design,

prior tasks' outputs, similar siblings to pattern-match against.

  • TDD instruction. Failing test first, watch it fail, implement,

watch it pass, run full suite, commit. Make this explicit in EVERY executor dispatch.

  • Commit metadata. Author identity, commit message shape, branch.
  • DO NOT modify . Critically important under parallel

batches. See P3 below.

Use the [omh-role:executor] marker in the goal — the OMH plugin auto-injects the executor role prompt via its pre_llm_call hook. Don't inline role text manually.

A full template for the executor goal field — including TDD instructions, sibling-aware DO-NOT-modify discipline, commit metadata, and retry variations for each strike category — is at references/executor-goal-template.md. Adapt the variables; keep the structure.

4. Gather evidence with omh_gather_evidence BEFORE dispatching verifiers

After all executors complete, run the project's actual test/build/lint commands via omh_gather_evidence. This produces a structured {results, all_pass, summary} object the verifier can grade against.

Critical: the verifier does NOT run evidence themselves. Gathering happens at the orchestrator level so you can verify executor claims match reality before the verifier reads them.

Allowlist gotcha. omh_gather_evidence enforces a token-prefix allowlist (~/.hermes/plugins/omh/config.yamlevidence_tool.allowlist_prefixes). Common project test commands like uv run --with pytest --with pyyaml -m pytest do NOT match uv run pytest because --with breaks the prefix. Either:

  • Use the matching prefix: uv run pytest (preferred — keep

pytest as a project dev dep so --with pytest is unnecessary).

  • Add a custom prefix to the OMH config.
  • Wrap with a project-local script.

If gather_evidence rejects your command, the symptom is exit_code: -1, output: "Command not in allowlist". Re-form the command before dispatching the verifier.

5. Dispatch verifiers in parallel (batched per task)

For each completed task, dispatch a verifier subagent with:

  • [omh-role:verifier] marker (auto-injects the verifier role prompt).
  • The task's acceptance criteria (so they grade against the spec, not

the executor's interpretation of it).

  • The full evidence output (the verifier MUST see real test results,

not paraphrased success claims).

  • File paths to inspect.
  • Specific load-bearing checks that go beyond "tests pass" (e.g.,

"verify the mismatched-flag check happens BEFORE any filesystem writes — if not, partial-flag invocations corrupt state").

Verifiers run in parallel via batched delegate_task(tasks=[...]) — same wall-clock savings as Round 2 ralplan reviewers.

The verifier returns one of:

  • APPROVE / PASS — task's passes flag becomes true.
  • REQUEST_CHANGES / FAIL — record verdict, retry executor with the

feedback. Track strikes (see P5 below).

A full template for the verifier goal field — including the acceptance-criteria-verbatim discipline, evidence-paste shape, sibling boundary checks, strike categorization, and worked verdict examples — is at references/verifier-goal-template.md.

Pitfalls (P1–P10)

These are the failure modes that ralph dispatchers stumble into. Numbered for cross-reference; gaps reserved for future additions.

P1 — Plan must be ralph-shaped, not design-shaped

omh-ralplan produces a stance.md — a design document. Ralph needs a task list with testable acceptance criteria.

If you point ralph at a stance directly, the planning gate either parses it weakly (extracting whatever numbered sections look task-shaped) or refuses outright. Translate the stance's MV slice into a proper ralph plan first.

The translation is mechanical:

  • Stance MV-slice items → ralph tasks (one item per task).
  • Stance test affordances → task acceptance criteria (verbatim where

the stance named them).

  • Stance "depends on" prose → task dependencies: field.
  • Stance file paths → task files: list (for parallel-batch

planning).

Author the ralph plan as .omh/plans/ralph-plan.md or .omh/plans/ralplan-.md. Ralph's planning gate finds either.

Worked translation example (from the 2026-04-27 janus run). The stance's "MV slice plan" section listed 13 work items spread across NOW (~3.5h, lineage capture before next provision) / NEXT (+72h, the update tool) / DEFERRED (later releases). The ralph plan landed each item as a task with this shape:

### Task 4 — bin/janus-new-being: version stamp + seed-history snapshot

**Files to modify:**
- `bin/janus-new-being`

**Files to create:**
- `bin/tests/test_janus_new_being_lineage.py`

**Description:**
Patch `bin/janus-new-being` provisioning logic to write lineage data
per the stance's NOW slice item 2. After successful provisioning,
write `/.janus/version`, snapshot rendered template + plugin
tree to `/.janus/seed-history/v1/` via post-write disk-read,
compute MANIFEST with content hashes per file...

**Acceptance criteria (verbatim from stance test affordance):**

    def test_provision_writes_v1_lineage(tmp_path):
        profile = tmp_path / "alice-janus"
        # ... provision invocation ...
        assert (profile / ".janus" / "version").read_text().strip() == "v1"
        seed = profile / ".janus" / "seed-history" / "v1"
        assert (seed / "SOUL.md").exists()
        ...

**Dependencies:** none (Task 5 extends, but doesn't conflict)

The translation discipline that made this work:

  1. Verbatim acceptance criteria from the stance. Where the stance

said test_provision_writes_v1_lineage_and_gh_config passes, the ralph plan used that exact test name. This makes the executor write the test the stance specified, and the verifier grade against the stance's own contract — no drift through paraphrase.

  1. Files-touched are explicit. Each task's files: lists exactly

what gets created and modified. This is what enables parallel- batch planning later (P2): the orchestrator can read the lists and check disjoint touch sets without re-deriving them from the description prose.

  1. **Dependencies are inferred from shared concrete artifacts, not

just prose.** The stance said the MANIFEST shape was authored in Task 4; Task 8 (lib.py with hash_equals_ancestor) needs to read that format. So Task 8's dependencies: [task-4] was inferred from the shared file format, not from a "Task 8 must come after Task 4" sentence.

  1. NOW/NEXT/DEFERRED gets folded into priority ordering. All

NOW-slice tasks get priority: 1 or priority: 2 (with priority-2 reserved for ones that gate later parallel batches). NEXT gets 3-5. DEFERRED items don't appear as ralph tasks at all — they're not part of this run's work envelope.

  1. **Test affordance section per task gets expanded to full pytest

function signatures.** The stance often listed test names with brief shape; the ralph task gives the executor the exact function names + behavior so they don't have to re-derive them.

The translation is its own load-bearing step. Doing it sloppy produces a sloppy run no matter how disciplined the orchestration is afterward. The ralph plan IS the contract executors implement and verifiers grade against; if it's vague, the loop produces vague work.

Budget 30-60 minutes for the translation on a 10+ task plan. The output is the file ralph's planning gate parses; you'll never look at the stance directly again during the run.

P2 — Identify parallel-safe batches before dispatching, not during

Walk all eligible tasks (passes: false + deps met) at the start of each iteration. For each pair, check disjoint-touch-set. Mark the parallel-safe set; dispatch them in one batched delegate_task.

If you wait until after dispatching one task to consider whether others could have run in parallel, you've forfeited the wall-clock savings for that iteration. The right-time-to-decide is at the start of the iteration, when you're already reading state.

Right batch size is 2-4. Two if dependencies are tight; four if multiple independents stack. Five-plus overloads the orchestrator's own context with executor reports + parallel verifier dispatches.

P3 — "DO NOT modify " must be explicit in parallel dispatch contexts

When dispatching parallel executors, only ONE task owns each shared file. The other executors must import (read-only) but not modify it.

Encode this explicitly in each executor's dispatch context:

> DO NOT modify migrations/lib.py during this task — Task X owns that > change. Import what you need; if a function isn't there yet, fall > back to inline implementation that matches Task X's expected > signature so they converge cleanly when both commits land.

Without this instruction, parallel executors race on the shared file and produce conflicting commits. With it, they respect the boundary and commit only their own work.

The instruction should also tell each executor to unstage sibling tasks' files before commit. Otherwise git add -A sweeps in neighbors' uncommitted work — see P9.

P4 — Encode forward-learnings in each executor dispatch

Each iteration produces learnings (gotchas, naming conventions, patterns that worked, patterns that failed). The next iteration's executors do NOT see these unless you encode them.

Maintain a per-iteration learnings list in the ralph state's completed_task_learnings field, and include the relevant subset in each subsequent executor's dispatch context.

Examples worth encoding forward:

  • "TEST-INFRA: never use hash(content) & 0xffff for tmpdir naming

— randomized + small modulus = collision risk."

  • "Use git rm -r (not rm -rf) to preserve git history when

removing tracked files."

  • "bin/janus-new-being uses uv shebang, no .py suffix; new bin/*

scripts should follow the same pattern."

  • "The classify() function in bin/_lineage.py ships the criterion

(path-prefix patterns + Class-B exact set), not enumeration. Reuse it; don't duplicate the taxonomy."

These compress and ride forward via the dispatch context. The omh-ralph state's completed_task_learnings is the canonical store.

P5 — Distinguish executor strikes by category

When the verifier returns REQUEST_CHANGES, the cause is one of:

  1. Test-infra — the test itself is buggy (e.g., a hash() & 0xffff

path collision, a fixture race, a test runner config issue). The implementation may be correct; only the test needs fixing.

  1. Spec-misread — the executor implemented something different

from what the acceptance criteria asked for. Implementation needs correction.

  1. Implementation bug — the executor implemented the right thing

but it has a real defect (logic error, edge case misse

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.