Skip to main content
Dispatches

Fibe Blog

Updates, guides, and engineering notes from the workshop.

How we bill by the day: the service-day model

· 10 min read

Billing at Fibe runs on a unit we call the service-day. A Marquee is either funded for today or it isn't. Every day, for every funded environment, a small charge is taken from the player's Wallet and the Marquee's paid-through time is pushed to the end of the current day. There is no monthly subscription to reason about, no proration math, no surprise cliff at the end of a cycle — just one question, asked once a day, forever: did you pay for today?

This post is about why we chose that shape, how the daily charge keeps an environment running, and the single design rule underneath it that keeps every part of the billing lifecycle agreeing on what "today" actually means.

Self-healing by design: convergence and eventual consistency across Fibe

· 23 min read

Here is the uncomfortable truth at the heart of any platform that runs other people's code on machines it doesn't fully own: the moment after you deploy something, it starts to be wrong. A container OOMs. A host reboots. A VM's clock skews. Someone pushes a new image. The network blips for ninety seconds and a healthcheck misses. None of this is exotic — it's Tuesday. The interesting question isn't whether reality will drift from what you asked for. It's what your system does in the gap.

Fibe's answer is the oldest good idea in operations, applied uniformly: you declare what you want, and a control loop drives the world back toward it. You say "this Playground should be running." Somewhere a reconciler wakes up every sixty seconds, looks at the actual Docker truth on your Marquee, notices it disagrees, and does exactly one thing to close the gap. Then it goes back to sleep. The state you typed is the source of truth; everything the containers are actually doing is just evidence.

One event, four destinations: how notifications fan out

· 9 min read

Your Genie finishes a long edit while you're staring at a different tab. Three things should happen at once: a toast slides in, a new item lands in your inbox so the news survives a reload, and — if you asked for it — your phone buzzes. None of the code that produced that message knows any of this. It raised one notification, passed a player and a string, and moved on.

That gap — between "something happened" and "the user finds out, in four different places" — is the small piece of the system that taught us the most about keeping a Rails app real-time.

Grounding the docs: tying every claim to a line of code

· 9 min read

Every architecture doc we have ever read was true the day it was written. That's the trap. Code keeps moving, the doc stays still, and six months later you have a beautiful, internally consistent description of a system that no longer exists. Nobody lied — the doc just quietly drifted into fiction, and it still reads like the truth.

So when we set out to write the internal "Lifecycle Atlas" for Fibe — the diagram pages explaining how a Playground boots, how billing gates a Marquee, how the Playguard reconciler heals things — we made one rule up front: a claim doesn't get to be on a page until it points at the line of code that makes it true. Not a design doc. Not an Alloy model. The actual running source. This post is about what that rule cost, what it caught, and why docs should go through CI.

CI-Job and Muti-Job: self-healing CI and mutation loops with headless Genies

· 10 min read

A Trick is the most boring primitive we have. It runs your container once, watches it finish, records the exit codes, and tears itself down. No routing, no Genie, no second act. So when someone proposed building "self-healing CI" on top of it, the obvious reaction was: with what? There's nobody home in a Trick.

That turned out to be the point. The Trick stays dumb; the intelligence lives elsewhere — a separate coding Genie that wakes up after the job is done, reads what went wrong, and tries to fix it. Compose a one-shot job with that out-of-band agent and you get a loop that runs your tests and, when they're red, takes a swing at making them green. We call the patterns CI-Job and Muti-Job, and the cleverness is never inside the Trick.

Give your AI agent Fibe superpowers: the MCP server

· 15 min read

Your coding agent is great at writing the diff. It is much worse at the part that comes after: spin up an environment, wait for it to actually come up, hand you a URL, tail the logs when something breaks. Today it does that by shelling out to the fibe CLI and string-matching the help text — which works until the agent invents a flag that doesn't exist, or misreads "building" as "ready," and you spend ten minutes untangling what it thought it did.

The Fibe MCP server fixes the seam. The same fibe binary you already have doubles as a Model Context Protocol server, exposing the entire platform as typed tools an agent calls directly — no subprocess, no shell parsing, no guessing. This guide walks you through wiring it into Claude Code, Cursor, or Codex, choosing how many tools to put in front of the agent, and what it can actually do once it's connected. By the end you'll have an agent that can take "launch the rails template and give me the URL when it's up" and just do it.

The reliability contract every Fibe client speaks

· 25 min read

Fibe runs your code on a Marquee — a Docker host that might be a Scaleway VM in Paris or your own laptop behind a hotel Wi-Fi captive portal. Between your fibe command and that host sits an HTTP API, a reconciler, a websocket, Traefik, and the open internet. Every one of those hops can hiccup. So when you type fibe playgrounds create and the connection dies two seconds in, the only honest answer to "did it work?" is: We don't know, and neither do you — unless we agreed on the rules beforehand.

This post is about those rules. We call it the reliability contract: a small set of primitives — typed errors, idempotency keys, 202 polling, classified retries, a circuit breaker, and a browser layer that survives reconnects — that the Go SDK, the CLI, the MCP server, and the web UI all speak the same way. The goal is simple and a little stubborn: you should never be left staring at a half-broken state wondering what to do next.

Zero-downtime rollouts (and healthchecks that actually mean something)

· 14 min read

Here's the failure we want to save you from. You ship a change, your service restarts, and for the eight seconds it takes your app to boot, every request gets a connection refused or a 502. On a dev Playground nobody notices. On something people actually use during the day, those eight seconds are a pile of errors and a Slack message asking if the site is down.

The fix is one label: fibe.gg/zerodowntime: "true". It flips a service from "stop the old container, start a new one" to a real rolling update — new replicas come up alongside the old ones, and traffic only shifts once the new ones pass a healthcheck. But the label is the easy part. The whole thing lives or dies on whether that healthcheck means anything. A healthcheck that returns 200 the instant the process boots gives you zero downtime and a wall of errors, because you cut traffic over to a replica that isn't actually ready. This guide is about getting both halves right.

Shipping the control plane: rolling updates with zero unavailable pods

· 10 min read

The Fibe control plane is the Rails app behind fibe.gg — it schedules your Playgrounds, talks to your Marquee, moves Mana around your wallet, and answers the SDK. It is the one genuinely centralized piece of Fibe: your environments run on your own Docker host, but the control plane runs on ours. So "drop a few requests, nobody will notice" is not a posture we get to take. A dropped request is a Genie that loses its socket, a fibe command that times out, a half-completed checkout.

The deploy strategy is boring on purpose: zero unavailable pods, a real health probe, and a load balancer that won't route to a pod until that probe is green. We push to main in the afternoon and watch capacity stay flat while a new version rolls in under the old one.

How we organize end-to-end tests for a stateful platform

· 9 min read

Most end-to-end suites test a stateless web app: click a button, the DOM changes, assert on the new DOM — all inside one browser tab. Our suite doesn't have that luxury. When a Fibe test clicks "Launch", a real Docker-Compose project starts spinning up on a real Marquee — a Docker host that might be a Scaleway VM in Paris or someone's laptop. The interesting state isn't in the page; it's a container, somewhere else, that doesn't exist yet and won't for the next forty seconds.

That single fact reshapes everything: the test is inherently async, the work is genuinely slow, and the thing you're asserting on is a remote process you don't control. Get the structure wrong and the suite goes red half the time for reasons nobody can explain, until everyone stops trusting it. This post covers the patterns that make browser tests against remote, stateful infrastructure boring and reliable.