There was a controller with nine hundred lines and one bug that only fired in September. Three developers touched it that week. When we pointed the complexity panel at it, the score said everything — and the coverage run said the test suite had never touched it. 4.1 ships the two tools that make that obvious before the September bug goes out.
A security review of Wheels 4.0 found a pile of "surely that's safe" that weren't: a policy that treated the string "yes" as true, a form method override that worked on a GET, a zip that could escape its directory. 4.1 closes them by failing closed. Here's the story area by area, and what you have to check on the way up.
@chapmandu reported his ported app's test suite running nearly six times slower on Wheels 4 than on 2.5. We didn't believe it, so we built a benchmark rig to prove him wrong. He was right. Here's the three-month investigation, two unrelated bugs it surfaced, and the lesson about trusting micro-benchmarks.
A deploy pipeline went green while doing nothing to the database, and a code review approved a generator run that had already written files. Both were "the CLI guessed wrong." 4.1 adds diff, dry-run, and offline mode — and the honesty fixes that make a green build mean something.
A storage service had to pick S3 in production and the local disk in dev. The to() binding couldn't express that, so the decision leaked into every caller. toFactory() gives a DI container a *how* — and it's the difference between one closed arrow and ten open switch statements.
A support engineer pastes a link into a customer chat, and they get /posts/4821. Nobody shares /posts/4821. bindBy="slug" exists to make resource URLs say something — and it comes with one mistake you can make that quietly breaks your site.
The enableSession() facade is one line of config. But the real story is the three subtle bugs it exists to prevent — the ones that only surface after the second deploy, or only on a reload, or only for a user who was already logged in. Here's what happens when the wiring goes right.
The story of how bcryptHash(), bcryptVerify(), and bcryptNeedsRehash() made it into Wheels 4.1 starts with a pentest finding and a migration that took three weeks. Here's the helpers, the cost trade-off, and the part where Adobe CF made us question our sanity.
Wheels 4.1 isn't another "we added features and fixed bugs" release. It's the release where a single bug report sent us back to the drawing board, where a security pass made the things you always assumed were safe actually be safe, and where the framework got meaningfully faster. Here's what's coming, and the story behind it.
Wheels 4.0.6 is the first 4.0 feature release after 4.0.5's hardening pass — one-command authentication (`wheels generate auth`), an authorization policy layer, pluggable local/S3 storage disks, query-builder chains that can start with `select()`, and the mixin-plan cache that was making 4.0.x feel slow. Also: Adobe `onApplicationEnd` teardown, tenant/pagination request-key collisions, test-runner isolation, and a production gate on `/wheels`.