· DYNOKORE TEAM

From vibe coding to governed development

In 1957, John Backus and his team at IBM presented a paper called The FORTRAN Automatic Coding System. The promise was in the name: you would describe the computation, and the machine would do the programming. It didn't end programming. It created far more of it — because the people writing FORTRAN no longer had to think in registers.

Every step up the ladder has looked like that. Machine code gave way to assembly, assembly to high-level languages. Each step let people write less about how and more about what. And each step moved the source of truth up a level: once compilers could be trusted, nobody maintained the assembly. They maintained the source.

Coding agents are the next step. What you hand an agent is, at bottom, a requirement: what the system should do. So it's tempting to conclude that programming is becoming natural language, and that the code is turning into an intermediate artefact nobody reads.

We think the direction is right. The conclusion is premature, and the reason why matters.

An agent is not a compiler

A compiler translates a formal language deterministically, and it preserves meaning. Compile the same source a hundred times and you get the same behaviour. That guarantee is why we stopped reading assembly.

An agent translates natural language probabilistically, and nothing guarantees it preserves meaning. Natural language is ambiguous to begin with. Give the same request twice and you can get two different programs, both of which pass their own tests.

In the late 1970s, Dijkstra wrote a short note called On the foolishness of "natural language programming". His point was that the value of a formal notation is its precision. He was right. And that's the problem teams are now living with.

What's breaking

We went through about 7,000 Hacker News comments from the past year about working with coding agents, with agents doing the first pass, and kept the 178 in which an engineer described something that actually went wrong for them. The most common complaints:

  • Code that works today and nobody can change tomorrow. Logic duplicated at the wrong layer, the repo's design ignored, a feature another team had to rewrite before it fit. This was the single most frequent theme.
  • Review that can't keep up. Agents produce more than people can read, and review turns into a bottleneck or a rubber stamp.
  • Someone else's AI output landing on you. Large generated changes from colleagues, which you're expected to review, fix or own.
  • Losing your grip on your own codebase. You merged it, but you no longer hold a mental model of it.
  • "It passes" isn't "it does what was asked." The code compiles, the tests are green, and it solves a slightly different problem.

None of these is fixed by better prompts. They're what happens when the source of truth moves up a level but nothing guarantees the translation.

Requirements become the source code

If requirements are where intent now lives, they need everything source code has needed for fifty years:

  • Versioning. Every change to a requirement is a recorded revision, not an edit to a chat history.
  • Review. A change to what the system should do is checked before anyone builds on it.
  • Tests. Each requirement carries acceptance criteria precise enough to check, not adjectives.
  • Traceability. Every line of code can answer: which requirement am I for?

That isn't "write a long spec, then generate". Heavy specs have their own failure mode. One engineer in our sample described a thirty-minute fix that turned into a 37-page AI planning document and a week of process. Governance is not more paperwork. It's making intent precise, keeping it in one place, and checking every output against it.

How we do it

We built DynoKore Keel around three ideas.

One source of truth. Requirements, acceptance criteria, tasks and decisions are versioned records in Keel, and every change traces back to them. Changes to requirements go through an independent examiner agent before they're published. When a question needs a person — how a feature should behave, whether an exemption is acceptable, whether a check may be relaxed — the answer is recorded, with who decided.

Controlled execution. Coding agents work under the project's written engineering standards; for example, library modules may only depend downward, enforced by architecture checks in CI. They can't change the acceptance criteria their tests must prove, and a rule forbids weakening a check to get green. A separate reviewer agent checks every merge request, test changes included. The agent that wrote the code never reviews it.

Verifiable outcomes. A task can't be marked done until its requirement chain exists and passes Keel's readiness check, and no code change merges until the automated checks pass. Routine approvals are delegated to agents, and the record shows which decisions a person made.

Notice what isn't in that list: a person reading every line. We couldn't, and neither can you. The work is in making that safe.

What we got wrong

We learned the hard way that a sentence in a prompt is not a control. We told our agents never to print credentials. Three times, a credential fragment still ended up in an agent's output. The fix wasn't a better prompt. It was mechanism: tools that need credentials read them in their own process and never print them, and a hook now blocks reading credential files at all.

That lesson generalises. In a governed system, a mistake that happens twice gets a mechanism, not a reminder.

And we should be honest about scope. DynoInvoice, the system we've built this way, is weeks old, not years. We can show you how it's structured and how every change was checked. We can't yet show you what it looks like after five years of maintenance. Nobody can, for agent-built systems. That's exactly why the structure matters now.

Where this goes

Will code eventually disappear from view, the way assembly did? Maybe, but only once checking an agent's output becomes as trustworthy as a compiler. Until then, the job isn't to stop engineering. It's to move engineering up a level, to the requirements, and keep the checks underneath honest.

If your team is already shipping agent-written code into a system you'll maintain for years, three things you can start tomorrow:

  1. Write down what "done" means before the agent starts, in terms a test can check.
  2. Never let the agent that wrote a change be the one that approves it.
  3. When a mistake happens twice, replace the reminder with a mechanism.

Vibe coding is a fine way to build a prototype. A system you'll run for years needs something else: governed development.

Every requirement. Every decision. Every proof.

We're opening Keel to a small group of design partners: engineering teams already building with agents who need to answer for what they ship. dynokore.ai