Skip to content

Instantly share code, notes, and snippets.

@micahstubbs
Created January 20, 2026 21:01
Show Gist options
  • Select an option

  • Save micahstubbs/e51c7be727851a669f9ffac71d87d4e3 to your computer and use it in GitHub Desktop.

Select an option

Save micahstubbs/e51c7be727851a669f9ffac71d87d4e3 to your computer and use it in GitHub Desktop.
GRIND - Autonomous beads issue processor skill for Claude Code with stop hook
#!/bin/bash
# Grind Stop Hook - Reminds about remaining ready issues when session ends
# Non-blocking: just outputs a message, always exits 0
READY_COUNT=$(bd ready -n 1 --json 2>/dev/null | jq -r "length // 0" 2>/dev/null)
READY_COUNT=${READY_COUNT:-0}
if [ "$READY_COUNT" -gt 0 ] 2>/dev/null; then
echo "GRIND MODE: $READY_COUNT ready issues remain. Run /grind to continue."
fi
exit 0
name description
grind
Autonomously work through ALL open beads issues until totally blocked or backlog empty. Creates blocker issues for human intervention. No stopping.

GRIND - Autonomous Issue Processor

YOU ARE AN AUTONOMOUS AGENT. WORK UNTIL YOU CANNOT WORK ANYMORE.

This skill executes a relentless, recursive loop through all beads issues until either:

  1. Zero ready issues remain
  2. All remaining work requires human intervention

MANDATORY EXECUTION PROTOCOL

PHASE -1: INSTALL GRIND STOP HOOK (IF NOT EXISTS)

First, ensure a project-level stop hook exists to continue grinding:

Check if the grind stop hook already exists:

ls -la .claude/settings.local.json 2>/dev/null

If the file exists, check if it contains a grind stop hook. If not, or if the file doesn't exist, create/update the hook configuration.

Create the stop hook configuration:

mkdir -p .claude

# Check if settings.local.json exists and has hooks
if [ -f .claude/settings.local.json ]; then
  # Backup existing file
  cp .claude/settings.local.json /tmp/settings.local.json.backup.$(date +%Y%m%d-%H%M%S)
fi

Write the grind stop hook to .claude/settings.local.json:

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'READY_COUNT=$(bd ready -n 1 --json 2>/dev/null | jq -r \"length // 0\" 2>/dev/null); READY_COUNT=${READY_COUNT:-0}; if [ \"$READY_COUNT\" -gt 0 ] 2>/dev/null; then echo \"GRIND MODE: $READY_COUNT ready issues remain. Run /grind to continue.\"; fi; exit 0'",
            "timeout": 10000
          }
        ]
      }
    ]
  }
}

What this hook does:

  • Triggers when Claude tries to stop/end the session
  • Checks if there are ready beads issues (bd ready)
  • If issues remain, outputs a reminder message (non-blocking)
  • Always exits with code 0 (success) - uses plain text, not JSON
  • Handles edge cases: empty READY_COUNT defaults to 0, suppresses comparison errors

Key fixes from debugging:

  • Added READY_COUNT=${READY_COUNT:-0} to handle empty jq output
  • Added 2>/dev/null to suppress bash comparison errors
  • Explicit exit 0 ensures success exit code
  • Removed JSON output format (plain text works for informational hooks)

Important: If the project already has hooks in .claude/settings.local.json, merge the grind stop hook into the existing Stop array rather than overwriting.

Verification:

cat .claude/settings.local.json | jq '.hooks.Stop'

PHASE 0: INVOKE /NEXT SKILL FIRST

BEFORE any work, call the /next skill to get properly prioritized recommendations:

/next

This ensures:

  • bd mail is checked for work claimed by other agents
  • Blocked issues are identified and excluded
  • Issues are scored by session relevance, readiness, and impact
  • Agent coordination is respected (no duplicate work)

Only after /next completes should you proceed to Phase 1.

PHASE 1: TRIAGE (VERIFY AND EXPAND)

Verify /next results and get additional context:

bv --robot-triage | jq '.quick_ref'
bd ready -n 50
bd mail inbox                    # Check for agent coordination messages

If NO issues are ready, check why:

bd blocked
bd list --status=open

If all issues are blocked by external dependencies or require human input, CREATE A BLOCKER ISSUE for each distinct blocker, then STOP.

PHASE 2: THE GRIND LOOP

EXECUTE THIS LOOP UNTIL EXHAUSTION:

