gagarinDocumentation

What we will never build

DigitalOcean, Railway and Heroku all started out coherent. None of them died of one bad decision — they died of fifty reasonable ones. The list is public so that walking away from it costs us something.

Every item below is something somebody will ask for one day, and the asking will be fair. The answer is already decided, and it is written down here so that a year from now we cannot quietly change it.

Deploying from a manifest

No YAML in your repo, and no “just apply this file”. A file sitting next to the code drifts from what is running sooner or later. Then nobody can tell you which of the two is telling the truth, which is the whole disease we set out to treat.

The other direction is built. gg eject hands your project back as Kubernetes manifests. But that is a snapshot, not an input. We do not take it back, because the moment we did it would be that second source of truth all over again.

A Swiss army knife

A platform that does a thousand things and in which you can never find any of them. Better a handful of capabilities that make sense the first time than a hundred that each need their own page of documentation.

The rule that holds this in place: anything new has to be sayable in the words we already have — project, service, resource, dependency — or it does not ship. That is a constraint on shape, not on size. We will add capabilities all day. We will not add a second way to do something we already do.

Jobs are the worked example. An image that runs to completion — a migration, a backfill — needed somewhere to live, and the answer was not a new noun with a new page: it is a service that ends, same row, same history, same graph, same meter. What differs is what it has and what it says, not what it is called.

Auto-deploy from git

Pushing an image pushes an image. Shipping is a separate call, always. Otherwise there are two paths that change state, racing each other, and “who shipped this?” goes back to being unanswerable.

Building your images for you

Your docker builds them, or your CI does. Building somebody else’s Dockerfile on our infrastructure means running their code on our machines for no benefit at all — we are going to run the finished image anyway. Building it here would just mean running it twice.

What this does not mean

It is not a promise to build nothing. Backups, webhooks, environments, jobs on a schedule — all of it can arrive, so long as it fits in the words already on the page. The refusal is about shape rather than function, which is why this list ought to survive a few years of real customers.

Domains used to be in this paragraph, and they have since shipped in exactly the way it describes. Not as a fifth noun, but as a property a public service has, with a command of its own, because an address outlives any deploy. That is the rule working rather than failing: it does not forbid new capabilities, it makes each one find a home in the words we already said.

A dashboard that changes infrastructure was an item on this list until September 2026, and it came off by the rule rather than against it. What this list guards is the single source of truth, and a screen is not a second one: anything my.gagarin.cloud ever changes goes through the same API your agent calls, one client at the one door. Today a browser session is minted with no scopes at all and the console only reads — but that is a fact about the credential, not a vow this page needs to hold. The vow it holds is one level down: state changes through the API, or it does not change.