Skip to main content

6 posts tagged with "ruby"

View All Tags

bin/check-full: the quality gate behind every change

· 10 min read

There is exactly one thing you need to know before opening a pull request against the Fibe Rails app: run bin/check-full. Not "run RuboCop, then Sorbet, then remember the architecture script, then the specs, oh and did you regenerate coverage?" Just the one command. If it's green, your change is ready for human eyes. If it's red, it tells you precisely what to fix.

That simplicity is the point — and it matters even more now that coding agents draft so many of our changes. This is the story of our canonical quality gate: what's inside it, and why it's one command instead of a checklist.

One 402 to rule them all: the not-funded gate

· 6 min read

Every platform that rents compute eventually asks the same question in a hundred different places: is this allowed to run right now? On Fibe, "right now" means funded — a Marquee that has paid for the current service-day. We answer that question with exactly one check and one HTTP status, and we route the consequences differently depending on who's asking.

This is the story of the not-funded gate — a single 402 that sits in front of roughly a hundred call sites.

Gradual typing at scale: Sorbet in a big Rails app

· 9 min read

Fibe runs Docker development environments for people, and the brain of that is a Rails modular monolith. It decides when a Playground is healthy, when to tear one down, when a Wallet has run dry, and when a state transition is illegal and should be refused. That code is dynamic Ruby, and it is load-bearing in the most literal sense: get a state transition wrong and you destroy someone's running environment.

So we type it — but not all of it. Typing every line of a Rails app is a great way to spend a quarter and ship nothing. We type the parts where a wrong shape becomes a wrong outcome, and leave the rest dynamic. This post is about where that line is.

The polyglot stack behind Fibe: Rails, a Rust core, a NestJS genie, and a Go SDK

· 21 min read

People assume four languages means four teams who couldn't agree, or four phases of a rewrite that never finished. Neither is true here. Fibe speaks Ruby, Rust, TypeScript, and Go on purpose, and each one is doing a job the others would do worse. The interesting part isn't the list — every grown-up system has a list. It's the rule that decides which language a given function lands in, and how boring we kept the seams between them.

This post is the honest version: what each piece is, why it exists, and the trade-offs we swallowed to get here. If you've ever stared at a monolith and wondered when to carve a piece off — and into what — this is one team's answer.

Keeping a Rails monolith modular with Packwerk

· 10 min read

Every few months someone asks when Fibe is going to "break the monolith into services." It's a reasonable question. We provision Docker hosts, route TLS, run AI coding agents, charge money, and reconcile container state every sixty seconds — all in one Rails app that ships in one deploy. On paper, the thing the microservices talks warn you about.

It isn't, and the reason is boring in the best way: the monolith is split into ten-plus enforced domains whose boundaries are checked in CI, so a call from the billing domain into the provisioning domain's internals fails the build like a syntax error would. We get the part of microservices that matters — domains that can't secretly reach into each other — and skip the part that hurts: a network between every method call.

Why we carved a Rust core out of our Rails app

· 10 min read

Fibe has been a Rails monolith since the first commit, and after a couple of years running a Docker-based dev-environment platform on it, we still think that was the right call. So when a small Rust workspace showed up in the repo, the obvious question — including from across the team — was some flavor of "oh no, are we rewriting in Rust?"

No. We extracted a very specific, very boring slice of the codebase into Rust, behind a rule we can state in one sentence. This post is that rule, why it works, and the genuinely annoying parts.