Could this work beyond demos?

By early 2025, I had been experimenting with AI-assisted development for some time. We had run workshops and hackathons, and I had started biweekly sessions with developers to move beyond occasional code completion and explore agentic development as part of our regular engineering process.

The tools were improving quickly, but there was a reasonable objection from the team. Most of the impressive examples were demos, small projects, or isolated implementations. What we ultimately cared about was whether this way of working could become reliable engineering practice, including in the large and mature systems we already had.

I didn’t have evidence for that, and I didn’t want to answer the question with enthusiasm.

At roughly the same time, we were exploring what AI could mean for our product. Those two threads came together in Territory Planner. It gave us a meaningful product problem and a real engineering project on which to test agentic development.

Remove the escape hatch

Before the first line of the Territory Planner prototype was written, we made one rule: developers would not write production code manually.

The reason was simple. If an agent struggled and the developer finished the difficult part manually, we could probably still ship the product. But we would learn very little about where agentic development failed or what had to change to make it reliable.

So there was no fallback. The product was developed through coding agents from the first prototype code through the production release, and we have continued developing it using the same principle.

Territory Planner was built as an isolated module and later integrated with our core system in pre-production. That isolation made the experiment manageable, but it did not keep the implementation small.

As it grew, we got exactly the kinds of problems I wanted the constraint to expose: hallucinations, skipped code, duplicated work, bugs, deferred functionality, and implementations that looked reasonable but were not what we intended. Generating code itself was rarely the main problem. The harder problem was getting the right implementation in the context of a growing system.

The process grew out of the failures

We did not start with a methodology for agentic software development. In the beginning, there was basically a prompt.

As the solution grew, that stopped being enough. We added a README with business context, high-level architecture and information about how components interacted. When another developer needed to work on the project, we modularized the documentation and introduced the first explicit development rules.

Then the agents started skipping things and duplicating work. Larger implementations led to long and painful troubleshooting. We responded with more structured specifications and clearer rules about what the agent could and could not decide.

Documentation became part of the development environment. A coding agent can know a great deal about software engineering and still know nothing about our product, our architectural decisions, our conventions, or why a particular part of the system works the way it does. If that knowledge is missing, the agent fills the gaps with assumptions.

Better context helped, but it exposed another problem. When the same agent planned an implementation and then implemented it, difficult parts could change the plan. Something could be simplified, deferred, or quietly moved out of scope, often with a reasonable explanation. The agent that had been allowed to make the decision was also allowed to reinterpret it when implementation became inconvenient.

That experience eventually produced the process we now call Three Stages of Implementation: Planning, Implementation, and Verification.

The Planner acts as the architect. It understands the requirement, explores the system, defines boundaries and produces the implementation specification, but it does not write code. The Implementer gets that specification and implements it, but it is not allowed to change architectural decisions or scope. If something is unclear, it stops and asks. Verification is separate again: another agent checks what was actually implemented against the agreed plan and requires evidence for what it considers complete.

The separation matters more than the names of the stages. We were trying to prevent implementation difficulty from silently changing a decision that had already been made.

None of this appeared in one design session. Prompt, documentation, rules, specifications, role boundaries and verification accumulated because the previous version of the process had failed in some way.

The process accumulated as the project exposed new failure modes. It began as a prompt. A README followed once the solution grew and needed more persistent context. Modular documentation and the first rules followed once another developer joined and implicit knowledge had to become transferable. Specifications, with planning, implementation, and verification kept separate, followed once the system grew further, agents skipped and duplicated work, and troubleshooting became longer and painful. What is still evolving is planning and story definition, so developers and QA have greater ownership of the problem before implementation.
  1. Just a prompt

  2. The solution grew
    More persistent context was needed

    In response, README

    Business context · high-level architecture · component interactions

  3. Another developer joined
    Implicit knowledge had to become transferable

    In response, Modular documentation + first rules

    Documentation per module · explicit development rules

  4. The system grew further
    Agents skipped and duplicated work
    Troubleshooting became longer and painful

    In response, Specifications + Three Stages of Implementation

    Structured implementation specifications

    Planning → Implementation → Verification

  5. Currently evolving

    Planning + story definition

    Greater ownership for developers and QA before implementation

The project did not stand still while this process was taking shape. Internal testing, Alpha and Beta changed requirements, and the product architecture evolved with them. We kept the same no-manual-code principle through those changes and into production. By then, the system had grown to more than 150,000 lines of code, more than 1,500 unit tests and eight modules, with a complex web application and AI architecture behind it. The process had to survive normal product development, not just the implementation of a fixed specification.

It had to work without me

There was one more test I cared about.

I had spent enough time with the tools to recognize many of their failure modes. I knew when an implementation was starting to drift, when more context was needed, and when something that looked finished probably was not.

If the approach only worked because I had learned how to make it work, we did not have an engineering capability. We had a personal workflow.

Bringing another developer into the project was therefore important for more than capacity. It forced knowledge that had been in my head into documentation, rules and a process that somebody else could follow. Other developers then used the same approach for increasingly complex implementations.

The developer’s role changed as well. They didn’t write production code, but that didn’t mean they were less involved in engineering. More of their work went into understanding the problem, architecture, context, decisions and verification. In practice, the role started moving toward the kind of work we traditionally associate with an architect or team lead: making sure the problem is understood, important decisions are made before implementation, the right context is available, and the result is actually what we intended to build.

We eventually turned those practices into workshops and guidance for the wider engineering organization.

The question got harder

We started with a question about whether agentic development could become reliable engineering practice, including in the large and mature systems we already had.

Territory Planner moved us much further than demos or isolated coding tasks. But it was itself built as an isolated module and integrated with our core system later. The team has continued into more complex problems with the same principle: no manual coding.

The next step is to translate what worked there into teams working directly on much larger, older systems.

Those teams have embraced the idea and the process. Now we have to find out what survives unchanged, what needs to adapt, and where the limits are. There is still a lot to do before I would say this works reliably across all of our systems.

The process we use today came from the places where the previous version failed. As we take it into these systems, I expect we’ll find more things that need to change.