The Service Factory

Software factories make software faster. Our clients never wanted software. They wanted the work done.
“Software factory” is this year's phrase. Factory describes one as an agent-native system that runs the whole software lifecycle, from the first signal to shipped and monitored code, and raised $200 million at a $5 billion valuation in September to build it.
But look at what comes off the end of the line: software. The client still has to learn it, run it, check what it produces and call you when it changes under them. The factory got faster but the client's job didn't get easier or smaller. Something is off.
Payroll used to be a service
In 1949, two brothers in New Jersey started Automatic Payrolls. Businesses handed over their payroll and got it back done, first by clerks at adding machines, later on punched cards. You know it today as ADP.

That was the service bureau: you didn't run the machine, you sent the work out. Then software became a product of its own, the personal computer (PC) and software as a service (SaaS) each made the tools cheaper. Each also handed the work back to the customer again.

The bureau lost because their business model didn't scale; every new customer needed more clerks. But a decision model doesn't: it settles the whole batch in one pass and asks a person only where it's unsure. That turns a service back into something that scales like software.
The real, hard work
Most of the clients we meet don't want software at all. They want the payroll run, the books closed, the vendor's sheet in the system. Software is just how they've been made to buy it.
A service factory runs the work for its clients instead of selling them software: a decision model does the work against the client's own ontology, an engineer handles only what the model is unsure of, and one shared platform makes every solution reusable for the next client.
Most of the work goes into the client's ontology, written down as a schema, and it's the part everyone sees: the source of truth for all data, where questions are asked from. Every category, every field it needs, which fields on object requires and another doesn't. Once that is written down, the model has a source of truth to work toward. Every cell in a spreadsheet stops being free text and becomes a question with a known set of answers. That's when model can take over.
The FDE who stays
Palantir made the forward deployed engineer famous: an engineer who sits with the client and builds where the work happens instead of selling from a distance. We work the same way. An FDE learns the workflow from the people who do it, builds it on our platform and runs it with them on real data.
The first thing they build isn't a screen. It's the schema: what things exist in the client's data, how they relate and which answers are allowed. It's the most important step and where most of an FDE's time should always go.
Once a decision model runs the workflow, one of our own FDEs takes it over: they answer its questions and change it when the client's business changes. The client sees the output, not the machine.
A factory needs a floor
A factory is only as good as its floor. If every FDE stands up their own stack for every client, you don't have a factory. You have a consultancy with a lot of repositories.
Our floor is called core, and it's deliberately boring: Postgres and Go, one stateless container per app. At the center is the schema. Every table is a type in the client's ontology, and everything is read from it, including one small API that every app, the chat and MCP share:
| Method | Endpoint | What it does |
|---|---|---|
| Discovery | ||
GET | /api/catalog | Types, views, relationships and apps |
GET | /api/views/{name} | Read a page of workspace data |
GET | /api/search?q={query} | Search the records you can see |
| Records | ||
GET | /api/objects/{type} | List records |
POST | /api/objects/{type} | Create one from its field values |
GET | /api/objects/{type}/{id} | Read one record and what it links to |
PATCH | /api/objects/{type}/{id} | Update only the fields you send |
DELETE | /api/objects/{type}/{id} | Delete one, with an audit trail |
| Workflows | ||
POST | /api/actions/{name} | Run an action with its input |
Sign-in, tenancy and row-level security sit under every one of these, so isolation isn't something an app can forget. And Postgres does most of what a web framework would: a table's comment becomes its API, a type inherits from core's types, and a page is just a view.
object reaches every type that inherits from it. Open animation.That's why the stack can stay at two technologies. Most of what a web framework does, Postgres already does if you let it.
Every app is one declaration
The pattern that matters most is how an app tells the platform what it needs. Each app declares one core.App value in Go, and the platform reads everything from it.
core.App{
Name: "E-Commerce",
Persona: "You are Marzy, the assistant for a retailer...",
Service: &core.Service{CPU: "2", Memory: "2Gi", Base: core.Go},
Edge: &core.Edge{Serves: []string{"/api/ecom/"},
Jobs: []core.Job{
{Name: "reminder", Cron: "0 * * * *", Job: ecom.Remind},
},
Questions: []core.Question{ecom.ProductQuestions, ecom.PhotoQuestions},
}
Because it's all Go values, things that used to be infrastructure move around like code. An agent is a persona and a shelf of skills. A decision model is a declared question. An FDE gives an app a new capability by declaring it, not by filing a ticket with a platform team.
Where the kernel ends
Every platform has the same fight. In January 1992, Andrew Tanenbaum posted “LINUX is obsolete” to a Usenet group. Linux put everything in one kernel, and he called that “a giant step back into the 1970s.” Linus Torvalds answered the same day: “True, linux is monolithic, and I agree that microkernels are nicer.” He kept it monolithic anyway, because it worked.

We have that argument every week, between core and the FDEs. Core wants coherence: one way to sign in, one way to store a record, one way to ask a model. An FDE wants isolation: an app shaped exactly around their client's problem, where nobody else's change can break it.
Lift too much and core bloats into a platform every app has to work around. Lift too little and you get two apps with two definitions of a product, slowly drifting apart. The most expensive thing to have twice is the schema, because every model and every screen built on it inherits the disagreement.
The goal is consistency, because you don't automate by shipping a better tool. You do it by running (and owning) the work yourself.
By Marijn Brussel. Originally published on LinkedIn on October 5, 2026.