| name | rb:compound |
| description | Capturing a solved Ruby/Rails/Grape problem as reusable knowledge. YAML solution doc. Triggers: "compound this", "save this solution", "capture this fix". |
| argument-hint | [path to fix|review|plan] |
| effort | low |
Compound Knowledge
Capture a solved problem as reusable knowledge. This creates a knowledge base that helps future sessions solve similar problems faster.
What to Compound
Compound problems that:
- Took significant time to solve (> 30 minutes)
- Involved multiple files or systems
- Required debugging or root cause analysis
- Have reusable patterns or lessons
- Others might encounter
Don't compound:
- Trivial syntax errors
- One-line fixes
- Problems specific to unique project state
- Already well-documented issues
Compound Process
START ──▶ VALIDATE AGAINST SCHEMA ──▶ USE RESOLUTION TEMPLATE ──▶ WRITE DOC
│
▼
UPDATE INDEX
│
▼
DONE
Document Structure
Solution documents use YAML frontmatter defined in ${CLAUDE_SKILL_DIR}/references/schema.md and follow the template in ${CLAUDE_SKILL_DIR}/references/resolution-template.md.
Required Frontmatter Fields
module: Ruby module or context area (e.g., "Accounts", "Hotwire/Turbo.UserList")
date: Creation date in YYYY-MM-DD format
problem_type: Category of problem (build_error, test_failure, runtime_error, etc.)
component: Affected component area (active_record_model, hotwire_mount, sidekiq_job, etc.)
symptoms: Array of 1-5 observable symptoms (error messages, unexpected behavior)
root_cause: Detailed explanation of WHY this happened
severity: critical, high, medium, or low
tags: Array of up to 8 searchable keywords (lowercase, hyphen-separated)
Optional Fields
ruby_version / rails_version: Specific version pattern X.Y.Z
iron_law_number: Integer (1-22) indicating which Iron Law was violated
related_solutions: Array of file paths to related solutions
Example Compound Document
---
module: "Accounts"
date: "2026-03-22"
problem_type: "runtime_error"
component: "active_record_model"
symptoms:
- "ActiveRecord::AssociationNotLoaded: association 'posts' not loaded"
- "N+1 query detected in controller"
root_cause: "missing includes on :posts association"
severity: medium
tags: ["preload", "association", "n-plus-one"]
---
# N+1 Query in Posts Controller
## Symptoms
- ActiveRecord::AssociationNotLoaded: association 'posts' not loaded
- N+1 query detected in controller
- Slow response time when loading user profiles
## Investigation
1. **Hypothesis 1**: Missing database index — Added index, query still slow
2. **Hypothesis 2**: Inefficient Ruby processing — Profiled code, bottleneck was DB
3. **Root cause found**: Missing preload on association
## Root Cause
The controller loads users and then accesses each user's posts association without preloading, causing N+1 query behavior. Each user triggers a separate query to load their posts.
## Solution
```ruby
# BEFORE (problematic)
def index
@users = User.all
end
# AFTER (fixed)
def index
@users = User.all.includes(:posts)
end
Files Changed
app/controllers/users_controller.rb:15 — Added includes(:posts)
spec/controllers/users_controller_spec.rb:20 — Added test for preload
Prevention
Related
.claude/solutions/rails-controller-n-plus-one-20260322.md — Similar issue in different controller
- Iron Law #3: "USE includes/preload for associations — avoids N+1 queries"
## Categories
Organize solutions by category for discoverability:
- **ruby** - Ruby language issues
- **rails** - Rails framework issues
- **grape** - Grape API issues
- **sidekiq** - Background job issues
- **security** - Security vulnerabilities
- **perf** - Performance issues
- **ar** - Active Record issues
- **deploy** - Deployment issues
## Compound Index
Maintain `.claude/solutions/index.md`:
```markdown
# Knowledge Index
## Ruby
- `ruby/hash-keys.md`
- `ruby/memoization.md`
## Rails
- `rails/strong-params.md`
- `rails/turbo-streams.md`
## Sidekiq
- `sidekiq/job-not-enqueuing.md`
- `sidekiq/idempotency.md`
## Security
- `security/sql-injection.md`
- `security/mass-assignment.md`
When to Update Index
Update the index when:
- Adding a new solution
- Solutions accumulate (reorganize by category)
- Finding similar existing solutions (link them)
Cross-referencing
Link related solutions:
- Similar symptoms, different causes
- Prerequisites or follow-ups
- Alternative approaches
Format:
## Related Solutions
- `path/to/x.md` - Similar: X, different root cause
- `path/to/y.md` - Prerequisite: Y, setup needed first
Integration with Workflow
Compound after successful resolution:
/rb:plan ──▶ /rb:work ──▶ /rb:verify ──▶ /rb:review ──▶ COMPOUND
│
▼
SOLUTION DOC
Or compound during /rb:learn when extracting patterns.
Compound vs Learn
- Compound: Capture specific problem/solution
- Learn: Extract general patterns and update skills
Use both: Compound first for the instance, Learn to generalize.
References
${CLAUDE_SKILL_DIR}/references/compound-workflow.md — Detailed capture workflow
${CLAUDE_SKILL_DIR}/references/schema.md — Solution frontmatter schema
${CLAUDE_SKILL_DIR}/references/resolution-template.md — Canonical solution template
Decision Menu
After creating a solution document, consider:
- Continue (default) - Move on to next task
- Promote to Iron Law check - If this represents a foundational pattern that should be an Iron Law
- Update skill reference - If this reveals a gap in existing skill documentation
- Update CLAUDE.md - If this changes how the plugin should behave or document functionality
Auto-Trigger Phrases
When user says any of the following, suggest /rb:compound:
- "that worked"
- "it's fixed"
- "problem solved"
- "the fix was"
- "resolved the issue"
- "thanks, that fixed it"
Quality Checklist
Good compounds have:
File Naming
Use kebab-case, descriptive names:
sidekiq-job-not-enqueuing.md ✓
fix.md ✗
issue-123.md ✗
Filename convention: {sanitized-symptom}-{module}-{YYYYMMDD}.md
Example: association-not-loaded-accounts-20260322.md
Gotchas
- Partial-fix capture. Solution doc must describe complete fix (root
cause + replacement strategy), not the first commit that touched
the file. See
references/schema.md for required fields.
- Off-list
problem_type label. Schema permits free-form labels but
suggested values (build_error, test_failure, runtime_error,
performance_issue, database_issue, security_issue,
hotwire_bug, sidekiq_issue, service_issue, action_cable_issue,
logic_error, deployment_issue, iron_law_violation) aid
retrieval grep. Use closest suggested value when one applies.
root_cause describes WHAT, not WHY. Per
references/schema.md, root_cause must explain the underlying
reason, not restate the symptom.
- Vague
symptoms. Must be specific + observable (exact error
string, exact failing assertion). Generic phrases ("test fails")
break retrieval grep.
- Missing or stale
tags. Tags drive search; cards without
retrieval-anchor keywords sit unfound.
Related — invoke manually if needed
- Mistake worth capturing as a rule →
/rb:learn (in-flight lesson capture)