Specs before code: how I steer AI agents with OpenSpec
Since 2023 I have built bauernjobs.de almost entirely with AI. Why that tips over without written specs at some point, and how OpenSpec's propose, apply and archive flow fixes it.
Part 1 of 3 in the series "AI development with guardrails". Part 2 (context files) appears on 5 November, part 3 (automated quality gates) on 12 November.
On 17 October 2023 I launched bauernjobs.de, a job platform for German agriculture. Farmers post jobs; seasonal workers from Romania, Poland, Bulgaria or Ukraine apply and message the farms directly. Every message is translated automatically. The platform runs in eight languages, with Stripe payments, email job alerts and a Filament admin panel.
Almost all of the code was written with AI. At first through chat assistants and copy and paste, later with agents that work directly in the repository. I wrote PHP by hand for more than 14 years. With bauernjobs.de I wanted to find out how far you get when you let the AI do the writing.
The honest answer: very far. And then you reach a point where it tips over.
Where it tips over
At the start everything is fast. You describe a feature in the chat, the agent builds it, you click through it in the browser, done. The commit history of bauernjobs.de shows it clearly: 89 commits in 2024, 99 in 2025, 390 by October 2026.
Speed is not the problem. The problem is that the intent is written down nowhere. What a feature is supposed to do lives only in the chat history, and that is gone when the session ends. Next time the agent reads the code and infers what was meant. If the code is wrong, it learns the wrong thing.
A concrete example from bauernjobs.de: a daily command was meant to deactivate job listings after 60 days. It ran every day, without errors, for months. When I finally read it:
- it used 30 days instead of 60,
- it set a column that played no part in deciding what is visible,
- and the line that saves the change was commented out.
The command did nothing. It only went unnoticed because visibility happened to be decided by the date somewhere else. No test, no error in the log, no customer complaint. That is what AI-written code looks like when nobody wrote down what it should do.
What OpenSpec is
OpenSpec is a small tool for spec-driven development with AI agents. The repository gets an openspec/ folder with two parts:
specs/: what the system does today, one file per capability. For bauernjobs.de that is 27 areas, fromlisting-paymentsthroughmessage-translationtogdpr-compliance.changes/: what is supposed to change. Each change is its own folder with the reasoning, a spec delta, a design and a task list.
The specs are plain language: requirements and scenarios in a "WHEN … THEN …" form. No UML, no 80-page requirements document.
The flow: propose, apply, archive
Every change goes through three steps, which I run as commands in the agent.
1. Propose: plan, don't code
I describe what I want. The agent reads the code, the existing specs and the project context, and writes four files:
proposal.md: why and what, including what is explicitly not part of the change,specs/…/spec.md: the delta, meaning which requirements are added, changed or removed,design.md: how, with the technical decisions and the alternatives,tasks.md: small tasks that can each be checked.
The most important rule in this step: no code is changed. The agent only plans. I read the proposal, cut, add and decide. Only then does anything get built.
That sounds like bureaucracy. In practice a proposal takes five to fifteen minutes. And those minutes are exactly when the misunderstandings show up that would otherwise show up after the deploy.
2. Apply: build against a checklist
The agent works through tasks.md one task at a time and ticks each one off. Because the requirements are written as scenarios, the tests almost write themselves: every "WHEN … THEN …" becomes a test case.
If a session breaks off or the context window fills up, tasks.md says where to continue. The next agent doesn't have to guess.
3. Archive: update the source of truth
Once the change is done and verified, it is archived. Its delta is merged into the main specs, so specs/ again describes exactly what the system does. The change itself stays in the archive with its date, as a record of the decision.
What changed at bauernjobs.de
I introduced OpenSpec in June 2026. The first step was not a new feature but an inventory: the agent read the existing code and described what it actually does. Wherever that differed from what was intended, it became a change proposal.
On 7 June 2026 alone, 17 changes found this way were completed and archived: an input-handling security flaw, gaps in the messaging system, missing database indexes, fake demo listings turned into honestly labelled samples. The command that deactivated nothing was one of them.
In September 2026 a full audit followed. The result is a roadmap with a clear order: fix the test environment first, then make payments safe, then email delivery, and only after that new features. Every step points to a change folder. The agent knows what it is working on and what it must not touch yet.
Two rules from that roadmap have proven especially useful:
- Open decisions are marked as open. For prices or customer testimonials it says explicitly: do not change without my confirmation, do not insert invented numbers. AI models like to fill gaps with plausible values. A written rule prevents that.
- A ticked task is not a test result. Something is done only when the checks pass. More on that in part 3.
What you can take from this
You don't have to use OpenSpec. The principle works with any tool:
- Write down what the system does today before you have it changed. You will find bugs just doing that.
- Separate planning from building. Have the agent write a proposal first, read it, then approve it.
- Record what should not happen. A "not part of this change" section saves more time than any clever prompt.
- Keep the spec up to date. A spec that is no longer true is worse than none.
AI writes code faster than any person. What it cannot do is know what you want when you haven't written it down.
The next part (out on 5 November) covers the files the agent reads first in every session, and why an outdated context file is more dangerous than none at all.
Using AI in development and noticing the quality drift? As a fractional tech lead I set up this workflow in your team: specs, context files and checks that stop fast code from turning into expensive code. Book an intro call