I recently used an engineering loop to build out a real codebase: SignalDesk, an open-source, technical-analysis-first market intelligence workbench.
The experiment worked better than I expected.
It turned vague product direction into issues, branches, pull requests, tests, CI checks, runtime smoke tests, and eventually a clean main branch. The repo ended in a healthy state: no open issues, no open pull requests, and working software that had been reviewed, tested, and merged in small increments.
That part was genuinely impressive.
But the more interesting lesson was not that the loop could write code. It was that it could create a different kind of engineering debt.
Not broken code. Not missing tests. Not even bad architecture in the obvious sense.
The debt came from too much plausible work being produced too quickly.
What worked
The strongest part of the loop was its ability to turn loose intent into executable steps.
Instead of sitting with a broad idea like “improve the product”, the system broke work down into small, reviewable pieces. It opened issues, made focused changes, ran checks, and closed the loop through pull requests.
That rhythm matters. A lot of AI coding still fails because it produces a large, opaque diff that nobody wants to review. This felt different. The work was split into smaller units, which made it easier to inspect and safer to merge.
It was also good at keeping momentum. Once the direction was clear, the loop could keep moving through routine engineering tasks without needing constant prompting.
The result was not just a pile of generated code. It was a cleaner repository with working functionality, test coverage, and a visible trail of decisions.
What did not work
The problem was that the loop was sometimes too willing to continue.
It could generate issues that sounded useful, write code that looked reasonable, and produce pull requests that passed basic checks. But not every completed task was equally valuable.
This is where the debt appeared.
When an engineering loop is productive, it becomes easy to confuse activity with progress. A closed issue feels like progress. A green check feels like progress. A merged pull request feels like progress.
Sometimes it is.
Sometimes it is just more surface area to understand, maintain, and justify.
The loop did not always know when the right answer was to stop, simplify, or leave something unbuilt. That judgement still needed a human.
Key findings
The main thing I learnt is that AI engineering loops are useful, but they need strong boundaries.
They are good at:
- turning direction into small engineering tasks
- maintaining a steady development rhythm
- producing reviewable pull requests
- running tests and smoke checks
- cleaning up obvious implementation gaps
They are weaker at:
- deciding whether a feature should exist
- understanding product restraint
- spotting when complexity is not worth it
- distinguishing useful completeness from unnecessary polish
- protecting the codebase from “plausible but low-value” additions
That last point is important.
The risk is not only that AI produces bad code. The risk is that it produces acceptable code for work that did not really need doing.
The new kind of debt
Traditional technical debt often comes from shortcuts. You know something is messy, but you accept it to move faster.
This felt different.
The code was not obviously messy. The process was not careless. The checks were not ignored.
The debt came from volume, speed, and plausibility.
When an AI loop can quickly create well-structured work, you need an even stronger filter on what work should enter the system in the first place.
Otherwise, you end up with a codebase that looks healthy from the outside but carries hidden product and maintenance debt inside it.
Not because the system failed.
Because it succeeded too easily.
What’s next
I still think engineering loops are going to become a normal part of software development.
Used well, they can make solo builders and small teams much more effective. They can take care of repetitive engineering flow, keep repositories moving, and reduce the friction between an idea and a working implementation.
But they should not be treated as autonomous product owners.
The next step is not just making these loops better at coding. It is making them better at knowing when not to code.
For SignalDesk, the next phase is about tightening the product, reducing unnecessary surface area, and making sure every feature earns its place.
That is the real test.
Not whether an AI loop can build more.
Whether it can help build less, better.