ralph-review-deep について
ralph-review-deepはRalphのファイルとbdグラフを検証し、opencodeで3つの独立したモデルレビューを並行実行するスキルです。単一サブエージェントを使うralph-reviewとは異なり、複数モデルでの確認を行います。
主な機能
- 01必要ファイルとbdグラフの検証
- 023モデルによるレビューの並行実行
- 03モデルごとのレビュー文書を作成
- 04進行状況、費用、エラーの追跡
- 05確認用ログの保持
活用シーン
- 01Ralph計画の独立したレビューを比較
- 02グラフ検証結果と計画の欠陥を確認
- 03モデル実行状況とログの調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jimweller/ clanker-skills --skill ralph-review-deepインストール後、Claude Code で/ralph-review-deepを入力して読み込まれたか確認します。
詳細
STARTER_CHARACTER = 🔬
Ralph Review(詳細)
beads グラフを検証し、異なるモデルを使って opencode run 経由で ralph の成果物を3つの独立したレビューで並行して実行します。各モデルは、目標の明確さ、タスクの分割、順序付け、計画の完全性、リスクと不足点、実現可能性を評価したレビュー ファイルを1つ作成します。
内部サブエージェントを使った、より高速な単一モデルのレビューには、代わりに ralph-review スキル(/ralph-review、$ralph-review)を使ってください。この詳細版は、レビューにかかる時間とコストを、複数モデル間の合意と引き換えにします。
モデル
| ラベル | モデル ID |
|---|---|
| openai | openai/gpt-5.5 |
| gemini | google/gemini-3.1-pro-preview |
| claude | az-anthropic/claude-opus-4-6 |
手順
ステップ 1:成果物の存在を確認する
PROJECT_ROOT=$(git rev-parse --show-toplevel)
以下がすべて存在することを確認します。
$PROJECT_ROOT/.llmtmp/ralph-plan.md$PROJECT_ROOT/.llmtmp/ralph-prompt-insession.md$PROJECT_ROOT/.llmtmp/ralph-prompt-external.md$PROJECT_ROOT/.beads/(ディレクトリ。bd 対応の確認にはbd list >/dev/null 2>&1を使用)
いずれかが存在しない場合は中止します。
ステップ 2:bd グラフを検証する
opencode を起動する前に、以下のチェックを実行します。ここでの失敗は重大度 HIGH の指摘事項であり、中止するか、明確に警告する必要があります。
bd グラフは、実行ごとのエピック配下に整理されています。スラッグは現在のブランチから導出され、エピックは ralph:<slug> ラベルを使って特定します。対象範囲を絞るすべてのチェックでは --parent ${EPIC} でフィルターします。
cd "$PROJECT_ROOT"
SLUG=$(git branch --show-current | tr '/' '-')
# 1. Single open epic for this run
EPIC_COUNT=$(bd list -t epic -l "ralph:${SLUG}" --json 2>/dev/null | jq '[.[] | select(.status=="open")] | length')
if [[ "$EPIC_COUNT" -ne 1 ]]; then
echo "HIGH: expected exactly one open epic with label ralph:${SLUG}, found ${EPIC_COUNT}"
fi
EPIC=$(bd list -t epic -l "ralph:${SLUG}" --json 2>/dev/null | jq -r '[.[] | select(.status=="open")] | .[0].id // empty')
# 2. Cycles
if ! bd dep cycles >/dev/null 2>&1; then
echo "HIGH: bd graph has dependency cycles"
bd dep cycles
fi
# 3. Minimum child count under the run epic
COUNT=$(bd list --parent "$EPIC" --json 2>/dev/null | jq 'length')
if [[ "$COUNT" -eq 0 ]]; then
echo "HIGH: run epic ${EPIC} has no child tasks"
fi
# 4. At least one ready task under the run epic
READY_COUNT=$(bd ready --parent "$EPIC" --json 2>/dev/null | jq 'length')
if [[ "$READY_COUNT" -eq 0 && "$COUNT" -gt 0 ]]; then
echo "HIGH: run epic ${EPIC} has tasks but no ready tasks (deadlock or all closed unexpectedly)"
fi
# 5. Isolated nodes within the run epic
if [[ "$COUNT" -gt 1 ]]; then
bd list --parent "$EPIC" --json 2>/dev/null \
| jq -r '.[] | select(.dependency_count == 0 and .dependent_count == 0) | "MEDIUM: isolated task " + .id + " " + .title'
fi
# 6. Description coverage: every child carries the worker's instructions
bd list --parent "$EPIC" --json 2>/dev/null \
| jq -r '.[] | select(((.description // "") | length) == 0) | "HIGH: task " + .id + " has empty description: " + .title'
# 7. Parent set equals label set (defense-in-depth orphan detection)
PARENT_IDS=$(bd list --parent "$EPIC" --json 2>/dev/null | jq -r '.[].id' | sort)
LABEL_IDS=$(bd list --label "ralph:${SLUG}" --json 2>/dev/null | jq -r '.[] | select(.issue_type != "epic") | .id' | sort)
if [[ "$PARENT_IDS" != "$LABEL_IDS" ]]; then
echo "HIGH: parent set (--parent ${EPIC}) and label set (--label ralph:${SLUG} excluding epic) differ"
echo "Parent-only (label missing): $(comm -23 <(echo "$PARENT_IDS") <(echo "$LABEL_IDS"))"
echo "Label-only (orphan, parent missing): $(comm -13 <(echo "$PARENT_IDS") <(echo "$LABEL_IDS"))"
fi
これらの指摘事項を保存してください。レビュー担当者は最終レポートで参照します。
ステップ 3:以前のレビューをクリーンアップする
rm -f "$PROJECT_ROOT"/.llmtmp/ralph-review-openai.md \
"$PROJECT_ROOT"/.llmtmp/ralph-review-gemini.md \
"$PROJECT_ROOT"/.llmtmp/ralph-review-claude.md
ステップ 4:ファイルを読み込み、プロンプトのコンテキストを作成する
以下のファイルの内容を連結して、単一の CONTEXT 文字列を作成します。
.llmtmp/ralph-plan.md.llmtmp/ralph-prompt-insession.md.llmtmp/ralph-prompt-external.md- ステップ 2 で解決したスラッグとエピック ID(リテラルラベル
SLUG=...およびEPIC=...) bd list --parent "$EPIC" --jsonの出力bd ready --parent "$EPIC" --jsonの出力bd list --label "ralph:${SLUG}" --jsonの出力- ステップ 2 の bd グラフ検証で得た指摘事項
- 計画の
plan documents:行に記載された計画ドキュメント。行を解析し、カンマで分割して空白を削除し、各パスを読み込みます。レビュー担当者がベースラインと区別できるよう、それぞれを=== plan-documents/<path> ===で囲みます。値が空の場合、読み込む計画ドキュメントはありません。 - プロジェクトルートにある
CLAUDE.mdとREADME.md(存在する場合) .llmdocs/内のすべての.mdファイル
各項目を次のように囲みます。
=== <relative-path or label> ===
<contents>
ステップ 5:レビュープロンプトを作成する
各 opencode プロセスが実行するプロンプトを作成します。<PROJECT_ROOT> と <CONTEXT> を置き換えます。
PROMPT="You are a plan reviewer running headless in a non-interactive session. There is no user present. Do not ask questions. Do not prompt for confirmation. Do not stop to wait for input.
YOUR PRIMARY OBJECTIVE IS TO WRITE A FILE. Everything else is preparation. After completing your review, your VERY NEXT action must be a tool call that writes the output file. Do not summarize, do not reflect, do not plan — write the file immediately.
OUTPUT RULES: You are running headless. Nobody reads your text responses. ALL review content goes exclusively into the output file via tool calls. Any text you generate outside of a tool call is wasted tokens and risks hitting the output token limit before you can write the file. Keep text responses to one short sentence at most.
PROJECT_ROOT: <PROJECT_ROOT>
## Context
<CONTEXT>
## How Ralph Loops Work
A ralph loop is an autonomous, iterative execution mechanism. Two execution modes share the same artifacts:
- **In-session (ralph-loop plugin)**: a Stop hook re-feeds the prompt to the same Claude session. Cheap on short runs; expensive on long runs because context grows quadratically.
- **External (scripts/ralph.sh)**: a bash while-loop spawns a fresh `claude --print` per iteration. Higher fixed overhead per iteration; stays in the cheap part of the cost curve indefinitely.
Authority sources in CONTEXT:
The CONTEXT contains two distinct authority categories. Treat them differently.
- **Plan documents** (under `=== plan-documents/...` blocks): forward-looking intent the planner consulted, e.g., a PRD, a Jira ticket, a design note. The plan must faithfully render these. Flag the plan if it omits, contradicts, or stale-references a requirement from a plan document.
- **Baseline docs** (`CLAUDE.md`, `README.md`, `.llmdocs/*`): the system's current state. The plan's job is to change this state. Do NOT flag the plan for deviating from baseline. Flag only if the plan changes baseline without including a corresponding docs-update bead (typically delegated to the docs skill).
Mechanics that apply to both modes:
- The bd graph is the state machine. The graph is shared across worktrees of the same repo. Each ralph run is organized under a per-run epic so concurrent runs in different worktrees stay isolated by `--parent` filtering. `bd ready --parent <epic> --json` finds the next unblocked task within this run.
- The run epic carries the label `ralph:<slug>` where `<slug>` is derived from the current branch. Every child task carries both `--parent <epic>` and the same `ralph:<slug>` label. The two signals are independent so the reviewer can detect orphans.
- The plan's "Run Identity" section records the literal slug and epic ID. The agent reads them directly from the plan each iteration, no derivation.
- One task per iteration. The agent reads `bd ready --parent <epic> --json`, takes the first result, runs the per-task workflow, then closes the task.
- When the ready queue is empty, the agent closes the epic and emits the sentinel as the terminal action. The epic is not closed by `bd` automatically.
- Resumable. A partially-completed graph resumes cleanly. Partial completion is normal; iterations are cheap.
- Every action is a bd task, including ralph lifecycle scaffolding. The branch creation, BEGIN tag, code work, docs, and END tag are all first-class beads, all parented to the run epic.
- Each bead carries its full per-task instructions in its description: files to touch, expected behavior, verification command, commit message. The worker reads `bd show <id>` and executes the description exactly.
- Run-wide conventions (commit style, language, build command, test command) live in `ralph-plan.md`, not in every description.
- Environment is a precondition. Credentials, network, toolchain, and runtime dependencies are the operator's responsibility. Do not flag missing environment setup as a gap.
Do NOT recommend: collapsing tasks into bundles, adding environment preflight checks, treating partial completion as a risk, modifying the prompt body, replacing the bd graph with a markdown checklist, or reintroducing a workflow-label taxonomy. The `ralph:<slug>` label is run-identity for partition and orphan detection, not workflow dispatch; do not flag it as a label taxonomy.
Flag as HIGH severity if: zero or more than one open epic exists for `ralph:<slug>`; any open child has an empty description; the bd graph contains cycles; the run epic has no children; the run epic has children but no ready tasks; the parent set under the epic differs from the label set for `ralph:<slug>` (orphans or planning typos); the per-task workflow does not explicitly stop after `bd close` (the agent will do multiple beads in one context, defeating the Ralph design); the per-task workflow does not close the epic before emitting the sentinel; the plan lacks a "Run Identity" section recording the literal slug and epic ID; the plan lacks an "Inputs" section with a `plan documents:` line; the plan omits or contradicts a material requirement explicit in any plan document; the plan's Approach prose declares an ordering ("X first", "after Y") that the bd dependency edges do not enforce. Flag as MEDIUM if: a description omits the verification command or commit message; an isolated task exists in a multi-task graph; the plan duplicates information that already lives in bead descriptions; a bead that touches README.md/CLAUDE.md/.llmdocs/ authors edits inline instead of running the docs skill.
## Your Task
Review the Ralph artifacts:
- ralph-plan.md (mode-neutral execution plan)
- ralph-prompt-insession.md (slash-command wrapper for the in-session driver)
- ralph-prompt-external.md (body for scripts/ralph.sh)
- The bd graph (issues, dependencies, ready/closed state)
Evaluate across these areas:
### 1. Goal Clarity
- Is the objective well-defined and unambiguous?
- Would a fresh-context iteration understand what success looks like from the plan alone?
### 2. Task Decomposition
- Are tasks the right granularity (one focused deliverable each)?
- Is each task independently completable?
- Are there missing tasks needed to achieve the goal?
- Are there unnecessary or redundant tasks?
- Do titles name deliverables rather than techniques?
- Do descriptions carry enough detail (files, verification, commit message) for a cold-start worker?
### 3. Sequencing and Dependencies
- Are dependencies correct in the bd graph?
- Would executing in `bd ready --json` order produce correct results?
- Are there implicit dependencies that should be explicit edges?
- Are there cycles or isolated nodes?
### 4. Plan Completeness
- Do the instructions cover repo-specific conventions, tools, and commands?
- Are build, test, and lint commands accurate?
- Is the per-task workflow clear (read description, execute it, close)?
- Does the plan have a "Run Identity" section that records the literal branch slug, the literal epic ID, and the epic label `ralph:<slug>`?
- Does the Per-Task Workflow read the epic ID from the "Run Identity" section and scope `bd ready` with `--parent <epic-id>`?
- Does the Per-Task Workflow close the epic via `bd close <epic-id>` before emitting the sentinel when the ready queue is empty?
- Does the Per-Task Workflow explicitly say STOP after `bd close` so the agent does not loop within a single context?
- Does the Git Workflow section require a `ralph/` feature branch and BEGIN/END tags?
- Is the Per-Task Workflow explicit that `bd close` for the current task runs BEFORE the sentinel?
- Do beads that touch `README.md`, `CLAUDE.md`, or `.llmdocs/` invoke the docs skill (/docs, $docs) rather than authoring edits inline?
### 5. Risk and Gaps
- What could go wrong during autonomous execution?
- Are there tasks that require human judgment or external access?
- Could any task leave the repo in a broken state?
### 6. Feasibility
- Can a single iteration realistically complete each task?
- Are there tasks that exceed what a fresh context can do autonomously?
For each area, list specific findings with severity (high/medium/low) and actionable recommendations.
## Output
Your VERY NEXT action after the review must be a tool call that writes the file. No intermediate steps.
Determine your model label:
- Claude variants: claude
- GPT variants: openai
- Gemini variants: gemini
Write to `<PROJECT_ROOT>/.llmtmp/ralph-review-$MODEL_LABEL.md` using this template:
\`\`\`markdown
# Ralph Loop Review
**Model**: <MODEL_LABEL>
## Goal Clarity
- **[medium]** Short title. Explanation...
## Task Decomposition
- **[high]** Short title. Explanation...
## Sequencing and Dependencies
- **[medium]** Short title. Explanation...
## Plan Completeness
- **[low]** Short title. Explanation...
## Risk and Gaps
- **[high]** Short title. Explanation...
## Feasibility
- **[medium]** Short title. Explanation...
## Summary
<overall assessment and top 3 recommendations>
\`\`\`
Finding format: \`- **[severity]** Title. Description.\`
Every section must be present. If no findings for an area, write 'No findings.' under its heading.
Then verify: \`ls -la '<PROJECT_ROOT>/.llmtmp/ralph-review-<MODEL_LABEL>.md'\`
If the file does not exist, write it again. Do not exit without the file."
ステップ 6:プロンプトをファイルに書き込む
大きなプロンプトでシェルによる展開の問題が発生しないようにします。
STATE_DIR="$PROJECT_ROOT/.llmtmp/ralph_review_state"
mkdir -p "$STATE_DIR"
OPENAI_DIR=$(mktemp -d)
GEMINI_DIR=$(mktemp -d)
CLAUDE_DIR=$(mktemp -d)
cat > /tmp/ralph-review-prompt.txt <<'PROMPT_EOF'
<the prompt from Step 5>
PROMPT_EOF
ステップ 7:独立したバックグラウンド Bash タスクを3つ起動する
各 opencode プロセスは、それぞれ独立したバックグラウンド Bash タスクとして実行する必要があります。単一のシェル内で & を使って連結しないでください。親プロセスが終了すると、子プロセスも終了します。
OpenAI:
STATE_DIR="<PROJECT_ROOT>/.llmtmp/ralph_review_state" && \
opencode run \
-m openai/gpt-5.5 \
--format json \
--print-logs \
--log-level INFO \
--dir "<OPENAI_DIR>" \
--title "Ralph Review - OpenAI" \
"$(cat /tmp/ralph-review-prompt.txt)" \
> "$STATE_DIR/openai.ndjson" 2>"$STATE_DIR/openai.log"
Gemini:
STATE_DIR="<PROJECT_ROOT>/.llmtmp/ralph_review_state" && \
opencode run \
-m google/gemini-3.1-pro-preview \
--format json \
--print-logs \
--log-level INFO \
--dir "<GEMINI_DIR>" \
--title "Ralph Review - Gemini" \
"$(cat /tmp/ralph-review-prompt.txt)" \
> "$STATE_DIR/gemini.ndjson" 2>"$STATE_DIR/gemini.log"
Claude:
STATE_DIR="<PROJECT_ROOT>/.llmtmp/ralph_review_state" && \
opencode run \
-m az-anthropic/claude-opus-4-6 \
--format json \
--print-logs \
--log-level INFO \
--dir "<CLAUDE_DIR>" \
--title "Ralph Review - Claude" \
"$(cat /tmp/ralph-review-prompt.txt)" \
> "$STATE_DIR/claude.ndjson" 2>"$STATE_DIR/claude.log"
3つすべてを独立したバックグラウンドタスクとして起動します。単一のシェル内で & を使わないでください。
出力ストリーム
各 opencode プロセスは、2つの出力ファイルを生成します。
<label>.ndjson(標準出力):--format jsonによる構造化 NDJSON イベントです。プログラムによる進捗追跡に使用します。<label>.log(標準エラー出力):プレーンテキストの情報レベルのログです。起動失敗、権限の問題、MCP サーバーのエラー、プラグインの読み込みを診断する際に使用します。
ログ行は、1行ごとに構造化テキストで記録されます。
INFO 2026-03-13T00:54:25 +4ms service=default directory=/private/tmp creating instance
ステップ 8:監視して完了を待つ
3つすべてが完了するまで、各バックグラウンドタスクをポーリングします。
NDJSON の進捗($NDJSON を実際のパスに置き換えます):
# Count completed steps
grep -c '"type":"step_finish"' "$NDJSON" 2>/dev/null || echo 0
# Check if done (last step_finish has reason "stop")
tail -1 "$NDJSON" 2>/dev/null | jq -r '.part.reason // empty'
# Check for errors
grep '"type":"error"' "$NDJSON" 2>/dev/null
テキストログ($LOGFILE を実際のパスに置き換えます):
# Errors or warnings
grep -E "^(ERROR|WARN)" "$LOGFILE" 2>/dev/null
# Recent activity
tail -5 "$LOGFILE" 2>/dev/null
ステップ 9:結果の報告
各モデルについて、.llmtmp/ralph-review-<label>.md が存在するか確認します。
モデルごとに以下を報告します。
- 成功または失敗(ファイルの有無)
- 合計コスト:すべての
step_finishイベントのcostの合計 - エラーが発生したかどうか
レポートの冒頭で、ステップ 2 の bd グラフ検証結果を別途提示します。
ステップ 10:クリーンアップ
実行後の調査に備えて状態ディレクトリを保持します(モデルごとの NDJSON イベントストリームとテキストログは、レビューの失敗、キャリブレーションの後退、コストの推移を診断する際に役立ちます)。
rm -f /tmp/ralph-review-prompt.txt
$STATE_DIR(.llmtmp/ralph_review_state/)は意図的に削除しません。以降のレビュアー実行では、モデルごとのファイルがその場で上書きされます。過去のデータを保持する必要がある場合は、再実行する前にディレクトリをアーカイブしてください。
予想される出力ファイル
合計 3 ファイル(モデルごとに 1 ファイル):
.llmtmp/ralph-review-openai.md.llmtmp/ralph-review-gemini.md.llmtmp/ralph-review-claude.md
NDJSON ログ形式のリファレンス
各 opencode プロセスは $STATE_DIR/<label>.ndjson に NDJSON を書き込みます。1 行につき JSON オブジェクトが 1 つです。解析に失敗する行(部分的な書き込み)はスキップします。
主なイベントタイプ:
- step_start - 新しい LLM ターンが始まります。
- text - モデルがテキストを出力しました:
{"type":"text","part":{"text":"..."}} - tool_use - ツール呼び出し:
{"type":"tool_use","part":{"tool":"bash","state":{"status":"completed","metadata":{"exit":0}}}} - step_finish - ターンが完了しました:
{"type":"step_finish","part":{"reason":"stop","cost":0,"tokens":{"total":13494}}}。reason: "stop"= 完了、reason: "tool-calls"= 継続中。 - error - セッションエラー:
{"type":"error","error":{"data":{"message":"..."}}}
便利な jq クエリ($NDJSON を実際のパスに置き換えます):
NDJSON="<PROJECT_ROOT>/.llmtmp/ralph_review_state/openai.ndjson"
# Is done?
tail -1 "$NDJSON" | jq -r 'select(.type=="step_finish") | .part.reason'
# Total cost
jq -s '[.[] | select(.type=="step_finish") | .part.cost] | add' "$NDJSON"
# All errors
jq -r 'select(.type=="error") | .error.data.message' "$NDJSON"
$LOGFILE をテキストログのパスに置き換えます。
grep -E "^(ERROR|WARN)" "$LOGFILE"
ルール
- 呼び出し元のエージェントはランチャーとしてのみ動作します。すべてのレビュー作業は opencode プロセス内で行います。
- レビュー分析を直接行わないでください。レビューは opencode プロセスが実行します。
- 実行中に質問しないでください。これは非対話型です。
- 3 つのプロセスをすべて並行して起動します。1 つが完了するのを待ってから次を起動してはいけません。
--commandではなく、プレーンなメッセージ呼び出しを使用します。--commandフラグには context7 MCP サーバーとの既知の問題があります。- 結果を報告した後も状態ディレクトリを保持します。NDJSON ファイルとログファイルは、実行後の調査に使用できるよう残しておきます。
- あるモデルが失敗しても、残りのモデルを待って結果を報告します。
- ステップ 2 の bd グラフ検証は、opencode ではなく呼び出し元のエージェントが実行します。検証結果はコンテキストとして opencode のレビュアーに渡されます。