Safe By Design: Discipline Is Not Enough
The Structural Weakness of AI Agentic Engineering

opinion
Software used to have a governor built into the process: reality.
You only had so many engineers, so many hours in the day, and so much code a team could physically produce. Ideas had time to collide with architecture, budgets, operations, and the ugly parts of maintaining something after it shipped.
AI blew through that governor.
Now we can generate software faster than we can reason about the structure underneath it, and we keep trying to solve that with discipline. Tell the agent to follow the architecture. Give it better context. Review everything. Document more. The problem is that eventually all of those controls depend on memory and intent. Neither one is strong enough. If the architecture matters, the system itself has to enforce it.
Discipline is not enough because the failure is structural, not merely behavioral.

Prototype → Value → Use Case Validation → Project Feasibility → Project Approval
Once approved, the concept has momentum, and force. Now people want it. This is The Structuralization Gap.
Rebuild/Refactor Foundation → Structural Architecture → Team Dynamics → Development → Deployment
This is not the Software Development Lifecycle (SDLC), this is a generalization of how experiments happen naturally between traditional projects and Agile projects. To contrast with the SDLC, the focus is on the front half of the equation of Software: the Creation process.
Some lessons in life are hard learned (follow my notes, and you’ll find a series of missteps worthy of a plaque or two), and Software Engineering is no different. Anytime a new system is created, it follows a similar pattern.
The problem is that AI is shortcutting the rebuild foundation step. Prototypes do not make it to production for a reason. Not all software ideas truly deserve to be in the system. Even the features and ideas that everybody wants, everybody begs for; sometimes, they just cannot go into the system. AI makes this problem so much harder to deal with.
Everybody wants to create something. That is the fun part. The problem is that creation and engineering are not the same process. One proves that something can exist. The other makes sure it can survive.
This is risk number one for AI driven Software Engineering. The ability to experiment used to be gated by how much of the foundation you understood. Not because Software Engineering was some protected club, but because you had to know enough to wire systems together, break them, fix them, and eventually understand why certain structures existed in the first place. That was usually a 5-10 year adventure, no matter what generation you came from. AI changed that. It can compress the creation side of that journey into days or weeks. What it cannot compress is the experience behind the judgment. The code generation got compressed; the engineering judgment did not. Software Engineering still requires an incredible amount of discipline, day in and day out. AI just makes it easier to move faster than that discipline can keep up.
The risk becomes real the second you get a single paying user. Once money is on the table, the software is no longer something the AI has a stake in. You do, the owner. You are responsible for that software, and what it does in the wild. You now have due diligence on the table. Things have to stay consistent enough that decisions can be made about how to respond to changes in User needs. This is the part you don’t learn in school, or in a book, or asking AI. If you have never deployed a breaking change, you most likely do not understand the blowback from broken software.
At the front of my career, the Fortune 500 company I worked for provided services to a shipping company. It was a real-time routing meta data system. Bleeding edge at the time, and they had a tight 10 minute Service Level Agreement. The cost for downtime was in the range of $10-20,000/minute. The second that system went dark, VPs and C-level people were on the call. This is where I learned reliability. Was it formal? No, just like AI, it was a new way of doing things.
The prototype track proves that something can create value.
Production engineering assumes responsibility for what happens when it fails.
Structural Integrity
Here we get to the structural weaknesses of AI Agentic Engineering. Prototyping is my guilty pleasure, I get it. If you vibe code up a solution, and you are able to get the appearance of working software, you get a hit of dopamine that reinforces your belief in the value. So you prompt it again, and add a feature. Then you prompt it again, and add another feature. So begins the structural erosion.
Even if you start with good intentions, and you tell the AI to follow the architecture, and to use certain design patterns, it ignores this. This is where discipline is no longer enough. Even if you spend the time to build the skills, agents, MCP servers, the CI/CD pipelines, the flows, somehow the AI gets off course. It has no stake in the output. It builds a bridge in a forward only direction, without any support. It is a weird phenomenon. One that is not easy to understand nor easy to explain.
Sometimes it is from context limits getting hit, and it does a context compaction, and something goes lossy. If it loses the architecture requirements, it will start to build sideways, and now be off course for a bit. Sometimes it is a bad prompt. As humans, we have real emotions, and sometimes we are tired, angry, upset, and the prompt gets a different level of focus. This is a proven concept with AI, if you use friendly language, it will engage different than when the language is aggressive. That is two things: context limits, and human prompting. Is that the total answer? No. It is just the beginning.

