Curated library of 28 public AI agent skills for Ruby on Rails development. Organized by category: testing, code-quality, engines, infrastructure, api, and context. Covers code review, architecture, security, testing (RSpec), engines, Hotwire, and TDD automation. Shared Ruby skills (YARD docs, DDD, service objects) have moved to ruby-core-skills. Repository agents remain documented in GitHub but are intentionally excluded from the Tessl tile.
93
95%
Does it follow best practices?
Impact
93%
1.78xAverage score across 28 eval scenarios
Passed
No known issues
Orchestrates robust background job implementation with TDD discipline, proper retry/discard strategies, comprehensive failure scenario testing, and production monitoring to ensure reliable async processing.
Objective: Define job responsibilities, idempotency strategy, and error classification before writing code.
Steps:
HARD GATE — Job Design Complete:
If gate fails: Clarify requirements before implementation.
Objective: Implement job logic under TDD discipline.
Steps:
HARD GATE — Tests Pass:
Example job test skeleton:
# spec/jobs/order_confirmation_email_job_spec.rb
RSpec.describe OrderConfirmationEmailJob do
let(:order) { create(:order, :completed) }
it 'sends confirmation email' do
expect(EmailService).to receive(:send_confirmation).with(order.id, order.customer_email, order.total)
described_class.perform_now(order.id, order.customer_email, order.total)
end
it 'is idempotent' do
expect(EmailService).to receive(:send_confirmation).once
2.times { described_class.perform_now(order.id, order.customer_email, order.total) }
end
it 'raises on transient errors so retry triggers' do
allow(EmailService).to receive(:send_confirmation).and_raise(EmailService::TimeoutError)
expect { described_class.perform_now(order.id, order.customer_email, order.total) }.to raise_error(EmailService::TimeoutError)
end
endExample job implementation skeleton:
# app/jobs/order_confirmation_email_job.rb
class OrderConfirmationEmailJob < ApplicationJob
queue_as :default
retry_on EmailService::TimeoutError, wait: :exponentially_longer, attempts: 5
retry_on EmailService::RateLimitError, wait: :exponentially_longer, attempts: 3
discard_on ActiveRecord::RecordNotFound
discard_on EmailService::InvalidEmailError
def perform(order_id, customer_email, order_total)
order = Order.find(order_id)
return if order.email_sent_at.present? # idempotency guard
EmailService.send_confirmation(order_id, customer_email, order_total)
order.update!(email_sent_at: Time.current)
rescue EmailService::TimeoutError, EmailService::RateLimitError => e
Rails.logger.error("[#{self.class}] transient error: #{e.message}")
raise
end
endNote:
discard_onhandles permanent errors at the framework level — no rescue block is needed for them. The rescue block above covers only transient errors that need logging before being re-raised to trigger retry.
Objective: Harden job for production with correct retry backoff, discard rules, timeouts, and monitoring hooks.
Steps:
retry_on with exponential backoff and a capped attempt count (3–5) for every transient error class.discard_on for every permanent error class; log discards.ApplicationJob callbacks.Solid Queue (Rails 8+) snippet:
# config/initializers/solid_queue.rb
SolidQueue.configure { |c| c.worker = { processes: 2, threads: 5, polling_interval: 1 } }Sidekiq snippet:
# config/initializers/sidekiq.rb
Sidekiq.configure_server { |c| c.redis = { url: ENV['REDIS_URL'] } }Monitoring hook in ApplicationJob:
class ApplicationJob < ActiveJob::Base
around_perform do |job, block|
start = Time.current
block.call
StatsD.timing("jobs.#{job.class.name.underscore}.duration", Time.current - start)
StatsD.increment("jobs.#{job.class.name.underscore}.success")
rescue StandardError
StatsD.increment("jobs.#{job.class.name.underscore}.failure")
raise
end
endHARD GATE — Retry Strategy Configured:
retry_on declared for every transient error with backoff and attempt capdiscard_on declared for every permanent error with loggingIf gate fails: Job is not production-ready.
Objective: Verify retry/discard behaviour under injected failures and confirm observability.
Steps:
Example failure scenario tests:
RSpec.describe OrderConfirmationEmailJob do
let(:order) { create(:order, :completed) }
it 'logs and re-raises on transient error' do
allow(EmailService).to receive(:send_confirmation).and_raise(EmailService::TimeoutError)
expect(Rails.logger).to receive(:error).with(/transient error/)
expect { described_class.perform_now(order.id, order.customer_email, order.total) }
.to raise_error(EmailService::TimeoutError)
end
it 'discards silently on permanent error' do
allow(EmailService).to receive(:send_confirmation).and_raise(EmailService::InvalidEmailError)
expect { described_class.perform_now(order.id, "bad", order.total) }.not_to raise_error
end
endHARD GATE — Failure Scenarios Tested:
If gate fails: Address failure scenarios before deploying.
Never deploy a background job without:
retry_on with backoffdiscard_on with loggingJob fails repeatedly in production:
retry_on/discard_on if mis-classified.Queue backs up:
agents
docs
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
skills
api
generate-api-collection
implement-graphql
code-quality
apply-code-conventions
apply-stack-conventions
assets
snippets
code-review
refactor-code
review-architecture
security-check
context
load-context
setup-environment
engines
create-engine
create-engine-installer
document-engine
extract-engine
release-engine
review-engine
test-engine
upgrade-engine
infrastructure
implement-background-job
implement-hotwire
optimize-performance
review-migration
seed-database
version-api
testing
plan-tests
test-service
write-tests