Agent skill
ralph-worker
Worker loop - execute tasks assigned by coordinator
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/data/shared-ralph-worker
SKILL.md
Ralph Worker
You are a worker in a multi-session Ralph Wiggum system. The PM coordinator assigns tasks, and you execute them.
On EVERY cycle, check coordinator status FIRST:
// Read prd.json.session
{
"status": "running|completed|terminated|max_iterations_reached"
}
If status is completed, terminated, or max_iterations_reached:
- Update your status to
"exiting" - Log exit reason to handoff-log.json
- Output:
<promise>WORKER_EXIT</promise> - Stop polling
If status is running: Continue normal polling loop.
Initialization (Auto-Created on First Run)
On your FIRST iteration only, automatically create the session directory:
mkdir -p .claude/session
If prd.json.session doesn't exist, wait for coordinator to create it.
Do NOT create prd.json.session yourself - the coordinator owns it.
You may update prd.json.items[{taskId}] fields you own (agent status updates via prd.json.agents.{your-agent}) but the coordinator creates the session.
Determine Your Agent Type
Check the --agent argument:
⚠️ MANDATORY: Skill Check Before Work
After reading the task from prd.json.items[{taskId}] and BEFORE starting implementation:
1. Read task requirements (category, description, files)
2. Check if task category matches a known skill
3. If skill exists, invoke it via Skill tool FIRST
4. Only start implementation after skill guidance complete
⚠️ You are FORBIDDEN from starting implementation without checking for relevant skills first.
Initialization
-
Wait for coordinator:
- Poll every 20 seconds for
prd.json.sessionto exist - If missing, log "Waiting for coordinator..." and continue waiting
- Poll every 20 seconds for
-
Register your presence:
- Update
agents.{your-agent}.lastSeento current timestamp - Update
agents.{your-agent}.statusto "waiting"
- Update
IDLE BEHAVIOR (What To Do When No Work Assigned)
When you have NO assigned task:
-
Update your heartbeat (MANDATORY - every 30 seconds):
json{ "agents": { "{{AGENT}}": { "lastSeen": "{{NOW}}", "status": "idle" } } } -
POLL AGAIN - read prd.json.session
-
Wait 30 seconds
-
Repeat forever until coordinator terminates
IMPORTANT: Once you receive a task assignment, focus on the work. You do NOT need to poll for new tasks while working, but you MUST still update your heartbeat periodically (see below).
Single Source of Truth (prd.json)
You update YOUR status in prd.json. PM controls task status.
What You Update
Update prd.json.agents.{your-agent} with your current state:
status- idle, working, awaiting_pmlastSeen- Auto-timestampcurrentTaskId- What task you're working on
What PM Controls
items[{taskId}].status- PM updates this based on your messagesitems[{taskId}].passes- PM updates this based on QA validation
When to Update Your Status
| Situation | Your Status (examples) |
|---|---|
| Start working on task | status: "working", currentTaskId: "{taskId}" |
| Complete work | status: "idle", currentTaskId: null |
| Need PM help | status: "awaiting_pm" |
| Waiting for task | status: "idle" |
Update Pattern
When you start working:
{
"agents": {
"developer": {
"status": "working",
"currentTaskId": "feat-001",
"lastSeen": "{{ISO_TIMESTAMP}}"
}
}
}
When you complete work:
{
"agents": {
"developer": {
"status": "idle",
"currentTaskId": null,
"lastSeen": "{{ISO_TIMESTAMP}}"
}
}
}
Message System (Unchanged)
After updating your status in prd.json, still send messages:
implementation_complete→ PM sets task to "ready_for_qa"bug_report→ PM sets task to "needs_fixes"
Working State: Keep Heartbeat Fresh
When you are actively working on a task:
You MUST update your heartbeat periodically:
- When you START working → Update heartbeat with
status: "working" - Every 60 seconds while working → Quick heartbeat update only
- When you COMPLETE work → Update heartbeat with
status: "idle"
Quick Heartbeat Update (takes 10 seconds):
- Read prd.json
- Update
prd.json.agents.{your-agent}.lastSeento current timestamp - Write back to prd.json
- Continue working
DO NOT skip this - PM needs to know you're alive! Without heartbeat updates, PM will think you disconnected.
Example:
// Before starting work
{ "agents": { "developer": { "status": "working", "lastSeen": "2026-01-19T12:30:00Z" } } }
// After 60 seconds of working (quick update)
{ "agents": { "developer": { "status": "working", "lastSeen": "2026-01-19T12:31:00Z" } } }
// After completing work
{ "agents": { "developer": { "status": "idle", "lastSeen": "2026-01-19T12:45:00Z" } } }
Main Loop (Run Continuously)
Poll every 30 seconds when idle:
Context Window Management
CRITICAL: You MUST automatically reset your context when reaching ~70% capacity to maintain performance.
Detection Guidelines:
- After large chunks of work, check your context using the task "/context"
- If is closer to ~70% run the reset procedure
Reset Procedure (AUTOMATIC - no approval needed):
- Read and save current prd.json state
- Run "/compact" task
- The stop-hook will detect this and continue with fresh context
State to Preserve Before Reset:
- Read
prd.json.sessionto understand current session state - Note your current task (if any) to resume after reset
After Reset:
- Re-read prd.json
- Continue polling from where you left off
- Do NOT repeat completed work
Main Loop (Detailed Steps)
-
Update your heartbeat:
json"agents": { "{{AGENT}}": { "lastSeen": "{{NOW}}" } } -
Read coordinator state:
- Parse
prd.json.session - Check if
statusis "terminated", "completed", or "max_iterations_reached" - If yes, exit gracefully
- Parse
-
Check for work based on your agent type
After completing each iteration, START OVER FROM STEP 1. POLL AGAIN. DO NOT STOP.
Atomic File Updates
Always update state files atomically:
# Read, modify, write atomically
STATE=$(cat prd.json)
# Use jq for JSON manipulation
NEW_STATE=$(echo "$STATE" | jq '.agents.developer.status = "working"')
# Write atomically
echo "$NEW_STATE" > prd.json.tmp
mv prd.json.tmp prd.json
If any of these, exit gracefully:
- Log "Session {{status}}. Exiting worker loop."
- Do NOT start new work
- Finish current task if in progress
Handoff Logging
Each handoff should be logged to .claude/session/handoff-log.json:
{
"handoffs": [{
"timestamp": "{{ISO_TIMESTAMP}}",
"from": "developer",
"to": "qa",
"task": "{{PRD_ID}}",
"reason": "ready_for_validation",
"iteration": {{N}}
}]
}
Quality Standards
This codebase will outlive you. Every shortcut you take becomes someone else's burden. Every hack compounds into technical debt that slows the whole team down.
Error Recovery
If coordinator state file is corrupted:
- Log error
- Wait for coordinator to recover
- Continue polling
If you can't complete a task:
- Document what you tried in your agent-specific progress file
- Set task status to "needs_fixes" with bug notes
- Don't block - return to waiting state
Didn't find tool you were looking for?