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
Complete code examples for Pundit and CanCanCan implementations.
# app/policies/post_policy.rb
class PostPolicy < ApplicationPolicy
def update?
user.admin? || record.user_id == user.id
end
def destroy?
user.admin?
end
def create?
user.present?
end
end# app/controllers/posts_controller.rb
class PostsController < ApplicationController
before_action :set_post, only: [:update, :destroy]
def update
authorize @post
if @post.update(post_params)
redirect_to @post, notice: 'Updated successfully'
else
render :edit, status: :unprocessable_entity
end
end
def destroy
authorize @post
@post.destroy
redirect_to posts_path, notice: 'Deleted successfully'
end
private
def set_post
@post = Post.find(params[:id])
end
end# app/models/ability.rb
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.admin?
can :manage, :all
else
can :read, :all
can :update, Post, user_id: user.id
can :destroy, Post, user_id: user.id
can :create, Post
end
end
end# app/controllers/posts_controller.rb
class PostsController < ApplicationController
load_and_authorize_resource
def update
if @post.update(post_params)
redirect_to @post, notice: 'Updated successfully'
else
render :edit, status: :unprocessable_entity
end
end
end# spec/policies/post_policy_spec.rb
require 'rails_helper'
RSpec.describe PostPolicy do
subject { described_class.new(user, post) }
let(:post) { create(:post, user: owner) }
let(:owner) { create(:user) }
context 'as the post owner' do
let(:user) { owner }
it { is_expected.to permit_action(:update) }
it { is_expected.to permit_action(:destroy) }
it { is_expected.to permit_action(:create) }
end
context 'as a different user' do
let(:user) { create(:user) }
it { is_expected.not_to permit_action(:update) }
it { is_expected.not_to permit_action(:destroy) }
it { is_expected.to permit_action(:create) }
end
context 'as an admin' do
let(:user) { create(:user, :admin) }
it { is_expected.to permit_action(:update) }
it { is_expected.to permit_action(:destroy) }
it { is_expected.to permit_action(:create) }
end
context 'as a guest' do
let(:user) { nil }
it { is_expected.not_to permit_action(:update) }
it { is_expected.not_to permit_action(:destroy) }
it { is_expected.not_to permit_action(:create) }
end
end# spec/requests/posts_spec.rb
require 'rails_helper'
RSpec.describe 'PATCH /posts/:id', type: :request do
let(:post) { create(:post, user: owner) }
let(:owner) { create(:user) }
it 'allows the owner to update' do
sign_in owner
patch post_path(post), params: { post: { title: 'New Title' } }
expect(response).to have_http_status(:ok)
expect(post.reload.title).to eq('New Title')
end
it 'denies a guest' do
patch post_path(post), params: { post: { title: 'New Title' } }
expect(response).to have_http_status(:unauthorized)
end
it 'denies a different user' do
sign_in create(:user)
patch post_path(post), params: { post: { title: 'New Title' } }
expect(response).to have_http_status(:forbidden)
end
it 'allows an admin to update any post' do
sign_in create(:user, :admin)
patch post_path(post), params: { post: { title: 'Admin Updated' } }
expect(response).to have_http_status(:ok)
end
endUse this shape in the final implementation report after automated specs pass.
# Rails console — Pundit
user = User.find_by!(email: 'member@example.com')
post = Post.find_by!(slug: 'admin-only')
Pundit.authorize(user, post, :update?)
# raises Pundit::NotAuthorizedError# Rails console — CanCanCan
user = User.find_by!(email: 'member@example.com')
post = Post.find_by!(slug: 'admin-only')
ability = Ability.new(user)
ability.authorize! :update, post
# raises CanCan::AccessDenied# HTTP check
curl -i -X PATCH http://localhost:3000/posts/admin-only \
-H "Authorization: Bearer <token_for_user_without_permission>"
# Expected: 403 Forbidden, or the app's configured denied-access response# spec/support/shared_examples/authorization.rb
RSpec.shared_examples 'requires authentication' do |action|
it "requires authentication for #{action}" do
public_send(action)
expect(response).to redirect_to(new_user_session_path)
end
end
RSpec.shared_examples 'requires authorization' do |action, resource_owner_method|
it "requires authorization for #{action}" do
other_user = create(:user)
resource = create(described_class.controller_name.singularize, user: other_user)
sign_in create(:user)
public_send(action, params: { id: resource.id })
expect(response).to have_http_status(:forbidden)
end
end# spec/controllers/posts_controller_spec.rb
require 'rails_helper'
RSpec.describe PostsController do
it_behaves_like 'requires authentication', :get, :index
it_behaves_like 'requires authorization', :patch, :update
enddocs
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