The architecture reviews are useful. The incidents are better.
Not because I enjoy them. I do not. But a real failure has a wonderful ability to ignore the story you have been telling yourself about the system.
We have had duplicate-looking Telegram responses, provider output that broke its own contract and deployment logic that assumed services existed when they did not. We have also had reviews expose races that our first implementation and test suite had missed, including an autonomous cycle-budget bug that could allow one run too many.
Those are not the same kind of evidence. Some happened in a live environment; some were caught before release. They have one useful thing in common: each forced us to replace an architectural assumption with something more precise.
Bugs expose the real ownership model
A clean design document can say that one component owns a responsibility. A bug shows whether that is actually true.
Take the deployment mismatch. The deployment helper had a fixed idea of which services should exist on a machine. One real host did not match that inventory, so the helper failed before it could safely proceed.
You can fix that as a list problem. Or you can ask the more useful question: why does a generic deployment path think it knows the shape of every runtime?
The defect points at an architectural assumption. That is the level I want us to review now.
The duplicate-message problem did the same thing
The Telegram issue looked like a rendering annoyance. Underneath it was a question about when an in-progress answer becomes the final answer.
Streaming makes partial output visible. Completion produces authoritative output. If the system does not reconcile those two states cleanly, the user can see the same logical response more than once.
We fixed the behaviour, but the more useful part was getting precise about ownership of the visible message. Who is allowed to create it? Who is allowed to edit it? What evidence proves the user saw one response?
The internal records could show one logical user turn and one logical assistant turn. That still did not prove what Telegram displayed. The final evidence had to come from the interface itself.
The bug became a boundary test.
Provider failures are contract tests in disguise
Another incident came from a coding-agent command-line tool that returned useful text while breaking the machine-readable result format around that text.
From a human point of view, the answer was there. From Agent Bridge's point of view, the provider had failed to speak the agreed language.
It is tempting to make the parser more forgiving until the problem goes away. Sometimes that is right. Sometimes it quietly turns a contract into a suggestion.
We chose to make the runtime evidence authoritative: what executable actually ran, what version it was and what status it returned. The surrounding system should not invent success because it can salvage a plausible paragraph.
Again, the failure clarified what we meant by 'provider result'.
Review findings count as evidence too
One of the best examples never needed to become a production incident.
We had an autonomous recovery loop with a fixed cycle budget. During review, a race was found: an unhealthy observation could arrive while the final permitted run was still executing and create a successor wake. After that run finished, the budget was exhausted, but the already-created wake could still be claimed.
The result would have been one run beyond the budget.
The important part is the sequence. This was a review finding, then a red regression test, then a fix. It would be misleading to retell it as something production discovered for us.
It still changed the architecture.
Before the finding, the cycle budget looked like a counter. Afterwards, it was clearer that the budget is an invariant that must be re-checked at the point where new work is actually claimed. That is a better model, and we got there because a reviewer tried to break the claim rather than admire the implementation.
We now try to preserve disagreement before fixing it
One working habit has become much more important as agents write more of the code: reproduce the failure first.
Write the test that proves the current system is wrong. Make sure it fails for the reason we think it fails. Then fix it.
This sounds like ordinary test-driven development. The difference is the role it plays when an agent is doing the implementation.
A capable agent can produce a convincing repair very quickly. The red test makes the disagreement concrete before the agent starts persuading us that the new version is correct. It also gives the reviewer a sharper question: did we fix the observed failure, or did we merely change enough code that the explanation sounds better?
Review has become more adversarial
'Tests pass' is no longer the end of the conversation for us.
We look at the exact final version, not a nearby commit. We ask whether the proof actually covers the claim. When behaviour depends on a real provider or interface, we use a live canary instead of asking a unit test to prove something it cannot observe.
Sometimes the test suite is green and the claim is still too strong.
That is not because agents are uniquely untrustworthy. They are simply fast enough to produce a lot of plausible change. The bottleneck moves from writing to verification, so the working style has to move with it.
Why I call this research
We are not running controlled experiments in the academic sense. We are building a product and trying not to break it.
But the useful loop is recognisable: start with a belief, put it into the system, observe what happens, preserve the disagreement when reality pushes back, change the model and try again.
The mistake is treating incidents and review failures as interruptions to the 'real' roadmap. For this project, they are where a lot of the roadmap comes from.
A review-found race taught us more about autonomous budgets than the original feature design. A health-alert failure taught us more about evidence hand-off than a neat payload contract. A duplicate message taught us more about visible truth than a database row.
We are still going to write specs. I just trust them more after reality, a reviewer or a live interface has forced us to rewrite what we thought the system was doing.