Reality looks like this:
Prompt → Generate → Does it fit? → No → Re-prompt → Generate → Does it fit? → No → Re-prompt…
The problem is not necessarily the quality of the model. The problem is the system around it — the harness — that doesn’t give the agent (the AI running your tools in a loop) enough context or feedback to know whether what it produced is actually right.
Two things make it worse: the same prompt can return five different answers (it’s non-deterministic), and the model will confidently invent APIs that don’t exist.
AI does not fix a development system, it amplifies the one you already have. So the interesting work isn’t the AI — it’s having solid software-development pillars: QA, Team Culture and Specs & Context.
Based on Andreas Wolf’s T3DD26 talk“Before You Let AI Touch Your Code”(slides)
I’d been circling this idea for weeks without a way to draw it. Then, during Andreas Wolf’s talk, it clicked — he’d already framed what I was trying to say. The house is my take on it. Same idea as the harness: everything around the AI that makes its output trustworthy — the house is just the harness drawn.
These pillars are not AI-specific infrastructure. They are good engineering practices even when no AI is involved: clear specifications help humans, QA gives humans fast feedback, and team culture creates ownership and trust.
Before adopting AI, build the house that AI can live in.
Using the 3 pillars as foundation of our software development the AI can assist us in writing better code, code that respects specs and standards, that does what is supposed to be done, while the human is still responsible and observes the whole loop from a different angle. This is a shared way of working, not a one-off. Because AI only amplifies, every project must stand on all three pillars. Miss one and AI amplifies the gap.
Shared assets make the pillars cheap to satisfy per project — you instantiate, you do not rebuild:
What stays per project: a live QA pipeline, real tasks (not just titles), the shared guidelines/skills wired in, and a human owning every merge.
Why all three are non-negotiable — what AI does when a pillar is missing:
Each part predates AI. What changes is the stakes — AI works faster and more autonomously, so every part now has to hold under more pressure. Why each one matters more with AI:
Remove one part and it collapses. Individually they underdeliver; connected, they give the multiplier.
Do not read QA as “we test the code”. Read it as: we have a system that tells us quickly whether what we produce is good or bad.
With AI this becomes literal. The QA pipeline is the objective function the agent optimises against: tests + E2E + types + lint + CI = a machine-readable definition of “done” that the agent can verify itself, iterate against, and fail on. Without it, the agent optimises a fake target and you are left grading its homework by hand.
(This isn’t “training” in the machine-learning sense — the model isn’t learning from your CI. The pipeline is simply the pass/fail signal the agent loops on until it goes green.)
The harness was valuable before AI; AI just makes it matter more — because now the tools can be run by the AI itself.
No AIWith AIHarness greengreenNo harness red**?** (unpredictable)
In an AI/software context, “harness AI” has a nice implication — AI has power, but you need a system around it to direct that power effectively.
Live example from the T3DD26 talk: a Claude Code session ran PHPStan on its own, saw 4 errors, fixed the 2 it had introduced and left the 2 pre-existing ones — because it had the tool and a clear pass/fail signal.
A human developer can ask 15 questions, read your face, and reconstruct what you meant. An agent cannot. The context has to exist before the work starts.
A 2–3 line prompt is a lossy compression of everything in your head plus the docs — and models are good at pattern completion, not mind reading. GitHub’s Spec Kit frames the same problem: a vague prompt forces the model to guess thousands of unstated requirements, so the spec becomes “the source of truth your tools and AI agents use to generate, test and validate code”. Its loop is /specify → /plan → /tasks → /implement; OpenSpec’s is explore → propose → apply → archive, where the archive is kept and referenced by later specs. (GitHub Blog)
A developer is immersed in the company, and soaks up a whole layer the agent never sees: coding conventions nobody wrote down, how this team names things, which corners of the codebase are fragile, who owns what, the decisions made long ago and the reasons behind them, the product’s tone, the unwritten quality bar, the company’s values and style. Much of a project’s intent also travels by word of mouth — from the client to the project lead to the developer — carrying priorities, the why, and shades of vision and goals that never land in a ticket. A new hire absorbs all of this over months — through reviews, conversations, osmosis. An agent starts every session cold: it has none of it and can’t pick it up by hanging around. The only way that knowledge enters its world is if someone makes it explicit — in guidelines, ADRs, examples and specs. That is the real job of this pillar: turning ambient, tacit team knowledge into context the agent can actually read.
What belongs in this pillar:
The most underestimated pillar, because AI does not only change how we write code. It changes how we decide what to build, how we distribute work, how we review, how much we trust each other’s output, how we admit we do not know something, how we handle AI mistakes — and who is responsible for the result.
Kept deliberately lean and dev-focused: the diagram drops softer culture lines (the right to say NO, “I don’t know” is allowed, how we adopt standards) — real, but attitude rather than harness, and “say NO” is already inside review → reject → redo.
The trust data makes this concrete: near-universal usage, roughly a third trusting the output, and “almost right but not quite” as the top complaint. Teams need a culture where “I don’t trust this output, let’s verify it” is normal engineering, not resistance to AI.
Take both directions of the evidence seriously:
You can teach the AI to run QA after each edit — or read the GitLab pipeline results — and, based on the outcome, fix the code, adapt, and add more tests.
It’s a good habit to keep a Definition of Ready (DoR), and to keep specs and decisions in local Markdown files — that’s what gives the AI the context it needs.
Once your tasks meet a clear Definition of Ready — and your specs, context, and decisions are complete, controlled, and continuously updated — you can feed tasks directly to AI and escape the prompt-and-pray loop.
“AI can make mistakes.”
You bet.
But perhaps the disclaimer is still too cautious. Just remove “can”:
AI makes mistakes.
So do humans. The difference is that AI can produce them faster, at scale, and with remarkable confidence. That doesn’t make AI useless. It means we need to stop treating its output as a finished product.
Clear specifications, automated tests, code reviews, and human judgment aren’t optional extras around AI-assisted development. They’re what makes it work.
About the author:
David Denicolò is a Senior TYPO3 Web Developer at[LST], the Swiss web agency in Lucerne, with 25+ years across backend and frontend. He works at the intersection of TYPO3/PHP, Python, CI/CD and AI-assisted engineering — most recently building an agency-wide Claude Code setup with shared coding standards, templates and skills. He writes about making AI a reliable teammate rather than a slot machine.
Connect on
About the Foundations of AI Assisted Software Development was originally published in Towards AI on Medium, where people are continuing the conversation by highlighting and responding to this story.