Blog>>Software development>>Copying specification instead of code lets an AI agent rebuild it to fit a new project quickly

Copying specification instead of code lets an AI agent rebuild it to fit a new project quickly

The most reusable thing we build isn't the code

Ask what a software services company actually accumulates over years of client work, and you get a short, familiar list. People, who get better with every project. Reputation, which compounds as long as you don't mess with it. And reusable code, the internal libraries, the accelerators, the boilerplate you find yourself carrying from one project to the next.

That third one is a bit of a misdirection. Code reuse across projects rarely works the way the pitch deck implies. An accelerator gets written against one client's assumptions and needs heavy work before the next client's. Making it fit a new system is its own project: you import the library, then spend time reshaping the fits around it. So then you end up with a compromise. You try to make your libraries and frameworks try to fit all potential use cases. This just makes the generic code complicated and harder to maintain since you need to check new requirements for regression, and every break means a new fork, which in turn pushes your maintenance costs up.

One experiment on a recent project suggests the reusable thing was never the code. It was the description of what the code was supposed to do. And now that itself can speed things up significantly.

Copying the specification, not the component

An engineer here had built a multi-tenant user-management component (a Keycloak-based access control) and specified it thoroughly in the first project: a requirements document and a PRD describing exactly how it should behave. When the same capability was needed in a second, unrelated project, he didn't copy the code across. He copied the specification, handed it to an AI coding agent working inside the second project, and asked it to build.

The result is worth talking about, because the interesting part isn't that it worked. It's how. The agent didn't recreate the old implementation line for line. It read the intent and re-built the component against the second project's existing architecture. And when the imported requirements collided with rules already living in that project, it stopped and flagged it, in effect telling him: your current project specifies one thing here, the component you're importing specifies another, you need to choose. Then it produced a version native to the new project's constraints.

Why this is different from a library

That is a different kind of reuse from anything we had before.

A library is a finished artifact. It carries not just the capability you want but also project-specific assumptions and contracts from when it was written, such as the data shapes, the naming, and the integration points of its original home. Reusing it means importing all of that and then doing the work to make it fit the new system. The capability comes with baggage, and unpacking that has a cost.

A specification carries none of that. It describes an end state; what the component must do, the constraints it must satisfy, the decisions already resolved, and nothing about how those were realized the first time. Hand that description to a capable agent inside a new project, and it creates what’s needed in the new system: it writes the implementation that fits this architecture. The integration work that used to be a separate phase gets absorbed into the generation, because the agent is building from intent rather than adapting an artifact.

This is where the practice touches something being called spec-driven development, the idea that the specification, not the code, is the durable source of truth, and code is generated against it. That idea is already well established. What's far less explored, and what this experiment points at, is what happens when you carry a specification across projects rather than within one. At that point it stops being a way to build software and becomes a way to reuse it, a reuse unit that, unlike a library, arrives with no assumptions to unpick. But a specification only travels that cleanly if it was built to travel.

What made the spec portable

The transfer worked because the documentation was already shaped for it. Each component lived in its own modular document rather than buried in one sprawling spec, so a single one could be lifted out without dragging four unrelated sections along with it. Every document followed the same fixed format, which is what lets one project's writing make sense inside another. It carried a glossary that explained what each term meant in context because an agent reads intent through language, and loose language builds loose software. And it was kept alive, updated as decisions changed, so it described the system as it was rather than as it used to be.

None of that is difficult to implement, but all of it is work. It’s the ordinary discipline that only reveals its value the day you try to move something.

What the client actually gets

For clients, the obvious win is speed; faster delivery is the benefit nobody turns down, and this delivers it. But the reason it's worth writing about isn't the speed alone. It's what comes with it.

A capability that has already been thought through, properly specified, argued over, and its trade-offs settled, never has to be designed from a blank page again. When that access-control model was needed the second time, the labour-intensive part was never the typing. It was the hours of "why this and not that" that produced the specification in the first place. That thinking is done. It gets re-realized in the new project's context in a fraction of the time it took to originate, without dragging the first project's assumptions along behind it.

Faster and cleaner are usually a trade-off. Here they are the same fact. For a client, that means proven patterns delivered at lower cost, without inheriting decisions that were made for somebody else's system.

Where client ownership sits

It's fair to ask where client IP lives in all this, and the answer is reassuring precisely because of how the mechanism works. What travels between projects is the shape of a solved problem, not any one client's proprietary requirements or code. The client-specific detail lives in the implementation, and the implementation is exactly the part that gets left behind and rebuilt. Reuse that operates at the level of general engineering patterns, and reconciles against each project's own constraints, stays on the right side of that line by design.

The honest limits

None of this is a finished methodology. It is one component, moved once, on one project, and worth admitting as such.

It also had an easy start. User management is well-trodden ground, the kind of component a model has seen a thousand versions of. A genuinely novel component such as a routing engine, a protocol state machine, the kind of thing our own network and infrastructure work is full of, is a much harder test, and it's one we haven't run yet.

The re-implementation has to be owned, too. It arrives as new code in a new project, which means it needs the same review, the same tests, and the same accountability as anything else we ship. Nothing here moves responsibility onto the tool; a human still makes the call when intent and reality disagree.

But the direction it points is hard to unsee. For years, the reusable asset a services firm hoped to carry between clients was code, and code turned out to be the thing least willing to travel. The specification, the part we used to treat as scaffolding, may be the asset going forward. We just didn't have anything that could read it and build it quickly.

Wróbel Krzysztof

Krzysztof Wróbel

Chief Technology Officer

Krzysztof has more than 15 years’ experience in the IT industry and has held a range of positions: Software Developer, Team Leader, Project Manager, Scrum Master and Delivery Manager. Krzysztof has led more than a few Rust projects. Taking advantage of the features of this programming language and its...Read about author >

Read also

Get your project estimate

For businesses that need support in their software or network engineering projects, please fill in the form and we'll get back to you within one business day.