CtrlK
BlogDocsLog inGet started
Tessl Logo

igmarin/rails-agent-skills

Curated library of 39 AI agent skills for Ruby on Rails development. Organized by category: planning, testing, code-quality, ddd, engines, infrastructure, api, patterns, context, orchestration, and workflows. Includes 5 callable workflow skills (rails-tdd-loop, rails-review-flow, rails-setup-flow, rails-quality-flow, rails-engines-flow) for complete development cycles. Covers code review, architecture, security, testing (RSpec), engines, service objects, DDD patterns, and TDD automation.

95

1.20x
Quality

98%

Does it follow best practices?

Impact

95%

1.20x

Average score across 35 eval scenarios

SecuritybySnyk

Passed

No known issues

Overview
Quality
Evals
Security
Files

criteria.jsonevals/scenario-2/

{
  "context": "Tests whether the agent implements background jobs following the rails-background-jobs skill: passing IDs not objects, adding idempotency checks before side effects, using correct retry/discard strategies, keeping perform thin, and configuring the recurring schedule in recurring.yml.",
  "type": "weighted_checklist",
  "checklist": [
    {
      "name": "Pass ID not object",
      "description": "SendInvoiceReminderJob.perform_later is called with an invoice ID (integer/string), NOT an Invoice object",
      "max_score": 10
    },
    {
      "name": "Load record in perform",
      "description": "The job's perform method looks up the invoice via a finder (e.g. Invoice.find) using the passed ID, not from an instance variable or argument object",
      "max_score": 8
    },
    {
      "name": "Idempotency check present",
      "description": "SendInvoiceReminderJob checks whether the reminder was already sent (e.g. checks reminder_sent_at or a flag) BEFORE sending the email",
      "max_score": 12
    },
    {
      "name": "Side effect after guard",
      "description": "The mailer call (InvoiceMailer or similar) appears AFTER the idempotency guard, not before it",
      "max_score": 8
    },
    {
      "name": "retry_on with attempts",
      "description": "retry_on is used for at least one transient error class AND includes an explicit attempts: N limit (not open-ended)",
      "max_score": 10
    },
    {
      "name": "discard_on permanent error",
      "description": "discard_on is used for at least one permanent/non-retriable error (e.g. ActiveRecord::RecordNotFound)",
      "max_score": 8
    },
    {
      "name": "Thin perform — service delegation",
      "description": "SendInvoiceReminderJob delegates business logic to a service object or mailer rather than containing multi-step orchestration inline in perform",
      "max_score": 8
    },
    {
      "name": "Recurring in recurring.yml",
      "description": "config/recurring.yml exists and defines the nightly sweep job with a cron or schedule expression targeting 08:00 UTC",
      "max_score": 10
    },
    {
      "name": "Solid Queue adapter",
      "description": "The implementation uses Solid Queue as the queue adapter (referenced in config, gemfile, or process_log.md) — not Sidekiq or async",
      "max_score": 8
    },
    {
      "name": "Spec covers idempotency",
      "description": "SendInvoiceReminderJob spec includes a test case verifying that enqueueing the job twice does NOT send the email twice (second enqueue is a no-op)",
      "max_score": 10
    },
    {
      "name": "Spec written for job",
      "description": "Both spec files exist (send_invoice_reminder_job_spec.rb and nightly_overdue_invoice_sweep_job_spec.rb) with at least one describe/it block each",
      "max_score": 8
    }
  ]
}

README.md

tile.json