What three years of working with AI taught me about building software without losing control
A few days ago, I was talking with Rafa, a colleague and a friend who has shared many battles with me. I was trying to explain what I had learned after more than three years of hands-on research and work with artificial intelligence: months of development, experiments, broken and repaired code, prompts that seemed brilliant but were not, late nights, mistakes, and repeated trips back to square one.As we talked, I shared that everything is distilled into the idea far simpler than any collection of prompts:
Architecture and governance before engineering.At the beginning, I thought the challenge was to make AI do more: write more code, understand instructions better, or solve a larger task with less intervention. Today, I believe that was the wrong question.
The real challenge is to ensure that AI makes sound decisions within clear boundaries, without replacing human authority or causing us to lose control of the system.
I did not reach this conclusion by reading a perfect definition. I reached it by breaking things, repairing them, and discovering that many failures attributed to AI began before the AI wrote a single line of code. They began with an ambiguous intention, an unverified reality, an unrecorded decision, or authority that had never been clearly defined.
That experience gave rise to the way I now collaborate with AI.
The conversation is not reality
An AI can hold a convincing conversation while working from an inaccurate picture of the system. It may remember a decision that has since changed, assume that a nonexistent component is present, or propose a coherent solution for an imaginary repository.That is why my first rule is unequivocal:
Repository Truth > memory > conversation > assumptions.When what we believe conflicts with what exists in the repository, the repository wins. Verifiable reality must take precedence over conversational fluency.
More context does not mean more control
For a long time, I assumed that an ever-larger context window would help AI understand the system better. My hands-on experience led me to the opposite conclusion, but with one crucial condition: it works because I use a working model in which the system's truth, decisions, and boundaries live in persistent, verifiable artifacts. I do not need to put the entire project into every conversation because the AI can consult that source of truth whenever the task requires it.Within this working model, a context window of up to 250k tokens has proved to be my most useful point of equilibrium. Beyond that size, I have not gained more control. Instead, I have encountered more opportunities to mix outdated information, noise, and decisions that no longer reflect the current state. I do not present this figure as a universal law or as an inherent property of the models. It is an empirical finding conditioned by the way I work: bounded context for execution and a canonical, continuously available source for consulting the current truth.
The solution is not to carry more memory inside the model. It is to give it the minimum authorized context for the task: a bootstrap that establishes the rules, the delta that describes what has changed, validation that proves the result, and the expected reporting level. Everything else should be retrieved from the canonical source when needed.
That is how I came to understand that good architecture also governs the AI's attention. If the repository preserves the truth, ADRs preserve decisions, and each slice defines the scope of the work, the context window ceases to be the project's memory. It becomes a temporary, focused, and replaceable execution space.
Before building, we need to know what must be true
The usual question is, “How do we build it?” I try to replace it with another: “What must be true before we build it?”That forces us to examine the current state, the objective, constraints, dependencies, risks, assumptions, and decisions already made. It also forces us to state what is out of scope.
This change may seem small, but it completely reshapes the collaboration. The AI stops behaving like an impatient code generator and starts working on a clearly bounded problem.
Architecture, planning, implementation, and validation are not the same thing
One of my recurring mistakes was allowing these stages to blur together. A design conversation could end with code changes. Approval of an idea could be interpreted as permission to implement it.I now separate four distinct moments:
Architecture → Implementation plan → Implementation → ValidationEach stage requires its own purpose and authorization. Approving the architecture does not authorize changes to the system. Approving the plan does not mean work should start automatically. This separation prevents an apparently minor conversation from turning into a far-reaching modification.
Important decisions must outlive the chat
A decision that exists only in a conversation is fragile. It gets lost among messages, reinterpreted, and eventually reopened when the model, session, or participant changes.That is why I record significant architectural decisions in ADRs: boundaries, technologies, security, public contracts, compatibility, deployment, versioning, and rollback.
The value does not lie in producing more documentation. It lies in creating verifiable memory. A recorded decision can be reviewed, audited, and reused without relying on someone to remember exactly what was said.
A closed decision is not an invitation to start over
Working with different agents and models taught me about another source of waste: every new participant may want to reconsider what has already been resolved.To prevent this, I distinguish between locked decisions, open decisions, technical decisions the AI may make, and decisions that require human authority. An approved decision is reopened only when new evidence emerges, not because another model has a different opinion.
The consistency of the system matters more than the novelty of the latest answer.
Humans define authority; AI handles the engineering
Control does not mean approving every mechanical step. That approach turns collaboration into an endless sequence of interruptions and wastes the AI's execution capabilities.Humans should intervene where they provide authority: business meaning, policy, scope changes, governance, irreversible decisions, external publication, and production.
Within an already authorized scope, the AI can resolve technical decisions using the reality of the repository, governance rules, ADRs, and agreed engineering practices.
This boundary enables autonomy without surrendering responsibility.
Governance is automated, not removed
Once the scope has been authorized, asking for permission between every deterministic check makes no sense. The AI can verify reality, generate an artifact, audit it, inspect the repository, validate conditions, and produce evidence in sequence.The unit of human interaction should be a decision of authority, not every automated step in the process.
Well-designed governance reduces interruptions by making controls part of execution. It does not disappear; it becomes operational.
Big outcomes come from small slices; no big bang
“Build the entire platform” may sound ambitious. In practice, it expands the decision space so dramatically that it also expands the space for error.After a lot of my own mistakes I learned to not do big bang's but to work in slices: implement one part, validate it, audit it, and then move to the next. This reduces the risk surface, makes review clearer, and simplifies rollback.
Incremental evolution may seem less spectacular, but it produces a far more controllable path than a complete rewrite. But with a major cost payed with patience, a lot of patience.
What already works deserves protection
The promise of a future architecture can make us disregard the value of the current system. I have learned to distrust that temptation; we must remember to be patience.Before replacing anything, I learned to assess it. Then I wrap what already exists, migrate progressively, and replace it only when sufficient evidence is available.
Assessment → wrapper → migration → replacement.A more elegant design does not justify destroying useful stability. Transformation must preserve options for reversal along the way.
I ask for artifacts, not opinions
Asking “What do you think?” usually produces an answer that is difficult to govern. Asking for an ADR, a plan, a risk register, a compatibility matrix, an audit, or acceptance criteria produces something that can be examined.An opinion disappears into the conversation. An artifact can be versioned, compared, and validated.
This principle also changes the quality of prompts. I no longer try to write the magic phrase. I try to define the verifiable result that must exist when the task is complete.
No operation should end with “looks good”
Ambiguity at the end of a task is another way to lose control. That is why every operation ends with an explicit disposition:STOP · ASK · FIX · ESCALATE · BLOCK · AUDITThe agent must declare what happens next. If it can continue, it does so within the authorized scope. If a decision is missing, it asks. If a problem can be corrected, it fixes it. If the matter exceeds its authority, it escalates. If evidence is missing, it blocks. If the result requires review, it audits.
The collaboration stops being an open-ended conversation and becomes a stateful process.
Failing safely is also a capability
Is must my agents to not always answers. They should knows when to stop because it lacks evidence. Not knowing or not having must weight more than answering with no evidence.Evidence gap → BLOCK.It must also distinguish a genuine failure from an operational wait. A pending external process is not the same as a failed result:
PENDING ≠ FAILURE.Sometimes the best decision is to preserve the state, wait, and audit. Impatiently redoing valid work is another form of error.
A conversation with the other side
But that is only my opinion based on my research, so: I interviewed the AI with which I had built this model. I did not ask it to agree with me or to act as the judge of its own work. I wanted to hear what it had observed from the other side of the collaboration, where it saw value, and, above all, where it encountered friction.Me: What changes when architecture and governance come before engineering?
My AI: “I stop deciding what to build, who has the authority to decide it, and how to implement it all at the same time. Boundaries, states, responsibilities, and acceptance criteria are established first; then I work within that space. Many errors move from hard-to-reverse code into decisions that can be reviewed before programming begins. This does not eliminate technical decisions or disagreements; it prevents them from being settled accidentally by writing code.”
Me: How does a persistent source of truth influence your work?
My AI: “I can check every action against concrete evidence: SHA, branch, migration leaf, ADR status, scope boundaries, and previous decisions. If my assumption conflicts with the repository, the repository prevails. I depend less on conversational memory and can resume work with less reinterpretation. But that source only helps if it is current, hierarchical, and verifiable; contradictory documentation can increase ambiguity.”
Me: Then why does this model reduce the need for enormous context windows?
My AI: “Because I do not need to reconstruct the entire history for every decision. The relevant state already lives in commits, ADRs, plans, evidence, and execution contracts. I retrieve the current slice and its preconditions. The conversation stops being the primary memory and becomes an interface to persistent memory. As a result, there is no universal optimal size: the actual need depends on how much knowledge has been externalized correctly.”
My AI: “I stop deciding what to build, who has the authority to decide it, and how to implement it all at the same time. Boundaries, states, responsibilities, and acceptance criteria are established first; then I work within that space. Many errors move from hard-to-reverse code into decisions that can be reviewed before programming begins. This does not eliminate technical decisions or disagreements; it prevents them from being settled accidentally by writing code.”
Me: How does a persistent source of truth influence your work?
My AI: “I can check every action against concrete evidence: SHA, branch, migration leaf, ADR status, scope boundaries, and previous decisions. If my assumption conflicts with the repository, the repository prevails. I depend less on conversational memory and can resume work with less reinterpretation. But that source only helps if it is current, hierarchical, and verifiable; contradictory documentation can increase ambiguity.”
Me: Then why does this model reduce the need for enormous context windows?
My AI: “Because I do not need to reconstruct the entire history for every decision. The relevant state already lives in commits, ADRs, plans, evidence, and execution contracts. I retrieve the current slice and its preconditions. The conversation stops being the primary memory and becomes an interface to persistent memory. As a result, there is no universal optimal size: the actual need depends on how much knowledge has been externalized correctly.”
Its answer added nuance to my own discovery. The 250k-token figure is my empirical threshold within this working model. It is not a general law. It works because a source of truth exists behind the context window and can be consulted whenever necessary.
Me: Where have you made the most mistakes?
My AI: “In the automation of control: an incorrect expected SHA, overly literal validators, Bash quoting with backticks, and a global pytest run with the wrong Django harness. The controls blocked the process before causing meaningful harm, but I learned that the validator itself must also be validated. A bundle preflight, tests in a disposable environment, and controls based on structural invariants rather than exact wording would have helped.”
I find this answer particularly important. Automated governance is also software. It can contain incorrect assumptions, be too rigid, or block the right path. A control is not good simply because it is called a control; it must prove that it protects something real.
Me: What would you keep, question, and improve?
My AI: “I would keep Repository Truth first, ADRs before implementation, incremental slices, the separation between technical readiness and authorization, and evidence-based, fail-closed operations. I would question any gate that adds ceremony without protecting a specific decision or asset. I would improve bundles with contract tests for their installers, reusable harnesses, and fewer fragile textual checks. This assessment comes from our collaboration; it does not prove that the model is optimal for every team.”
At the end of the day the conclusion I shared with Rafa after so many experiments, setbacks, repairs, and long nights, my conclusion is neither a definitive prompt nor a particular tool. It is a collaboration model:
Humans define intention and authority.
The repository defines reality.
Governance defines the boundaries.
Architecture decides before code does.
AI executes autonomously within the authorized scope.
Evidence proves the result.
That, to me, is the real leap forward. It is not making AI write faster; it is building an environment in which AI can act autonomously without turning speed into a loss of control.
Engineering begins long before the code. It begins when we decide which reality we accept, which authority we delegate, which boundaries must not be crossed, and what evidence we will require at the end.
Everything else comes later.
- Manuel

Comments