Style source of truth: Style and formatting defer to the project's configured linter(s). This skill adds non-style behavior and architecture guidance only. For Hotwire + Tailwind specifics, see apply-stack-conventions.
Quick Reference
| Topic | Rule |
|---|---|
| Principles | DRY, YAGNI, PORO where it helps, CoC, KISS |
| Comments / tags | Explain why; tagged notes need actionable context |
| Logging | One verified message argument (usually a JSON hash); no interpolation; include a redacted backtrace on errors |
| Deep stacks | Chain apply-stack-conventions → domain skills (services, jobs, RSpec) |
HARD-GATE
TESTS GATE IMPLEMENTATION:
When this skill guides new behavior, the tests gate still applies:
PRD → TASKS → TEST (write, run, fail) → IMPLEMENTATION → …
No implementation code before a failing test. See write-tests.
Core Process
When reviewing or refactoring Rails code, follow this sequence. Each step maps to a required checkpoint in your output.
- Run linter — Detect config (e.g.
.rubocop.ymlor.standard.yml), run the appropriate tool, note absence if none found. Output: linter detected (or absent); style defers to it. - Apply area-specific rules — Check path patterns and apply targeted guidance from the Apply by area table. Output: concrete per-path recommendations for every relevant changed file.
- Verify tests gate — Confirm failing tests exist before any new behavior. Output: failing spec, run command, expected failure, minimal implementation step, passing rerun.
- Enforce structured logging — Ensure all
Rails.loggercalls use the installed logger's verified single-message interface; include anevent:field and redacted backtrace for errors. Output: apply structured logging rules from Sub-Rules below. - Enforce comment discipline — Ensure all tags (
TODO:,FIXME:) have actionable context (owner, ticket). Output: apply comment discipline rules from Sub-Rules below. - Chain to specialised skills — Use the Integration table to pull in deeper guidance (security, jobs, specs) as needed.
Language: English unless explicitly requested otherwise.
Sub-Rules
Comments and tagged notes
Comment why, not what. Tags — TODO: / FIXME: / HACK: / NOTE: / OPTIMIZE: — must carry actionable context (owner, ticket, next step). Naked tags fail review.
# BAD — naked tag, no context
# TODO: fix this
# GOOD — TODO with next step + dependency
# TODO(jsmith, JIRA-1234): replace TIER_RATES with DB-backed lookup once billing API v2 is stable.
Structured Logging
Use the project's installed logger interface. Standard Ruby/Rails loggers accept one message argument; a two-argument structured call requires a verified custom adapter. Log once at the recovery boundary, redact sensitive data, and preserve unexpected exceptions.
rescue Timeout::Error => e
Rails.logger.error({ event: "order.processing_failed", error_class: e.class.name, backtrace: e.backtrace&.first(5) }.to_json)
raise
end
Apply by area (path patterns)
| Area | Path pattern | Guidance |
|---|---|---|
| ActiveRecord performance | app/models/**/*.rb |
Eager load in loops; prefer pluck / exists? / find_each. |
| Controllers | app/controllers/**/*_controller.rb |
Strong params; thin actions → services; IDOR / PII → security-check. |
| RSpec | spec/**/*_spec.rb |
FactoryBot; let > let! unless eager setup required. |
| Service objects | app/services/**/*.rb |
Single responsibility; .call / injected deps. |
| Background jobs | app/jobs/**/*.rb / app/workers/**/*.rb |
Idempotency, retries, queue choice, and side-effect boundaries → implement-background-job. |
RSpec and let_it_be (test-prof)
Only recommend let_it_be if test-prof is already in Gemfile.lock. Otherwise default to let; reach for let! only when lazy evaluation would break the example. Don't introduce test-prof unless asked.
Extended Resources (Progressive Disclosure)
Load these files only when their specific content is needed:
- assets/checklist.md — Use for detailed code review checklists.
- assets/snippets.md — Use for quick code snippets of common patterns.
Document which assets were loaded and why in your output so the process is verifiable.
Integration
| Skill | When to chain |
|---|---|
| apply-stack-conventions | Stack-specific: PostgreSQL, Hotwire, Tailwind |
| model-domain | When domain concepts and invariants need clearer Rails-first modeling choices |
| create-service-object | Implementing or refining service objects |
| implement-background-job | Workers, queues, retries, idempotency |
| write-tests | Spec style, tests gate (red/green/refactor), request vs controller specs |
| security-check | Controllers, params, IDOR, PII |
| code-review | Full PR pass before merge |