Reading Roundup: Enough to Ship
Two people and four weeks. A five-hour spike that won the deal. Twenty lines of Ruby that replaced scattered params.
Hey there,
Three of this week’s articles are about shipping something real with less than you’d expect: fewer people, fewer hours, fewer lines of code. The other two are about what happens when you don’t stay lean: dependencies that block upgrades, and controller logic that piles up until nobody wants to touch it. The thread is pragmatism. Know when you have enough to ship, and ship it.
2 Martians, Greenfield to MVP in 4 Weeks: Agentic Coding on Rails
Evil Martians shipped a production educational platform with two people (a designer and an engineer) in four weeks using Rails, Inertia, React, and Claude Code. The skills they built along the way are now open source.
https://evilmartians.com/chronicles/2-martians-greenfield-to-mvp-in-4-weeks-agentic-coding-on-rails
What an AI-Assisted Spike Taught Us About Selling Software
Planet Argon’s Software Delivery Manager (not a developer) built a 20-hour spike in five hours using Claude Code and the agency’s house skills. The working app changed the sales conversation from “does this sound right?” to “what happens when I do this?”
https://blog.planetargon.com/blog/entries/what-an-ai-assisted-spike-taught-us-about-selling-software
Upcoming Changes in Rails Rate Limiter
Rails 8.2 makes the built-in rate limiter more flexible: dynamic to: and within: values via callables, and duck-typed cache-key objects that let you key rate limits on any object that responds to cache_key.
https://tejasbubane.github.io/posts/rails-rate-limit-upcoming-changes/
The Hidden Costs of Technical Debt in Rails
FastRuby.io on the quiet patterns that slow teams down: controllers that grow because “the code is already there,” silenced tests, outdated gems that block upgrades, and the stretched estimates that follow.
https://www.fastruby.io/blog/hidden-costs-of-technical-debt.html
Stop Passing Params Around. Use a Plain Ruby Class for Filtering in Rails
A bit of self-promotion this week. I wrote up the PageScope pattern I’ve been using across a few projects: a plain Ruby class with ActiveModel::Model and ActiveModel::Attributes that models filter state for a page. Twenty lines, no gems, and the controller drops to two lines.
https://dcyoung.dev/shorts/stop-passing-params-around-use-a-plain-ruby-class-for-filtering-in-rails/
Quick notes and actionables
The Evil Martians piece is the most detailed agentic coding case study I’ve read: two people, four weeks, authentication, Stripe Connect, live video, a course builder, teacher and student experiences, an admin panel, and a blog. The key insight is that they skipped Figma entirely. The designer built in Storybook using React components, and the engineer took that code directly into the Rails + Inertia app. No handoff, no re-interpretation. The filter abstraction story is worth reading on its own: a bug from duplicated sorting logic led to a proper Filter class that the AI then applied consistently everywhere. Skills encode the architectural decisions. The engineer holds the vision.
The Planet Argon spike article is a good companion to the Evil Martians piece: where Evil Martians show what a two-person team can build in a month, Planet Argon show what a non-developer can build in an afternoon. The point that landed for me is about discovery work. The spike worked because they had transcripts from client calls, competitive research, and a shared document defining the thin slice. All of that context went into the build. The AI didn’t fill in the gaps because there were no gaps to fill. “The quality of the inputs determines the quality of what gets built” is the line I’d highlight.
The Rails 8.2 rate limiter changes are small but useful: the dynamic
to:andwithin:via callables mean you can set different limits for different user types without separate controller declarations. The duck-typing onby:is the neater addition. Rather than build a cache key string manually, you can pass an object that responds tocache_key. TheData.definewrapper pattern in the article is worth noting: it keeps rate-limit key logic out of the model and makes the intent explicit.The tech debt article names the patterns that everyone recognises but nobody flags: controller files that grow because adding to them is easier than restructuring, tests that get commented out and never come back, and the stretched estimates that follow when developers know an area is fragile. The Spree/active_shipping dependency story is a good example of how a small, forgotten gem can block an entire upgrade. Their advice to “ask new devs what confused them” as a way to surface where cleanup is needed is practical and costs nothing.
I wrote the PageScope article after using the same pattern across three projects: the core idea is that filter state for a page is a modelling problem, and Rails already has the tools to model it.
ActiveModel::Modelgives youform_withsupport.ActiveModel::Attributesgives you typed attributes with defaults. Afiltermethod applies the scopes. The controller drops to two lines, the URL holds the state, and adding a filter is adding an attribute. The tabs-as-form-buttons pattern and theData.definefor select options are the parts I use most. It’s the kind of thing that feels like over-engineering the first time and obvious by the third.
From the week
The Evil Martians and Planet Argon articles this week both reminded me of something I’ve been noticing at work. There’s a gap in large software teams between wanting to move fast and actually doing it. Not because people are slow, but because the process around them is heavy. Risk aversion, planning cycles, and re-estimating the same piece of work three times before anyone writes a line of code.
I’ve always leaned towards just building the thing. If something feels right based on past experience, I’d rather put a rough version together and learn from it than spend a week writing a document about it. Not recklessly, but the cost of a quick prototype is almost always lower than the cost of another round of planning. And with AI in the mix now, that cost has dropped even further.
I think we’d see better outcomes in a lot of teams if there was more room for pragmatism. Less “let’s validate before we start” and more “let’s build a small thing and see what we learn.” The Evil Martians shipped a production MVP in four weeks with two people. Planet Argon won a deal with a five-hour spike. Neither of those happened because someone wrote a perfect spec first.
Plenty to chew on this week. If you end up building something off the back of any of these, I want to hear about it. P.S. You can see everything I’ve been reading at dcyoung.dev/bookmarks.