The Ant Problem
How many legs does an ant have? Six. Take one away and it can still walk, but now the structure is compromised. It can move, but it cannot carry the same load. Add a seventh leg and maybe it helps, maybe it does not. Add two in the right places and now you have something different: a balanced structure with new capabilities. That is evolution. We all want that step forward. We all want the innovation.
Now give the ant 50 legs.
At that point, every individual leg might work. The problem is the ant no longer does. One leg gets slightly out of sync and the whole thing becomes fragile. It is brittle, hard to reason about, and almost impossible to maintain. That is what vibe coded software starts to look like. The AI keeps solving the prompt in front of it, adding another leg, another abstraction, another path, another fix. Locally, the answers can look correct. Structurally, the system is getting worse.
By the time you notice the bloat, the cost of fixing it is usually much higher than the cost of adding one more thing. Refactors stop being clean because the design has already fractured. The system starts taking on the properties of a legacy system long before it has earned the age. At some point, you cannot refactor your way out of it. You have to start cutting legs off and rebuild the structure underneath it.
When it was non-AI assisted coding, this cycle naturally controls itself. It follows human, wall clock time. New features, concepts and ideas become time and space constrained. You don’t build out every idea because you can’t code for 5000 hours. AI inverts this. It generates code at light speed. The output it creates is wild.
So what is happening around the world? Companies and individuals are using AI to code up solutions that would have been cost, resource, time, human, or otherwise constrained. Things that were pet project ideas now are becoming green lit as software can be vibe coded up quickly. For the casual person learning to code, and building ideas, this is great. This is to be encouraged, and one of the better ways to learn how code works. It comes with a cost, and that is what is being highlighted.
AI has no stake in the output, no matter how disciplined you are as a company or an individual. It is working inside a limited context window, and that context is always going to be incomplete. It cannot hold the entire system at once. Something gets dropped, something gets compacted, something gets misunderstood, and eventually the structure starts to drift. You cannot solve that by telling the AI to pay better attention. The structure has to enforce itself.
Software gives us a way to do that. We can test it. We can define contracts, enforce boundaries, break builds, and make the code prove that it is still following the design. The problem is that a green test suite can lie to you too. AI loves mocks. It can write tests around the thing it just built and prove to itself that the thing it built works, without ever touching the real path through the system. Now everything is green, everybody feels good, and then boom, production finds the part nobody actually tested.
How do you deal with this?
How do you get to where you can actually feel confident that the code AI builds is safe to use?
PR sizes are exploding, systems are hitting new levels of code bloat, and the human factors surrounding it are all struggling to keep up. It is a mess.
So how do you keep the ant from growing 50 legs?
Suggestions
- Define structural requirements.
- Document the in and out-of-process steps and where they go.
- Define the design patterns upfront.
- Design a path that all features are required to hook into; not optional.
- This is for control, and boundary enforcement.
- Without a controlled choke point that all paths take, rogue paths will develop through the codebase.
- Enforce these 3 requirements as low as you can. Force the build to break if these constraints are not honored. Structural integrity depends on it.
- Documentation - REMOVE IT - from the agent. Keep it for the humans, put it in a separate branch, do not expose it to the agent. Let the codebase itself be the documentation. Limit what the AI has available to it.
- Nothing will throw an agent off faster than outdated .md files with arch decisions in it. It will read that, consider it higher priority information for the context, and use that as the guiding force instead of the code.
- Data Models.
- Use real data models. Define your structures for the AI to work on. Prompts should be contracts that are defined upfront, in and out. This allows for tighter logging, auditing and reproducibility (as much as is possible with dynamic models).
- Unit tests are not enough. Integration tests are not enough.
- Regression tests are key to survival if you have a live system.
- End to end tests, such as rich CI/CD pipelines that build/test/deploy/monitor/evaluate are the areas to focus on to limit the scope of impact.
- Instrument Everything; use APM - Application Performance Monitoring and Time-Series Data Tools.
- Prometheus, InfluxDB, TimescaleDB, etc. Whatever flavor of time-series data you store, that is a first step. It will expose holes in the architecture fastest.
- Wrap every input point from entry to exit, time it, and store it. Plot it, and evaluate over time. If you have nothing here, this is the first step to seeing change over time.
- An example to start with.
- Take Claude Code, and use the hooks feature to time your agents.
- On SessionStart have it call some utility that emits a timestamp to track.
- On SessionEnd, have it emit a timestamp and send that to a time series database, like InfluxDB, and use something like Grafana to see how your agents are working in real time.
- This will give you a glimpse into the power of time-series data, and how it can help you control your agents, and by extension, your software as it grows.
- NEVER LEAVE A REFACTOR HALF FINISHED.
- It cannot be stressed enough the importance of this: make the AI finish refactors 100%, no exceptions. If you choose to put in a specific Design Pattern in, make sure every single piece of the codebase uses it. The velocity at which these machines generate code is so fast that it will make decisions that appear correct but are wrong.
- If a refactor was only half applied, the codebase is now fractured. A fractured codebase makes the AI delusional about the design of the system. If a compaction happens in the middle of a sequence, and it reads the wrong pattern from previous designs, the result is a compounding of the refactor debt.
- Make it structural impossible for a refactor to remain unfinished.
- NEVER LEAVE A REFACTOR HALF FINISHED!!!!!!!
- It cannot be stressed enough the importance of this: make the AI finish refactors 100%, no exceptions. If you choose to put in a specific Design Pattern in, make sure every single piece of the codebase uses it. The velocity at which these machines generate code is so fast that it will make decisions that appear correct but are wrong.
Discipline is not enough
Structural enforcement needs to come from the design of the codebase itself, not just the product features. Architectural tests are the key to keeping the codebase in alignment with existing platform requirements.
Examples of how you use this kind of thing, through frameworks or lower level APIs:
C# has Roslyn and NetArchTest
Java has ArchUnit
Zig has comptime
Python has PyTestArch and AST
Go has arch-go and go/ast
Node has eslint-plugin-boundaries and dependency-cruiser
There are ways to do this across most of the major programming languages.
They all require the same thing:
Define the architecture, use a real model for how things connect to each other, abstract the interface, wall clock the methods, timestamp events, store them in a time-series database, visualize them, use forecasters to alert you, and you have a system that can control itself.
None of this is new. You clock it, name it, tag it, trend it, alert it, reduce it, eliminate it.
AI has made creation cheap. It has not made structure cheap.
The answer is not better prompting or greater developer discipline. It is systems designed so that architectural correctness is difficult to violate in the first place.
Stay safe.
AI-Assisted