Rails 8.2 was still development work, identified as 8.2.0.alpha, when this watch was checked on 14 September 2026. The Rails release announcements and pinned source establish the snapshot; they do not promise a release date.
For an application on 8.1, the useful question is which changes its installed framework can understand. The current 8.2 defaults file contains ten settings. Only one exact setting already works in released 8.1.3.1. Two other effects have older APIs you can use deliberately. Copying the whole file into an initializer would confuse accepted configuration keys with implemented behavior. Defaults and configuration
Read the warning against the installed version
This comparison pins main at b24658a9b2c6, 8-1-stable at 0151bfbe7731, and the released baseline at 8.1.3.1. Main requires Ruby 3.3.1 or newer; the released 8.1 tag requires 3.2 or newer. A generated .ruby-version is a separate observation because the generator consults its version-manager environment and running Ruby. The rehearsal used Ruby 3.4.10 with load_defaults 8.1 retained, first on the released gem and then on the pinned edge checkout. The edge generator wrote ruby-3.4.10; the common suite passed four tests and ten assertions on each framework. Requirements and generator
| Change and PR | On pinned main | Inspected 8.1 stable / released tag |
|---|---|---|
| Queue adapters (56518, 56629) | Sidekiq adapter removed; five other core adapters deprecated. | Sidekiq already deprecated; the other new warnings absent. |
| CSRF (56561, 56350) | Omitted with: warns under the earlier :null_session default; header verification added. |
New warnings/APIs absent; explicit with: available. |
| Variants (51951) | preprocessed: deprecated in favor of process:. |
New option absent in both. |
| Passwords (56057) | Optional Argon2; BCrypt remains default. | algorithm: absent in both. |
| Marcel (58549) | Requires Marcel 2. | Both retain Marcel 1 requirements. |
| JSON (58601, 58612) | JSON 3 keyword-option fixes present. | Present on stable, absent from released 8.1.3.1. |
| Ractors (58578, 58642) | Selected shared-state changes present. | Inspected changes absent in both. |
| Query order (58548) | shuffle_unordered_selects exists, default false. |
Setting and implementation absent in both. |
The full source inventory and runnable checks are in the companion download. These are synthetic examples prepared with AI assistance, with source and execution records retained. They establish the named behavior on the recorded versions, not compatibility for a client application.
Keep the controller’s response policy explicit
Rails 2.0 added form and Ajax authenticity tokens in 2007. Rails 5.0 added per-form tokens and Origin checking in 2016; Rails 6.1 adopted a SameSite=Lax cookie default in 2020. The tagged defaults record the Origin and SameSite settings. These layers constrain requests carrying browser credentials. Fetch Metadata adds information about the initiating site, but an upgraded application still needs to establish which protections its retained defaults actually enable.
The immediate preparation is to find controllers that call protect_from_forgery without with: and establish their existing failure response. In 8.1.3.1, that bare call chooses :null_session. Adding with: :exception changes behavior; adding with: :null_session makes the existing choice explicit. A controller inheriting Rails’ default protection may already use exceptions. Read the actual inheritance and authentication path before editing it. Released implementation
The fixture exercised the same explicit declaration on both framework versions:
protect_from_forgery with: :null_session
Its missing-token test kept the existing empty-session response. The separate exception-policy test rejected the missing token and accepted a valid token from the same session. On edge, a header-only probe rejected missing headers over HTTPS. The separate plain-HTTP probe allowed a missing-header request when ActionDispatch::Http::URL.secure_protocol was false.
On pinned main, with: still governs the response to failure, while using: selects header or token verification. The new :header_only default needs separate tests for the clients that actually call the application. It is not a reason to add unsupported header-verification settings to 8.1 or to make the same change in every API controller. Edge implementation
Check which gem loads the queue adapter
Rails 4.2 introduced Active Job in 2014 to give jobs a common interface across backends. Rails 8.0 made Solid Queue the generated default in 2024. Removing an adapter from core changes who maintains the integration. An existing application can keep its backend when its queue gem supplies the integration and passes the application’s tests.
The 8.1 warning names Sidekiq 7.3.3 or newer as supplying its own adapter. The rehearsal used Sidekiq 8.1.7 on both Rails versions and verified that the adapter loaded from that gem. A job enqueued and drained in fake mode with Redis access blocked. This tests adapter loading and the local job path, not a live Redis deployment.
Transaction timing is another decision. The global config.active_job.enqueue_after_transaction_commit setting is nonfunctional in 8.1 and restored on this main snapshot. An 8.1 application can instead set the boolean on an individual job class or ApplicationJob. That changes when work becomes eligible for enqueueing. Test both commit and rollback, and verify the queue adapter’s behavior before broadening the setting. Released job implementation
Password hashes need a reader during migration
Rails 3.1 introduced has_secure_password with BCrypt in 2011. Password challenges arrived in 7.1 in 2023, and the 8.0 authentication generator reused that foundation. Main adds optional Argon2, whose memory cost makes parallel guessing more expensive. Existing applications still need to authenticate their existing digests during any transition.
The edge Argon2 adapter does not provide a BCrypt fallback reader or a complete rehash-on-login workflow. Changing algorithm: is therefore not a migration plan for existing accounts. Keep the working BCrypt path until the application has an explicit mixed-hash design, tested verification and rollback behavior, and a decision for users who never log in again. A rehash needs the user’s plaintext password during a verified authentication or reset; an existing digest cannot supply it. Edge algorithm implementation
The edge probe authenticated its own Argon2 digest. Giving its Argon2-only reader a BCrypt digest raised Argon2::ArgonHashFail and left the digest unchanged. A separate, explicit handoff using an already-verified plaintext password passed; it did not test database persistence or concurrent logins.
Use the defaults file after the framework supports it
The earlier-value column below describes effective behavior on pinned main with earlier load_defaults; a raw configuration value may be nil where the behavior is false. It does not mean those APIs exist in released 8.1.3.1. These are all ten assignments in the current template, counting the header hash once.
| Exact setting | Earlier value → 8.2 default | Available on 8.1.3.1? |
|---|---|---|
config.active_job.enqueue_after_transaction_commit |
false → true |
Global key does not work; use the job-class boolean if appropriate. |
config.action_controller.forgery_protection_verification_strategy |
:header_or_legacy_token → :header_only |
No. |
config.action_controller.default_protect_from_forgery_with |
:null_session → :exception |
No global key; an explicit controller with: is available. |
config.action_dispatch.default_headers |
Five-header hash → four headers, omitting X-XSS-Protection |
Yes. Preserve intentional application headers. |
config.active_record.postgresql_adapter_decode_bytea |
false → true |
No. |
config.active_record.postgresql_adapter_decode_money |
false → true |
No. |
config.active_storage.analyze |
:later → :immediately |
No. |
config.action_controller.rescue_from_event_backtrace |
nil → :array |
No. |
config.action_dispatch.strict_accept_header |
false → true |
No. |
ActiveSupport.raise_on_invalid_time_zone_parse |
false → true |
No. |
Separate edge boots with 8.1 and 8.2 defaults verified all ten configured values. That is a configuration check, not ten exercised features; PostgreSQL decoding remains source analysis because this fixture uses SQLite.
None of these defaults requires conversion of a Rails serialized-data format. That does not make every change invisible to downstream code. The PostgreSQL settings change low-level query results to binary strings or BigDecimal; the backtrace option changes a notification payload; strict Accept handling changes content negotiation; invalid time-zone parsing raises instead of returning nil. Those are useful regression-test targets before enabling the settings on edge. Configuration details
Active Storage needs particular care. Immediate analysis changes when metadata becomes available and when work happens; direct uploads still require later analysis when the data is not locally available. Likewise, the edge process: :later variant option is not a spelling correction you can apply to 8.1. On released 8.1, the probe passed process: through to the vips transformation and raised Vips::Error. Pinned main consumed the timing option and produced the expected resized image. Named variant implementations
Check the branch and the released tag
These commands were run inside the recorded Rails checkout:
git log --oneline v8.1.3.1..0151bfbe7731 --grep=JSON -i -- activesupport
git show 0151bfbe7731:activesupport/lib/active_support/json/decoding.rb
git show v8.1.3.1:activesupport/lib/active_support/json/decoding.rb
The stable source uses JSON.parse(json, **options); the released tag uses JSON.parse(json, options).
A main commit may have a different hash after a cherry-pick. A failing ancestry check alone therefore cannot establish that a backport is absent. Check the stable implementation, its tests and the patch discussion, then inspect the actual released tag. A fix present on 8-1-stable is still unavailable to an application locked to an older gem until the application installs a released version containing the fix.
JSON supplied a concrete example. With JSON 3.0.2, released 8.1.3.1 passed an options hash positionally into JSON.parse, and the probe raised ArgumentError. The pinned main run passed. The stable branch contains the keyword-argument repair, but the released tag does not. The shared application tests therefore used JSON 2.21.2; a passing edge run is not permission to raise that dependency in an unchanged 8.1 bundle.
The maintenance policy currently lists 10 October 2026 for 8.1 ordinary fixes and 10 October 2027 for security fixes. It also describes a support-extension condition tied to feature releases. Recheck that policy and maintainer announcements before applying the November dates. Neither a deadline nor a merge on main proves that every ordinary fix must wait for 8.2. The support calendar explanation covers the separate framework and runtime clocks.
The September Ractor work addresses particular shared state, not every application’s initialization code. Inspect the relevant state before moving initializers. The unordered-query shuffle is a test aid on main; applications can already make required ordering explicit. It excludes raw SQL and does not turn an unordered LIMIT 1 into a deterministic choice. Marcel’s version change likewise calls for MIME-allowlist fixtures, not a blind rewrite of stored blob types.
Template and editor integration also need precise labels. Pinned main offers Herb as an ERB implementation, but Erubi remains the default. Action Text has an editor abstraction while still selecting Trix. Neither observation establishes a new default editor or the outcome of a future conference session. ERB implementation, Action Text configuration.
What to do this week
- Record the loaded Rails, Ruby, JSON and queue-adapter versions. Check the adapter’s source location instead of assuming Rails owns it.
- Make an ambiguous controller strategy explicit only after tests establish the response you want. Keep header verification as a separate edge rehearsal.
- Test a job’s commit and rollback path before adopting its 8.1 class-level enqueue setting. Keep the queue backend decision separate.
- Retain supported variant and password APIs on 8.1. Add tests for metadata timing and existing digests before planning the edge replacements.
- Run the pinned companion, then repeat the relevant checks against your own application and exact dependency lock. Refresh the branch and release evidence when the next version is announced.
For the earlier steps that get an application onto 8.1, use the Rails upgrade ladder.
Sources remain linked beside the claims. The Rails blog, edge release notes and pinned framework files above supply the release and implementation record; the companion supplies the synthetic examples and their results.