rails-audit — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited rails-audit (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A top-level health-check for an existing Rails app — inheriting a legacy codebase, onboarding to an unfamiliar project, or doing a pre-engagement review. This skill is the entry point for reviewing an app, the counterpart to [[rails-core]] which is the entry point for writing one.
It orchestrates: it owns the broad health-check items nothing else covers (version pinning, dependency CVEs, exposed secrets, seeds, tech-debt) and hands off the deep dives to the specialist skills ([[rails-database-performance]], [[rails-security]], [[rails-performance]], [[rails-testing]], [[rails-upgrade]]). Do not re-derive what those skills already do — run the cheap detection here, then delegate the fix.
The audit ends in a written, severity-ranked report (see Producing the Report).
Gemfile, app/, config/ present).file:line (the audit must point at real code, not generalities).A shared, explicit version is the baseline for reproducible builds. Check the version is pinned and still supported.
cat .ruby-version 2>/dev/null || echo "MISSING .ruby-version"
grep -nE '^\s*ruby\s+["'\'']' Gemfile
grep -nE '^\s*gem\s+["'\'']rails["'\'']' Gemfile
ruby -v; bin/rails -v 2>/dev/nullgem "rails" with no version, or a loose >=) → 🟡 a bundle update can silently jump majors. Lock it.head -1 Gemfile # source must be HTTPS
grep -nE 'cooldown' Gemfile .bundle/config 2>/dev/null # supply-chain cooldown set?
grep -nE 'group\s+:' Gemfile # dev/test gems grouped out of production?source "https://rubygems.org", cooldown: 4 so freshly-hijacked gem releases can't resolve for 4 days. Rationale and scope rules: [[rails-project-setup]].group :development, :test do … end, so a production deploy run with BUNDLE_WITHOUT=development:test (or bundle install --without development test) neither installs nor loads them: smaller image, faster boot, smaller attack surface.Don't flag missing per-gem version pins. With a committedGemfile.lock(andbundle install --deployment/BUNDLE_FROZEN=trueon deploy), every version is already frozen; loose constraints in theGemfileare fine.
Two free, fast scanners. Run both.
gem install bundler-audit 2>/dev/null; bundle exec bundler-audit check --update 2>/dev/null || bundler-audit check --update
gem install brakeman 2>/dev/null; bundle exec brakeman -q -A 2>/dev/null || brakeman -q -AGemfile.lock gems with known CVEs and the patched version → 🔴/🟡 by criticality. Record each advisory + the upgrade target.High first → 🔴.Secrets in the repo (or in git history) are the highest-impact, easiest-to-miss finding.
grep -rinE '(password|secret|api[_-]?key|access[_-]?key|token)\s*[:=]\s*["'\''][^"'\'' ]{6,}' config/ app/ lib/ 2>/dev/null
git log --oneline -- config/master.key config/credentials.yml.enc 2>/dev/null
grep -nE 'config/master.key|config/credentials.*\.key|\.env' .gitignore 2>/dev/null** → 🔴. Move to encrypted credentials (bin/rails credentials:edit`) or ENV.config/credentials.yml.enc (encrypted, committable) decrypted by master.key (which must stay out of git).A suite that nobody has touched in a year is a liability, not a safety net.
git log -1 --pretty=format:'%ci %s' -- test/ spec/ 2>/dev/null; echo
ls -d test spec 2>/dev/null
grep -c . <(find app -name '*.rb') ; find test spec -name '*_test.rb' -o -name '*_spec.rb' 2>/dev/null | wc -lDevelopers must be able to stand up a working local DB without a production dump.
test -s db/seeds.rb && echo "seeds.rb present ($(wc -l < db/seeds.rb) lines)" || echo "MISSING/empty db/seeds.rb"
grep -nE 'find_or_create_by|destroy_all|delete_all' db/seeds.rb 2>/dev/nullcreate! that dupes on re-run) → 🟢 prefer find_or_create_by so seeds can be loaded, cleared, and re-loaded cleanly.bundle exec rubocop --format offenses 2>/dev/null | tail -20 || bundle exec standardrb 2>/dev/null | tail -20
ls .rubocop.yml .standard.yml 2>/dev/nullrubocop-rails or standard for consistent style.rubocop --auto-gen-config to baseline, then fix incrementally.A fast smell test before the full schema audit. Foreign keys without indexes are the most common Rails performance bug.
echo "FK-ish columns:"; grep -E '_id' db/schema.rb | grep -v 'add_index\|t\.index' | wc -l
echo "indexes:"; grep -E 'add_index|t\.index' db/schema.rb | wc -lgrep -rnE '\.(each|map)\b' app/views/ app/controllers/ 2>/dev/null | head -20 # loops that may trigger per-row queries
grep -rnE '\.includes\(|\.preload\(|\.eager_load\(' app/ 2>/dev/null | wc -l # is eager loading used at all?includes/preload → 🟡 probable N+1. Spot-check the dev log (or add prosopite — near-zero false positives, unlike bullet) to confirm.Production footguns — cheap greps for configurations that cause outages, not just slowness:
grep -nE 'puma_worker_killer|unicorn-worker-killer' Gemfile # memory-threshold worker killers
grep -rnE 'send_data|send_file' app/controllers/ | head # large files served from the web process
grep -rnE 'queue_adapter\s*=\s*:inline|Resque\.inline' config/ | grep -v development # inline jobs outside dev
grep -rnE 'timeout' config/initializers/*elastic* config/initializers/*search* config/initializers/*redis* 2>/dev/null # client timeouts set at all?Cheap size heuristics surface the files most likely to hide problems.
echo "Fattest models:"; wc -l app/models/**/*.rb 2>/dev/null | sort -rn | head -10
echo "Fattest controllers:"; wc -l app/controllers/**/*.rb 2>/dev/null | sort -rn | head -10
echo "Service-object sprawl:"; ls app/services 2>/dev/null | wc -l
grep -rnE '^\s*def ' app/controllers/ 2>/dev/null | grep -vE 'index|show|new|create|edit|update|destroy' | head # non-REST actions
echo "ApplicationController methods:"; grep -cE '^\s*def ' app/controllers/application_controller.rb 2>/dev/null # dumping-ground smellbefore_action, with no grouping) → 🟡. It accretes current-user checks, default redirects, env (production?/staging?) checks, www-canonicalisation, response-header setters, etc., that nobody dares move. Group related methods under comments, push any method used by only 1–2 controllers into a concern included just there, and extract each cluster of 2+ related methods into a named concern (e.g. include Akamai). The base controller should read as a manifest of includes. → [[rails-controllers]] (Pattern 1).grep -rinE 'todo|fixme|hack|xxx|deprecated' app/ lib/ 2>/dev/null | wc -l
grep -rinE 'todo|fixme|hack|xxx' app/ lib/ 2>/dev/null | head -40
grep -rnE '^\s*#\s*[a-z].*\b(def|end|do|=)\b' app/ lib/ 2>/dev/null | head # commented-out codeTODO/FIXME/HACK → 🟢/🟡. Decide per item: do it, ticket it, or delete the stale note.End the audit with a written report, grouped by severity (🔴 → 🟡 → 🟢). Each item:
### 🔴 <short title>
- **Where:** path/to/file.rb:42 (or: Gemfile, db/schema.rb)
- **Finding:** what's wrong, with the evidence (the grep hit / scanner line).
- **Impact:** why it matters (security / perf / maintainability / onboarding).
- **Fix:** the concrete change, and **→ which skill** to use for the deep fix.Close with a one-paragraph summary: overall health, the top 3 things to fix first, and the recommended order (security & exposed secrets before refactors).
| # | Check | Command / signal | Deep-dive skill |
|---|---|---|---|
| 1 | Version pinning | .ruby-version, locked gem "rails", EOL? | [[rails-upgrade]] |
| 2 | Gemfile hygiene | HTTPS source, cooldown, dev/test groups | — |
| 3 | Vulnerabilities | bundler-audit, brakeman | [[rails-security]] |
| 4 | Exposed secrets | grep config/, master.key gitignored | [[rails-security]] |
| 5 | Test health | git log -1 -- test/ spec/, coverage | [[rails-testing]] |
| 6 | Seed data | db/seeds.rb present & idempotent | — |
| 7 | Lint/style | rubocop / standard offenses | [[rails-style]] |
| 8 | Schema/index | FK-count vs index-count | [[rails-database-performance]] |
| 9 | N+1/perf | loops without includes | [[rails-performance]] |
| 10 | Architecture | fat models/controllers, service sprawl | [[rails-philosophy]], [[rails-models]], [[rails-controllers]] |
| 11 | Tech debt | TODO/FIXME, dead code | — |
file:line. No evidence, no finding.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.