templates/skills/languages/ruby/SKILL.md
Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
npx skillsauth add hivellm/rulebook RubyInstall 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.
CRITICAL: Execute these commands after EVERY implementation (see AGENT_AUTOMATION module for full workflow).
# Complete quality check sequence:
bundle exec rubocop # Linting and formatting
bundle exec rspec # All tests (100% pass)
bundle exec rspec --format documentation # Test coverage
# Security audit:
bundle audit # Vulnerability scan
bundle outdated # Check outdated deps
CRITICAL: Use Ruby 3.2+ with RuboCop and modern tooling.
source 'https://rubygems.org'
ruby '>= 3.2.0'
# Production dependencies
gem 'rake', '~> 13.0'
# Development dependencies
group :development do
gem 'rubocop', '~> 1.60', require: false
gem 'rubocop-performance', require: false
gem 'rubocop-rspec', require: false
end
# Test dependencies
group :test do
gem 'rspec', '~> 3.12'
gem 'simplecov', require: false
gem 'simplecov-lcov', require: false
end
# Both development and test
group :development, :test do
gem 'pry'
gem 'pry-byebug'
end
Gem::Specification.new do |spec|
spec.name = 'your_gem'
spec.version = '0.1.0'
spec.authors = ['Your Name']
spec.email = ['[email protected]']
spec.summary = 'Brief summary'
spec.description = 'Longer description'
spec.homepage = 'https://github.com/you/your_gem'
spec.license = 'MIT'
spec.required_ruby_version = '>= 3.2.0'
spec.files = Dir.glob('{lib,bin}/**/*') + %w[README.md LICENSE.txt]
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ['lib']
spec.add_dependency 'rake', '~> 13.0'
spec.add_development_dependency 'rspec', '~> 3.12'
spec.add_development_dependency 'rubocop', '~> 1.60'
end
CRITICAL: After implementing ANY feature, you MUST run these commands in order.
IMPORTANT: These commands MUST match your GitHub Actions workflows to prevent CI/CD failures!
# Pre-Commit Checklist (MUST match .github/workflows/*.yml)
# 1. Lint (MUST pass with no warnings - matches workflow)
bundle exec rubocop
# 2. Run all tests (MUST pass 100% - matches workflow)
bundle exec rspec
# or: bundle exec rake test (for Minitest)
# 3. Check coverage (MUST meet threshold - matches workflow)
COVERAGE=true bundle exec rspec
# 4. Security audit (matches workflow)
bundle exec bundler-audit check --update
# 5. Build gem (if gem project - matches workflow)
gem build *.gemspec
# If ANY fails: ❌ DO NOT COMMIT - Fix first!
If ANY of these fail, you MUST fix the issues before committing.
Why This Matters:
rubocop -a (auto-correct) locally but rubocop in CI = failure.rubocop.ymlExample .rubocop.yml:
require:
- rubocop-performance
- rubocop-rspec
AllCops:
TargetRubyVersion: 3.2
NewCops: enable
Exclude:
- 'vendor/**/*'
- 'tmp/**/*'
- 'bin/**/*'
Style/StringLiterals:
EnforcedStyle: single_quotes
Metrics/MethodLength:
Max: 15
Exclude:
- 'spec/**/*'
Metrics/BlockLength:
Exclude:
- 'spec/**/*'
- '*.gemspec'
/spec (RSpec) or /test (Minitest)Example RSpec test:
# spec/my_class_spec.rb
RSpec.describe MyClass do
let(:instance) { described_class.new(value: 'test') }
describe '#process' do
context 'with valid input' do
it 'returns processed value' do
result = instance.process('input')
expect(result).to eq('PROCESSED: input')
end
it 'handles empty strings' do
expect(instance.process('')).to be_nil
end
end
context 'with invalid input' do
it 'raises ArgumentError' do
expect { instance.process(nil) }.to raise_error(ArgumentError)
end
end
end
describe '#validate' do
it 'returns true for valid data' do
expect(instance.validate('valid')).to be true
end
it 'returns false for invalid data' do
expect(instance.validate('')).to be false
end
end
end
Example Minitest:
# test/my_class_test.rb
require 'test_helper'
class MyClassTest < Minitest::Test
def setup
@instance = MyClass.new(value: 'test')
end
def test_process_returns_expected_value
result = @instance.process('input')
assert_equal 'PROCESSED: input', result
end
def test_process_handles_empty_strings
assert_nil @instance.process('')
end
def test_process_raises_on_nil
assert_raises(ArgumentError) { @instance.process(nil) }
end
end
Create spec/spec_helper.rb:
if ENV['COVERAGE']
require 'simplecov'
require 'simplecov-lcov'
SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::LcovFormatter
])
SimpleCov.start do
add_filter '/spec/'
add_filter '/test/'
minimum_coverage 80
minimum_coverage_by_file 70
end
end
require 'your_gem'
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.filter_run_when_matching :focus
config.example_status_persistence_file_path = 'spec/examples.txt'
config.disable_monkey_patching!
config.warnings = true
config.default_formatter = 'doc' if config.files_to_run.one?
config.profile_examples = 10
config.order = :random
Kernel.srand config.seed
end
# Install dependencies
bundle install
# Update dependencies
bundle update
# Check for outdated gems
bundle outdated
# Security audit
bundle exec bundler-audit check --update
.gitignore.byebug_history or debug fileseval unless absolutely necessaryExample code style:
# ✅ GOOD: Clean Ruby code
class DataProcessor
def initialize(options = {})
@threshold = options.fetch(:threshold, 0.5)
@verbose = options.fetch(:verbose, false)
end
def process(data)
validate_input!(data)
log('Processing data...') if @verbose
data.select { |item| item[:value] > @threshold }
end
private
def validate_input!(data)
raise ArgumentError, 'Data must be an array' unless data.is_a?(Array)
raise ArgumentError, 'Data cannot be empty' if data.empty?
end
def log(message)
puts "[#{Time.now.iso8601}] #{message}"
end
end
# ❌ BAD: Poor practices
class DataProcessor
def process(data)
$threshold = 0.5 # DON'T use globals!
if data == nil # Use nil? method
return false
end
result = []
for item in data # Use .each or .map
if item[:value] > $threshold
result.push(item)
end
end
puts result # DON'T print in library code
result
end
end
Must include GitHub Actions workflows:
Testing (ruby-test.yml):
Linting (ruby-lint.yml):
Build (ruby-build.yml):
gem signinRUBYGEMS_API_KEY to GitHub secrets# 1. Update version in gemspec or version.rb
# 2. Update CHANGELOG.md
# 3. Run all quality checks
bundle exec rubocop
bundle exec rspec
gem build *.gemspec
# 4. Create git tag
git tag -a v1.0.0 -m "Release version 1.0.0"
# 5. Push (manual if SSH password)
# git push origin main
# git push origin v1.0.0
# 6. Publish to RubyGems (or use GitHub Actions)
gem push your_gem-1.0.0.gem
<!-- RUBY:END -->research
Author a rulebook task spec interactively — research, draft, ask the user clarifying questions, confirm, then create the tasks in rulebook ready for /rulebook-driver. Use when the user wants to plan/spec a feature before implementing.
development
Behavioral guidelines to reduce common LLM coding mistakes — overcomplication, sloppy refactors, hidden assumptions, weak goals. Use when writing, reviewing, or refactoring code. Auto-applies; invoke explicitly via /karpathy-guidelines or 'follow karpathy discipline'.
data-ai
Autonomous AI agent loop for iterative task implementation (@hivehub/rulebook ralph)
data-ai
Use SQL Server for enterprise relational data storage with advanced features, high availability, and Windows integration.