Curated library of 41 public AI agent skills for Ruby on Rails development. Organized by category: planning, testing, code-quality, ddd, engines, infrastructure, api, patterns, context, and orchestration. Covers code review, architecture, security, testing (RSpec), engines, service objects, DDD patterns, and TDD automation. Repository workflows remain documented in GitHub but are intentionally excluded from the Tessl tile.
95
93%
Does it follow best practices?
Impact
96%
1.77xAverage score across 41 eval scenarios
Passed
No known issues
Three concrete scenarios showing the exact shape of a Context Summary, a Confusion Block, and an engine-boundary summary. Use these as templates, not as generic patterns to tweak.
Task: Add fulfilled_at timestamp to Order and expose it in the JSON API.
### Context Summary
- Scope: Order model + Api::V1::OrdersController (JSON serializer)
- Rails version: 7.1.3 (from Gemfile.lock)
- Relevant tables: orders (id, state, placed_at, shipped_at) — db/schema.rb:118-135
- Relevant routes: resources :orders, only: %i[index show update] — config/routes.rb:42
- Nearest pattern: app/models/order.rb:24 (state machine with aasm, timestamp callbacks on transition)
- Nearest spec: spec/models/order_spec.rb:12 (shared context `with a placed order`)
- Engine boundary: N/A
- Gotchas: Order uses aasm; timestamps are set in `after_transition` blocks, not via `touch`. Serializer is Blueprinter (app/blueprints/order_blueprint.rb:8) — not ActiveModelSerializers.
- Confusion: NONEContext loaded. Next: plan-tests — first failing spec should assert fulfilled_at is set on the ship! transition.
Task: Fix bug where User#display_name returns email instead of full name for users with a profile.
### Context Summary
- Scope: User#display_name (app/models/user.rb:67)
- Rails version: 7.1.3
- Relevant tables: users (email, first_name, last_name), profiles (user_id, display_name_override) — db/schema.rb:201-240
- Relevant routes: N/A (model-level change)
- Nearest pattern: app/models/user.rb:67 (current implementation returns `email`)
- Nearest spec: spec/models/user_spec.rb:45 (asserts it returns `"#{first_name} #{last_name}"` — currently passing against stubbed code)
- Engine boundary: N/A
- Gotchas: Profile.display_name_override was added in migration 20260201_add_profile_overrides.rb but never wired into User#display_name.
- Confusion: SEE BELOW
### Confusion Block
- Ambiguity: The spec at user_spec.rb:45 expects full-name behavior, but production code returns email. Which is the intended behavior?
- Evidence:
- spec/models/user_spec.rb:45 — expects `"Ada Lovelace"`
- app/models/user.rb:67 — `def display_name; email; end`
- db/migrate/20260201_add_profile_overrides.rb introduces `profiles.display_name_override` but nothing reads it
- Options:
A. Treat spec as source of truth: return `"#{first_name} #{last_name}"`, fall back to email; also wire in `profile.display_name_override` when present
B. Treat code as source of truth: update spec to expect email; drop the unused column
- Recommendation: A — the migration and spec both indicate the intended direction; current code is the regression
- Needed from you: Confirm A, or point to the product decision behind BContext loaded. Waiting on Confusion resolution before proposing the fix.
Task: Add a "Resend invite" button to the admin users screen. Invitations lives in a mounted engine.
### Context Summary
- Scope: Admin::UsersController (host) + Auth::InvitationsController (engine Auth::Engine)
- Rails version: 7.1.3
- Relevant tables: users, auth_invitations (token, expires_at, user_id) — db/schema.rb (host) + engines/auth/db/schema.rb
- Relevant routes:
- host: namespace :admin { resources :users } — config/routes.rb:18
- engine: mount Auth::Engine, at: "/auth" — config/routes.rb:3
- engine internal: resources :invitations, only: %i[create] — engines/auth/config/routes.rb:7
- Nearest pattern: app/controllers/admin/users_controller.rb:88 (existing `reset_password` action calls `Auth::PasswordResets::Create.call(user:)`)
- Nearest spec: spec/requests/admin/users_spec.rb:52 (pattern for admin-triggered engine actions, uses `Auth::Engine.routes.url_helpers`)
- Engine boundary: Auth::Engine — host must call through `Auth::Invitations::Create.call(user:)`, NOT `Auth::InvitationsController` directly. Engine exposes the service object as the integration point.
- Gotchas: Engine uses its own `current_admin` helper via isolate_namespace; host's Pundit policies do not apply inside the engine. Token TTL is 48h (Auth::Engine.config.invitation_ttl).
- Confusion: NONEContext loaded. Next: review-domain-boundaries — confirm the host→engine call goes through the service object, not the controller.
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
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
scenario-36
scenario-37
scenario-38
scenario-39
scenario-40
scenario-41
mcp_server
skills
api
generate-api-collection
implement-graphql
code-quality
apply-code-conventions
apply-stack-conventions
assets
snippets
code-review
refactor-code
respond-to-review
review-architecture
security-check
context
load-context
setup-environment
ddd
define-domain-language
model-domain
review-domain-boundaries
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
orchestration
skill-router
patterns
create-service-object
implement-calculator-pattern
write-yard-docs
planning
create-prd
generate-tasks
plan-tickets
testing
plan-tests
test-service
triage-bug
write-tests
workflows