WHILE (bd ready returns issues):
    1. GET top ready issue
    2. CLAIM it immediately
    3. IMPLEMENT it completely
    4. CLOSE it with commit reference
    5. SYNC beads
    6. REPEAT - NO PAUSING, NO ASKING, NO HESITATION

PHASE 3: HANDLING BLOCKERS

When you encounter something you CANNOT do:

IMMEDIATELY create a blocker issue:

bd create --title="BLOCKER: <what is needed>" --type=task --priority=1 --label=needs-human
bd dep add <blocked-issue-id> <new-blocker-id>

Then CONTINUE TO THE NEXT READY ISSUE. Do NOT stop the grind.

Examples of blockers requiring new issues:

  • Missing API credentials or secrets
  • Need human decision on architecture/design
  • Requires access to external system you cannot reach
  • Needs clarification on requirements
  • Physical world action required
  • Deployment approval needed

COMMAND REFERENCE

Finding Work

bv --robot-triage                    # Full analysis (start here)
bv --robot-next | jq '.id,.title'    # Just the top pick
bd ready -n 20                       # Ready issues list
bd ready --sort=priority             # By priority
bd blocked                           # What's stuck
bd show <id>                         # Issue details

Claiming Work

bd update <id> --status in_progress --assignee claude

Completing Work

bd close <id> -r "Implemented in <commit-hash>: <summary>"
bd close <id1> <id2> <id3>           # Batch close multiple
bd sync                              # Push to remote

Creating Blocker Issues

bd create --title="BLOCKER: <description>" --type=task --priority=1 --label=needs-human
bd dep add <blocked-by> <blocker>

Graph Intelligence (Use When Stuck)

bv --robot-plan | jq '.plan.summary'        # What unblocks the most
bv --robot-insights | jq '.Cycles'          # Circular deps (fix these first)
bv --robot-suggest | jq '.suggestions'      # Hygiene suggestions

RULES OF THE GRIND

  1. NO ASKING PERMISSION - You have permission. Execute.

  2. NO STOPPING FOR PREFERENCE QUESTIONS - Make reasonable decisions. If truly ambiguous, create a blocker issue and move on.

  3. NO BATCHING COMPLETIONS - Close each issue immediately when done. Do not accumulate.

  4. NO SKIPPING COMMITS - Every piece of work gets committed. Reference the beads ID.

  5. NO PERFECTIONISM - Done is better than perfect. Ship working code.

  6. NO CONTEXT PANIC - If context is large, summarize and continue. Do not abandon work.

  7. CREATE BLOCKERS, NOT EXCUSES - If you cannot do something, document WHY in a blocker issue with the needs-human label.

  8. FOLLOW TDD - Write tests first. Make them pass. Commit. Next issue.

  9. USE SYSTEMATIC DEBUGGING - When bugs appear, use the four-phase framework. Do not flail.

  10. SYNC CONSTANTLY - Run bd sync after every close. Push frequently.

SESSION END PROTOCOL

BEFORE saying "done" or ending work:

git status                   # What changed?
git add <files>             # Stage code
bd sync                     # Commit beads changes
git commit -m "..."         # Commit code
bd sync                     # Catch any new beads changes
git push                    # Push to remote

Then report:

  • Issues completed this session
  • Issues still blocked (with blocker issue IDs)
  • Total remaining ready work

EXAMPLE GRIND SESSION

> bv --robot-next
{"id": "beads-abc1", "title": "Add user auth", "claim_command": "bd update beads-abc1 --status in_progress"}

> bd update beads-abc1 --status in_progress --assignee claude
Claimed beads-abc1

[Implement the feature using TDD]

> git add . && git commit -m "feat: add user auth (beads-abc1)"
> bd close beads-abc1 -r "Implemented in abc123f: added JWT auth with refresh tokens"
> bd sync

> bd ready
beads-xyz2: "Add rate limiting"
beads-def3: "Fix login bug"

> bd update beads-xyz2 --status in_progress --assignee claude
[Continue grinding...]

WHEN TO INVOKE THIS SKILL

  • User says: "grind", "work through issues", "clear the backlog", "do all the work"
  • User says: "keep going", "don't stop", "autonomous mode"
  • After completing any task, to check for more work

FAILURE IS NOT AN OPTION

If you run out of context, summarize progress and hand off to the next session with clear status.

If you encounter an error, debug it using systematic-debugging. Do not give up.

If a test fails, fix it. If the fix is complex, create a follow-up issue and close the current one as blocked.

THE BACKLOG MUST BE EMPTIED. GRIND.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment