Complete guide to all features in the grind loop system.
Choose the right model for each task to optimize cost, speed, and quality.
2025 Best Practice: Use Haiku 4.5 for most work. It's fast, cost-effective, and handles the vast majority of coding tasks excellently.
Models Available:
haiku- Haiku 4.5 - Fast, intelligent, cost-effective (recommended for most tasks)sonnet- Sonnet 4 - Premium reasoning for complex multi-step problemsopus- Opus 3 - Maximum capability for architectural decisions (rarely needed)
Usage:
tasks:
- task: "Fix linting errors"
verify: "ruff check ."
model: haiku
max_iterations: 5
- task: "Refactor authentication"
verify: "pytest tests/auth/"
model: sonnet # Use sonnet for complex refactors
max_iterations: 15CLI:
uv run grind.py run -t "Fix tests" -v "pytest" -m haikuDecision Guide (2025):
Use Haiku 4.5 (Default) for ~90% of work:
- Bug fixes and debugging
- Test fixes and writing tests
- Linting and formatting
- Simple to moderate refactoring
- API endpoint updates
- Database query fixes
- Documentation updates
- Dependency updates
- Performance optimizations
Use Sonnet 4 only when you need:
- Complex multi-step refactoring across many files
- Tricky algorithmic problems requiring deep reasoning
- Architectural planning for large features
- Security-sensitive code changes
Use Opus 3 rarely, only for:
- Major architectural redesigns
- Security audits requiring exhaustive analysis
- Mission-critical algorithm development
Cost Comparison: Haiku is ~50x cheaper than Opus. For most grind loops, the speed and cost savings of Haiku far outweigh any marginal quality gains from larger models.
Execute custom slash commands at key lifecycle points.
Hook Points:
pre_grind- Before loop startspost_iteration- After each iterationpost_grind- After loop completes
Hook Triggers:
once- Run one time only (default)every- Run every timeevery_n- Run every N iterationson_error- Run when errors detectedon_success- Run when task succeeds
Basic Example:
tasks:
- task: "Fix tests"
verify: "pytest"
hooks:
pre_grind:
- "/compact"
post_grind:
- "/code-review"Advanced Example:
tasks:
- task: "Optimize performance"
verify: "pytest --benchmark"
hooks:
pre_grind:
- "/compact"
- "/explain-codebase"
post_iteration:
- command: "/compact"
trigger: every_n
trigger_count: 3
- command: "/benchmark"
trigger: every
post_grind:
- "/code-review"
- "/performance-report"Common Patterns:
Periodic cleanup:
post_iteration:
- command: "/compact"
trigger: every_n
trigger_count: 5Error diagnostics:
post_iteration:
- command: "/debug-logs"
trigger: on_errorFinal validation:
post_grind:
- "/test"
- "/lint"
- "/type-check"Customize the system prompt to add domain-specific instructions.
Three Approaches:
tasks:
- task: "Fix security issues"
verify: "bandit -r src/"
prompt_config:
preamble: "You are a security expert focused on preventing vulnerabilities."tasks:
- task: "Optimize queries"
verify: "pytest tests/db/"
prompt_config:
additional_context: |
Database: PostgreSQL 15
Current issue: N+1 queries in user endpoints
Focus on read performance
additional_rules:
- "Always measure performance before and after"
- "Consider index usage and query plans"
- "Minimize database round trips"tasks:
- task: "Security audit"
verify: "bandit -r src/ && safety check"
prompt_config:
custom_prompt: |
You are a security auditor. Your mission:
## TASK
{task}
## VERIFICATION
Run: {verify_cmd}
## SECURITY CHECKLIST
1. Check for SQL injection vulnerabilities
2. Verify input sanitization
3. Review authentication/authorization
4. Check for exposed secrets
5. Validate HTTPS usage
Signal GRIND_COMPLETE when all checks pass.
Signal GRIND_STUCK if you need human review.Note: Custom prompts must include {task} and {verify_cmd} placeholders.
Break large problems into independent subtasks automatically.
Usage:
uv run grind.py decompose \
--problem "Fix all 47 failing tests" \
--verify "pytest tests/ -v" \
--output tasks.yamlWhat It Does:
- Runs the verification command
- Analyzes failures
- Groups related issues
- Creates task list ordered by dependency
- Saves to YAML file
Example Output (tasks.yaml):
tasks:
- task: "Fix authentication test failures in tests/auth/test_login.py"
verify: "pytest tests/auth/test_login.py -v"
max_iterations: 5
- task: "Fix database test failures in tests/db/test_queries.py"
verify: "pytest tests/db/test_queries.py -v"
max_iterations: 5
- task: "Fix API endpoint tests in tests/api/"
verify: "pytest tests/api/ -v"
max_iterations: 8Then Run:
uv run grind.py batch tasks.yamlRun multiple tasks sequentially with aggregated results.
Usage:
uv run grind.py batch tasks.yaml --verboseOptions:
--verbose- Show full output from each task--stop-on-stuck- Stop if any task gets stuck
Results Summary:
============================================================
BATCH SUMMARY
============================================================
Total: 10 Completed: 8 Stuck: 1 Failed: 1
Duration: 245.3s
Needs attention:
[stuck] Fix complex authentication logic
[error] Fix database migration issues
Working Directory:
tasks:
- task: "Fix frontend tests"
verify: "npm test"
cwd: "./frontend"Tool Restrictions:
tasks:
- task: "Review code only"
verify: "true"
allowed_tools: ["Read", "Glob", "Grep"]Permission Mode:
tasks:
- task: "Dangerous refactor"
verify: "pytest"
permission_mode: "requireApproval"Max Turns:
tasks:
- task: "Complex refactor"
verify: "pytest"
max_turns: 100tasks:
- task: "Implement user authentication with OAuth"
verify: "pytest tests/auth/ -v && ruff check . && mypy ."
model: opus
max_iterations: 20
cwd: "./backend"
hooks:
pre_grind:
- "/compact"
- "/explain-codebase auth/"
post_iteration:
- command: "/compact"
trigger: every_n
trigger_count: 5
- command: "/security-check"
trigger: every_n
trigger_count: 3
post_grind:
- "/code-review"
- "/security-audit"
- "/test"
prompt_config:
preamble: "You are a senior backend engineer specializing in authentication systems."
additional_rules:
- "Follow OAuth 2.0 best practices"
- "Store secrets securely"
- "Implement PKCE flow"
- "Add comprehensive tests"
- "Log security events"
additional_context: |
Tech stack: FastAPI, SQLAlchemy, PostgreSQL
OAuth provider: Google
Session management: Redis
Existing auth code is in:
- backend/auth/oauth.py
- backend/auth/session.pyImport the package directly:
from grind import grind, TaskDefinition, GrindHooks, PromptConfig, SlashCommandHook
# Simple task
task = TaskDefinition(
task="Fix linting",
verify="ruff check .",
model="haiku"
)
result = await grind(task)
# Complex task
task = TaskDefinition(
task="Optimize queries",
verify="pytest tests/db/ --benchmark",
model="sonnet",
max_iterations=15,
hooks=GrindHooks(
pre_grind=[SlashCommandHook("/compact")],
post_iteration=[SlashCommandHook("/benchmark", trigger="every")],
post_grind=[SlashCommandHook("/code-review")]
),
prompt_config=PromptConfig(
preamble="You are a database optimization expert.",
additional_rules=[
"Measure before and after",
"Consider index usage"
]
)
)
result = await grind(task, verbose=True)
if result.status == GrindStatus.COMPLETE:
print(f"Success in {result.iterations} iterations!")
print(f"Hooks executed: {len(result.hooks_executed)}")Don't add hooks and custom prompts until you need them. Start with basic tasks.
- Use haiku for volume work (linting, formatting)
- Use sonnet as default (good balance)
- Use opus sparingly (expensive, slow, but powerful)
For large problems, let Claude break it down:
grind decompose -p "Fix all issues" -v "pytest" -o tasks.yaml
grind batch tasks.yamlUse hooks to automate manual steps:
/compactto manage context/testto verify/code-reviewfor quality
Add domain-specific knowledge via prompts:
prompt_config:
preamble: "You are a [domain] expert."
additional_rules:
- "Domain-specific rule 1"
- "Domain-specific rule 2"The quality of verification commands determines success:
- Good:
pytest tests/ -v --tb=short - Bad:
pytest(no useful error output)
- Increase
max_iterations - Change to more powerful model (opus)
- Add custom prompt with more context
- Break into smaller tasks via decompose
- Check trigger conditions
- Verify slash command exists
- Use
--verboseto see hook execution
- Check verification command output
- Add domain context via prompt_config
- Use more powerful model
- Add hooks for intermediate checks
Last Updated: 2025-11-28