ruby-runtime-compatibility
Use when determining or enforcing Ruby, Rails, Bundler, and runtime-version compatibility before implementing, upgrading, linting, debugging, or reviewing Ruby/Rails code.
Files1
View on GitHubSKILL.mdskills/ruby-runtime-compatibility/SKILL.md
GitHubRuby Runtime Compatibility
Purpose
Establish the actual Ruby/Rails/Bundler runtime contract before using version-sensitive APIs, gems, framework features, or tooling.
This skill separates:
- Ruby engine — CRuby, JRuby, TruffleRuby, or another implementation;
- resolved runtime — a concrete version established by repository evidence;
- declared constraint — a version/range the project permits;
- supported matrix — versions exercised by CI or tooling;
- tooling target — versions configured for linters/type checkers/formatters;
- conflict — repository evidence that does not agree.
Do not silently convert a constraint into a concrete runtime version.
Activate when
- adding or changing Ruby/Rails code with version-sensitive behavior
- upgrading Ruby, Rails, Bundler, or core dependencies
- adding/updating gems or RuboCop plugins
- debugging environment-specific failures
- reviewing compatibility or deprecation issues
- choosing Rails APIs or configuration options
- generating a project profile for an AI coding agent
Repository inspection
Inspect these sources in descending specificity:
Gemfile.lock.ruby-versionGemfile- gemspec files
.tool-versions.mise.toml/mise.toml- Dockerfiles/container build configuration
- CI workflow version matrices
- deployment/runtime configuration
- project documentation only when executable/configuration evidence is absent
Record the source and exact evidence for every resolved value.
Resolution rules
Ruby
Resolve the Ruby implementation separately from the version. A version such as 3.3 can behave differently across CRuby/JRuby/TruffleRuby, and native extensions may impose engine/platform constraints. Prefer:
Gemfile.lock RUBY VERSION
→ .ruby-version
→ Gemfile ruby directive
→ gemspec required_ruby_version
→ tool-version files
→ CI/deployment declarations
A CI matrix may describe supported versions without identifying the local runtime. Preserve it as a support range/list.
Rails
Prefer:
Gemfile.lock exact rails version
→ Gemfile rails constraint
→ explicit framework configuration/documentation
Gemfile constraints such as ~> 7.2 are constraints, not proof that Rails 7.2.x is actually installed.
Bundler
Prefer:
Gemfile.lock BUNDLED WITH
→ environment/tooling declaration
Do not assume the lockfile Bundler version is the runtime's currently executing Bundler version; it is lockfile requirement/evidence.
Ruby compatibility across dependencies
When changing a gem:
- inspect its declared Ruby requirement;
- inspect Rails compatibility;
- inspect adjacent framework plugins/extensions;
- inspect lockfile resolution;
- check CI-supported Ruby versions;
- identify deprecations/removals between the current and target runtime.
Never infer compatibility merely because a gem can be installed in an unrelated environment.
Conflict handling
If repository evidence conflicts:
collect evidence
→ identify stronger source
→ report conflict
→ do not invent a winner
→ ask for clarification when implementation depends on it
Example:
.ruby-version = 3.3.6
Gemfile.lock RUBY VERSION = 3.2.4
Result:
ruby.resolved = unknown
ruby.conflict = true
Do not choose one value merely because its source looks newer.
Compatibility classification
For a requested feature/API/tool, classify the result as one of:
supported— evidence establishes availability in the resolved runtime;constrained— project permits it but no concrete runtime is resolved;unsupported— project/runtime explicitly rules it out;version_sensitive— behavior/API differs across relevant versions;unknown— repository evidence is insufficient;conflict— authoritative repository sources disagree.
Version-sensitive implementation procedure
1. resolve runtime profile
2. identify API/framework feature
3. determine version boundary
4. compare project version with boundary
5. inspect local conventions/deprecations
6. implement compatible form
7. run focused tests
8. run version-sensitive verification/lint
9. inspect final diff
Do not use the newest API merely because it is available in current documentation.
Upgrade procedure
baseline
→ inventory dependencies
→ read release/deprecation notes
→ update compatibility constraints
→ update lockfile
→ run focused tests
→ run full tests
→ run RuboCop/security/dependency checks
→ inspect generated/application changes
→ document remaining deprecations
Treat major/minor framework upgrades as migration projects, not dependency-edit-only tasks.
CI and deployment
CI matrices and deployment configurations are evidence of supported/runtime targets.
They must be distinguished from:
- the local developer runtime;
- the lockfile's resolved runtime;
- the minimum gem requirement.
If CI tests Ruby 3.2, 3.3, and 3.4, report a supported matrix rather than claiming one runtime is the runtime.
Reference example
Version gates decide between APIs instead of rescue-ing NoMethodError; requirements state the supported floor.
require "rubygems/version"
RUBY_FLOOR = Gem::Version.new("3.1")
raise "requires Ruby >= #{RUBY_FLOOR}" if Gem::Version.new(RUBY_VERSION) < RUBY_FLOOR
def filter_present(list)
if RUBY_VERSION >= "3.4" # targeted adoption of newer stdlib
list.filter_map { |v| v unless v.empty? }
else # documented fallback for the floor
list.reject(&:empty?)
end
end
result = filter_present(["a", "", "b"])
raise "filter broken" unless result == %w[a b]
puts "#{RUBY_VERSION}: #{result.inspect}"
Agent review checklist
- Ruby engine resolved or explicitly marked unknown
- Ruby runtime resolved or explicitly marked unknown
- Rails runtime resolved or explicitly marked unknown
- Bundler requirement inspected
- version constraints separated from resolved versions
- CI/deployment support matrix inspected when relevant
- conflicting evidence surfaced
- version-sensitive API boundaries checked
- gem/plugin compatibility checked
- upgrade work treated as a migration when applicable
- focused tests run
- relevant lint/security/dependency checks run
- final compatibility assumptions documented
Verification
Use the repository's configured tools first.
When available, verify:
ruby --version
bundle --version
bundle exec rails --version
bundle exec rubocop --version
For the repository-independent profile generator, use:
ruby bin/runtime-profile PATH
It must report evidence and conflicts rather than silently selecting a version.
Never claim compatibility has been established unless the relevant runtime/tool evidence was actually observed.
Source foundation
This skill is repository-process guidance synthesized for AI coding agents. It intentionally does not hard-code a single Ruby or Rails version. Runtime truth comes from the target application's configuration, lockfile, CI, and deployment evidence.