skills/dev-ralph-loop/SKILL.md
This skill should be used when REQUIRED by dev-implement for per-task implementation loops.
npx skillsauth add edwinhu/workflows dev-ralph-loopInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Announce: "I'm using dev-ralph-loop to set up verification loops."
<EXTREMELY-IMPORTANT> ## Load TDD Enforcement (REQUIRED)Before starting ANY ralph loop, you MUST load the TDD skill to remember the testing gates and task reframing:
Read ${CLAUDE_SKILL_DIR}/../../skills/dev-tdd/SKILL.md and follow its instructions.
This loads:
Read dev-tdd skill content now before proceeding with ralph loops. </EXTREMELY-IMPORTANT>
ONE LOOP PER TASK. NOT ONE LOOP PER FEATURE. This is not negotiable.
A single feature-level loop provides ZERO per-task enforcement. You can just move to the next task without the loop actually gating anything.
Each task in PLAN.md gets its own ralph loop with its own completion promise. </EXTREMELY-IMPORTANT>
For task N in PLAN.md (1, 2, 3, ...):
1. Start ralph loop for task N
2. Inside loop: spawn Task agents, iterate until done
3. Output promise → loop ends
4. Move to task N+1, start NEW ralph loop
Why per-task loops?
IMPORTANT: Avoid parentheses () in the prompt - they break zsh argument parsing.
Use dashes or brackets instead.
Skill(skill="ralph-loop:ralph-loop", args="Task N: [TASK NAME] --max-iterations 10 --completion-promise TASKN_DONE")
Skill(skill="ralph-loop:ralph-loop", args="Debug: [SYMPTOM] --max-iterations 15 --completion-promise FIXED")
| Parameter | Purpose | Recommendation |
|-----------|---------|----------------|
| Prompt | What this loop is for | Be specific: "Task 2: Add auth service" |
| --max-iterations | Safety limit | 10 for implementation, 15 for debugging |
| --completion-promise | The completion gate | Unique per task: TASK1_DONE, TASK2_DONE, etc. |
Each iteration follows this pattern:
Task(subagent_type="general-purpose", prompt="""
[TASK-SPECIFIC INSTRUCTIONS]
Context:
- Read .planning/LEARNINGS.md for prior attempts
- Read .planning/SPEC.md for requirements
- Read .planning/PLAN.md for approach
Report back: what was done, results, any blockers.
""")
After Task agent returns:
If complete: Output the promise
<promise>TASKN_DONE</promise>
If incomplete: Do NOT output promise. Spawn another Task agent to continue.
<EXTREMELY-IMPORTANT> ## Promise RulesYou may ONLY output the promise when the statement is COMPLETELY AND UNEQUIVOCALLY TRUE.
The promise is a claim that:
You may NOT output the promise to:
If the promise isn't true, don't output it. Keep iterating. </EXTREMELY-IMPORTANT>
When you output the promise, the ralph loop ends. Then:
- [ ] Task N: Description → - [x] Task N: Description
After outputting a promise, you MUST start the next task within the SAME RESPONSE.
Not "should". Not "recommended". MUST.
| If you're about to... | Instead... | |----------------------|------------| | End your response after a promise | Continue with next task's loop invocation | | Ask "should I continue?" | Just continue | | Summarize progress so far | Save it for when ALL tasks are done | | Wait for user acknowledgment | User doesn't need to acknowledge each task |
The only valid stopping points:
[x] completeFinishing one task is NOT a stopping point. The user is waiting for the FEATURE, not status updates. </EXTREMELY-IMPORTANT>
## Task 1: Create types
Skill(skill="ralph-loop:ralph-loop", args="Task 1: Create types --max-iterations 5 --completion-promise TASK1_DONE")
[Spawn Task agent → implements types]
[Verify: tsc --noEmit passes]
<promise>TASK1_DONE</promise>
[Update PLAN.md: - [ ] Task 1 → - [x] Task 1]
[Log to LEARNINGS.md]
[IMMEDIATELY continue to Task 2 - same response]
## Task 2: Add service method
Skill(skill="ralph-loop:ralph-loop", args="Task 2: Add service method --max-iterations 10 --completion-promise TASK2_DONE")
[Spawn Task agent → implements method]
[Verify: tests fail → iterate]
[Spawn Task agent → fixes tests]
[Verify: tests pass]
<promise>TASK2_DONE</promise>
[Update PLAN.md: - [ ] Task 2 → - [x] Task 2]
[Log to LEARNINGS.md]
[IMMEDIATELY continue to Task 3 - same response]
## Task 3: Add route handler
Skill(skill="ralph-loop:ralph-loop", args="Task 3: Add route handler --max-iterations 10 --completion-promise TASK3_DONE")
[Spawn Task agent → implements route]
[Verify: integration test passes]
<promise>TASK3_DONE</promise>
[Update PLAN.md: - [ ] Task 3 → - [x] Task 3]
[Log to LEARNINGS.md]
## All tasks complete - NOW you can stop
These thoughts mean STOP—you're about to skip enforcement:
| Thought | Reality | |---------|---------| | "One loop for the whole feature" | NO. One loop PER TASK. Feature loops don't enforce. | | "I'll just move to the next task" | Did the current task's loop complete? If no loop, no gate. | | "Per-task loops are overhead" | Per-task loops are the ONLY enforcement. | | "Ralph is for hard problems" | Ralph is for ALL tasks. Simple tasks need gates too. | | "I'll iterate without the loop" | Without ralph, you'll declare done prematurely. | | "The ceremony isn't worth it" | The ceremony IS the value. It prevents shortcuts. | | "I'll cherry-pick the parts I need" | Skills are protocols, not menus. Follow all of it. | | "Tests passed on first try, skip loop" | Still need the loop structure. Lucky ≠ verified. | | "Task done, let me check in" | NO. Update PLAN.md, then start next task immediately. | | "User might want to review" | User wants ALL tasks done. Keep going. | | "Natural pause point" | Only pause when ALL tasks complete. | | "I'll update PLAN.md later" | NO. Update it NOW, right after the promise. | | "PLAN.md is just documentation" | PLAN.md is the source of truth. Keep it current. | | "Should I continue?" | YES. Don't ask. Just continue to the next task. |
Each task needs its own ralph loop. One feature loop provides ZERO per-task enforcement.
After outputting a promise: (1) Update PLAN.md, (2) Log to LEARNINGS.md, (3) Start next task's loop. All in the same response.
Ralph loops are for:
Ralph loops are NOT for:
For tasks that produce rendered visual output (slides, charts, UI), use visual-verify instead of a plain ralph loop. Visual-verify wraps the ralph-loop pattern with render → look-at → fix steps:
Read ${CLAUDE_SKILL_DIR}/../../skills/visual-verify/SKILL.md and follow its instructions.
This skill is invoked by:
dev-implement - for standard implementation tasksdev-debug - for bug investigation and fixesvisual-verify - wraps ralph-loop for visual output tasksAfter all tasks complete, proceed to the next phase of the parent workflow.
development
Build the meeting-level proxy-voting × ownership panel on the WRDS SGE grid — ISS N-PX fund votes reduced to (item × block) direction cells, joined to institutional and mutual-fund ownership. Use when working with risk.voteanalysis_npx, N-PX fund-level votes, ISS→CRSP fund linking, index/passive/active voting blocks, or a proxy-voting panel that needs ownership attached.
development
Use when "CRSP CIZ", "CRSP v2", "CRSP flat file format 2.0", "crsp.dsf_v2 / msf_v2", "StkDlySecurityData", "StkMthSecurityData", "StkSecurityInfoHist", "stocknames_v2", "DlyRet / MthRet / DlyPrc / MthPrc", "SHRCD or EXCHCD equivalent in new CRSP", "SIZ to CIZ migration", "CRSP data after 2024", "CRSP delisting returns", "CRSP cumulative adjustment factors", "CRSP index INDNO / INDFAM", or any CRSP stock/index query where the legacy SIZ column names no longer exist.
development
Use when linking or deduping datasets by entity name rather than a shared key — 'fuzzy match', 'fuzzy name matching', 'entity resolution', 'record linkage', 'match company/person names', 'dedupe entity names', 'name-based join', 'bridge identifiers' (CIK ↔ permno ↔ gvkey ↔ wficn ↔ EIN ↔ personid), or any use of char n-gram TF-IDF, cosine similarity on names, `sparse_dot_topn`, or RapidFuzz at scale.
development
Use when building a publication-quality table in Python — 'regression table', 'results table', 'summary statistics table', 'etable', 'coefplot', 'great_tables', 'GT', 'gt table', 'format a table for the paper', 'export table to LaTeX/HTML', significance stars, spanners, or column formatting for a table headed into a paper, slide deck, or notebook.