A new project used to start with a week of arguments. Which runtime. Which framework. How the layers split. Where data access lives. What we do about auth, and what that means for the API. How it gets built, tested and deployed, and by whom.
The week was slow and often tedious, and at the end of it you had a repository with about nine files in it. Most of the value was not in the files.
The part that got fast
That week is largely gone now. You describe the application and you get one back: routed, styled, wired to a database, with a test suite and a pipeline. It runs. For a lot of projects it is better than what the week of arguments would have produced, and it costs an afternoon.
This is a real improvement and it is worth saying so plainly. Nobody should be hand-writing a fifth CRUD scaffold in 2026.
The mistake is reading it as the whole job getting easier. One part of the job got much faster. The rest of it stayed exactly where it was.
The decisions did not go away
Every one of those decisions still gets made. Something picked the ORM. Something decided that the service layer talks to the repository and not the other way around. Something chose session cookies over tokens, and something decided which errors are retried.
What changed is that the choosing happened inside a generation step, in one pass, and nobody in the room took part in it. The result is usually defensible. The reasoning is not recoverable.
You notice this about three months in, when someone asks why. Why this ORM. Why a queue here and a direct call there. Why auth is in middleware on one route and in the controller on another. On a project where the slow week happened, someone remembers, and often there is a page written down. On a generated project there is frequently no answer at all, because there was never a decision — only an output that nobody had a reason to question.
Greenfield becomes legacy faster than it used to
It is more useful to define legacy code as code nobody currently understands than as code that is old. Age is only the usual way of arriving there.
By that definition a codebase can be legacy in its first month. We have looked at applications a few months old with the symptoms of a fifteen-year-old system: nobody can say what the modules are for, a change in one place breaks something apparently unrelated, and there is a directory the team avoids.
Nothing had gone wrong in the generation. The code was fine. What was missing was the thing the slow week used to produce as a by-product — a shared model of the system, held by the people who own it.
The old process was inefficient at producing code and quite good at producing understanding. We replaced it with something that is excellent at producing code and produces no understanding at all.
The judgment was learned in the boring parts
This is the uncomfortable part, and it is worth being direct about it.
Nobody learns why a boundary matters by being told why a boundary matters. They learn it by putting the boundary in the wrong place, shipping it, and paying for it two sprints later. The same is true of retries, of transaction scope, of the difference between a foreign key and a hope. The boring parts were the apprenticeship. That was their second job.
Those parts are now optional, and they are mostly skipped — reasonably, because doing them by hand is slower and nobody is paid to be slow. But the judgment that came attached to them is not being replaced by anything in particular. An engineer starting today can produce a working system in their first week and will not be equipped to review one for another few years. Nothing about that is their fault.
And it runs the opposite way to what you would expect. The scarce skill is no longer writing code. It is reading it. A team can now produce more code in a day than it can carefully read in a week, and reading is the one part of this that has had no productivity increase whatsoever.
What seems to help
We do not think this is solved, and we would be suspicious of anyone who says it is. But three things clearly help, and none of them are clever.
Decide before you generate, and keep the answers. Not the things a parser can work out for itself — a tool can see you are on Postgres. The decisions: the target runtime and version, the architecture, where the layers sit, how data is accessed, what auth looks like, what you are deliberately not doing. That is ten or fifteen minutes of answering, and it is the difference between a project that can explain itself in a year and one that cannot.
Review a plan, not a diff. A plan is short enough to actually read and cheap enough to reject. By the time the same decisions arrive as four thousand lines of working code, they will be skimmed and approved, because rejecting them means throwing away something that already runs.
Read the system back, continuously. Which files implement which use case. Where execution starts and what is reachable. What the API contract really is, as opposed to what the documentation claims. This is the thing that used to live in a senior engineer's head, and it is the part that no longer arrives on its own.
None of this restores the judgment that came from doing the work by hand. That is a longer problem and it belongs to the industry, not to a tool. The narrow claim is that a project should not lose its own reasoning on day one, and that part is both fixable and cheap.
How we build it
This is roughly what the greenfield side of CogniDev Workbench is shaped around, so it is fair to say how.
A greenfield run starts with a question deck about the target — runtime and version, framework, architecture, layering, data access, auth, API style, build, test, CI, deploy, observability. It asks only about decisions. It does not ask you to type in facts it can derive. The answers are written into the repository and stay there, so the project carries its own record of why it is shaped the way it is.
What follows is a plan you read before any code exists, then composition from authored blocks rather than improvisation, then the code itself. Afterwards the workbench reads the result back structurally — the call graph, the entry points, what is reachable, the use cases and the files that implement them — so that what was generated does not stay unread.
That last step matters more than it sounds. A generated codebase that nobody has read is not really yours yet.
The question worth asking
If you are starting something new this quarter, the question is not whether to generate it. That is settled, and generating it is usually right.
The question is whether, in six months, anyone on the team will be able to say why it is shaped the way it is — and whether the answer will come from a person, a document, or a shrug.