Enable javascript in your browser for better experience. Need to know to enable it? Go here.

Are non-functional requirements the missing guardrail for AI-generated code?

LLMs are brilliant at shipping features, but unless you prompt them explicitly they're indifferent to the systemic qualities that keep those features reliable, secure and scalable. More worryingly, they can be completely oblivious to legal and regulatory obligations unless prodded to consider them. Specifying explicit, testable, non-functional requirements are an approach to tackling these blind spots; here’s how they can help.

 

At a recent open space at the Future of Software Development Retreat in Switzerland, a question struck me: could non-functional requirements, arguably the most consistently undervalued artifact in our industry, become a critical guardrail for LLM-generated systems? Perhaps they can — and there’s never been a better time to act.

The LLM feature trap

 

Give an LLM agent cohort a set of feature prompts, and they will deliver. Magically, efficiently and most likely thoroughly, even going beyond what you asked for. The code is output, it deploys, it runs. For a while everything looks perfect; then the non-functional cracks begin to appear.

 

I've watched this play out across organizations of all sizes: systems that are functionally complete but operationally fragile. Response times that degrade under load. Security postures that were never specified and therefore never enforced. Compliance requirements that nobody promoted the model about and so weren’t factored in. Scalability assumptions baked in from the first prompt and then never revisited. Cost and efficiency concerns not given a moment’s consideration.

 

Now, it’s not that LLMs can't incorporate non-functional requirements, but they don't infer them up front. Why should they? We rarely considered them up front when we built our software by hand. Our bias is theirs. The blind spot is the same.

The exec in the driving seat

 

There's a particular dynamic accelerating this problem. A significant number of executives are now vibe coding. They’re prompting their way to working prototypes, many of which seem impressive. From this, and what little they remember from their days at the codeface, they’re drawing conclusions about how easy it is to generate production-ready systems. (This came up directly as a session topic at the Engelberg Open Space: “how do you manage the expectation-reality-risk gap when leadership has personally experienced how fast features can appear?”)

 

The experience isn't misleading, exactly. Features do appear fast, and lots of them. It's the stuff we ask for first; the reason for those systems to exist. What doesn't appear (unless explicitly and additionally specified) is everything in the gaps: the reliability, the performance envelope, the security model, the compliance posture. A prototype that impresses in a demo and a system that holds up under production load are not the same artifact. Executives who conflate the two are accepting implicit architectural decisions based on an incomplete picture, and the teams beneath them are left managing the gap.

Why does this keep happening?

 

Unfortunately we aren’t just experiencing a non-functional requirement specification gap; it's far more fundamental. For too long, too many of us believed that the right non-functional characteristics simply emerge organically from good, clean code. Or, if they don’t, we believe we can sprinkle them on at the end. We comfort ourselves with the lie that they belong in the testing phase, not the specification phase.

 

None of that is true; in fact, it was never true. The "R" in NFR stands for requirement. You start to think about and specify them up front, or you don't get them at the end.

 

Now, to be clear, some non-functional requirements are impossible to specify up front, for example availability SLOs. But we can do enough work at the outset to have an awareness of what range these requirements might sit in, as well as which of the myriad NFR categories are going to be most central to our systems. 

 

LLM-assisted development doesn't change this logic, but it does amplify the consequences of ignoring it. When a developer fails to think about performance constraints, you hopefully notice in code review. When a model skips them across ten thousand lines of generated code, you notice in production.

Andrew Harmel-Law, Thoughtworks
The investment required to get NFRs into the encoded system has never been lower. The potential return — systems that intentionally meet their reliability, security and performance obligations — has never been greater.
Andrew Harmel-Law
Technology Director, Thoughtworks
The investment required to get NFRs into the encoded system has never been lower. The potential return — systems that intentionally meet their reliability, security and performance obligations — has never been greater.
Andrew Harmel-Law
Technology Director, Thoughtworks

The opportunity hiding in plain sight

 

Taken together, I think we’re at an exciting point in the development of how we build our systems, because the cost of realizing and balancing NFRs in those systems has dropped significantly. If you can describe a system's quality requirements in precise, testable language, LLMs can encode them into the architecture, the tests and the deployment configuration.

 

This is a leverage point. The investment required to get NFRs into the encoded system has never been lower. The potential return — systems that intentionally meet their reliability, security and performance obligations — has never been greater.

 

Two trends converge here. While unit tests seem to be declining in relative importance as AI generation makes them cheap to produce and easy to game, higher-level tests in the form of harnesses are becoming more valuable, because they validate behavior and intent rather than implementation. Executable specifications that express non-functional requirements as testable assertions sit comfortably in this second space.

 

With these in place, walking skeletons can now be legion. Spin up candidate architectures, run them through NFR test harnesses, and promote the ones that appropriately balance our most important non-functional requirements. This is architectural iteration at a speed that simply wasn't available before, and one where we can clearly articulate the key quality attributes that matter.

Scope NFRs to the architecture: One size doesn’t fit all

 

We don’t need to be satisfied with this blunt pan-system application of NFRs. One of the most expensive mistakes in NFR work is applying requirements uniformly across a system when they only genuinely apply to part of it. LLMs can help you avoid this, but, again, only if you ask the right questions.

 

Amazon doesn't want all their systems to be PCI compliant, but they need the subsystems that handle payment data to be PCI compliant. What’s more, they benefit from those systems being distinctly separate from everything else, with a compliance boundary that is real, explicit and defensible. Similarly, an insurance broker's SaaS platform doesn't need to be engineered for peak load across the board. The quoting engine needs to handle the surge when a new product launches; the document archive almost certainly doesn't.

 

Precise scoping doesn't weaken your NFRs; it strengthens them. A well-bounded compliance requirement you can actually test and enforce is worth far more than a blanket obligation that quietly erodes everywhere.

 

Getting this NFR scoping right is itself an architectural act. It forces you to think clearly about which parts of your system carry which quality obligations, and to draw boundaries accordingly. I’d argue domain boundaries. LLMs are surprisingly good at helping surface these distinctions. Ask them to identify which components in a proposed architecture are load-bearing for a given NFR, and you often get a useful first cut. The key is that those boundaries then need to be enforced in the architecture, not just asserted in a document.

Visible trade-offs with ADRs

 

As I’ve already suggested, every significant NFR involves trade-offs. Choosing high availability means accepting eventual consistency somewhere. Optimizing for low latency often means higher infrastructure cost. Tightening security controls adds friction to developer workflows. These aren’t failures of design; they’re the very substance of it. The problem is when they remain implicit, undocumented, and therefore to anyone who wasn't in the room when the decision was made.

 

Architecture decision records (ADRs) are the right mechanism for making these trade-offs explicit and traceable. An ADR that references the specific NFRs in tension (citing the requirement for 99.95% availability and the requirement for strict data consistency, for example) creates a record of why the system is the way it is. Future architects, auditors and the AI models helping to extend the system all benefit from that explicit context.

 

This is an area where LLMs add immediate value. Given a set of NFRs and a proposed architectural approach, they can draft the ADR, articulate the trade-offs, and flag the requirements that are in tension. The judgment call remains human, but the documentation burden is significantly reduced (which is usually why ADRs don't get written).

NFRs are the connective tissue linking strategy and systems

 

Behind every architectural trade-off should be technology strategy. And behind that technology strategy should be product and/or business strategy. In practice, these relationships are often assumed rather than made explicit. NFRs are one of the few places where that chain of reasoning has to become concrete.

 

Consider what it means for a business strategy to prioritize rapid market expansion. That decision has NFR implications: higher tolerance for eventual consistency, more aggressive scalability requirements, potentially lower initial security investment with a plan to harden later. Or a strategy built around regulatory markets: compliance and auditability become load-bearing NFRs, and that shapes every architectural choice downstream.

 

As with NFRs, these relationships aren't always complementary. Technology strategy and business strategy can be in genuine tension. Think, for example, of a product team pushing for speed-to-market and a security function insisting on controls that slow release cycles are not simply failing to communicate. They may be representing real strategic conflicts that haven't been resolved at the right level. NFRs surface those conflicts. When you can see which business objectives are pulling against each other through their architectural implications in a testable specification, you have something to take back to the conversation that created the tension in the first place.

 

This is perhaps the deepest value of taking NFRs seriously in an AI-assisted development world. Not just better systems, although you get those, but a clearer, more honest picture of how organizational strategy actually manifests in the things you build.

Five ways to use NFRs as a forcing function

 

All this being said, what are some concrete steps you can take right now to put NFRs into the specs passed to your LLMs?

 

  1. Identify key personas and their quality expectations. Different users experience NFRs differently. A trading desk and a content editor have different latency tolerances. Make this explicit in your specifications from day one.

  2. Work through the trade-off sliders explicitly. Availability vs. consistency. Performance vs. cost. Security strictness vs. developer velocity. LLMs can walk you through these trade-offs systematically, but only if you ask. Build this into your architecture process, not your retrospective.

  3. Turn regulatory and legal frameworks into testable specs. GDPR, SOC 2, PCI-DSS aren't abstract obligations, they're precise requirements that can be expressed as executable tests. Let the model do the translation work; ask them to re-articulate them as testable specs. Then get your experts to validate the results.

  4. Reverse-engineer implicit NFRs from proven exemplars. Benchmark services, such existing cloud provider SLAs,  encode decades of hard-won quality thinking. Extract that thinking with an LLM, make it explicit again as testable specs and use that to set your own baselines.

  5. Generate fixtures and test harnesses directly from NFRs. If a requirement is specified precisely enough to test, it can be used to generate the test data and pipeline configuration. Close the loop between specification and verification. Don't leave it as a manual step.

  6. Generate realistically shaped test datasets. Here I mean both standing data and request shapes and mixes. A performance test that hammers a single endpoint with uniform payloads against an empty database tells you very little. On the other hand, one that reflects the actual distribution of real-world traffic against target real world standing data offers far more confidence around whether your system will hold. NFRs give you the specification from which that realism can be derived, and LLMs can do much of the generation work once these requirements are clear.

What architects and CTOs need to do now

 

So as a senior technologists, what can you start doing right now? Firstly, whatever your level of seniority, stop treating NFRs as a QA concern or a post-launch optimization. Specify them as entry criteria for any AI-assisted development initiative. If a team can't articulate the reliability, performance, security, and compliance profile of what they're building before they start prompting, they're not ready to start prompting.

 

And if you're an executive who's been in the driving seat yourself, one who's felt the thrill of watching a working prototype appear in minutes, your bias-to-action instinct to move fast is an asset. But the gap between a convincing demo and a production system is exactly where NFRs live. The organizations that get this right will be the ones that bring that speed to bear on well-specified systems, not just impressive ones. You also have the greatest chance of knowing the key non-functional goals your systems out to embody. Make these clear and help your teams turn these into the specs that can rove things. You’ll thank yourself later.

 

The tools are there. The cost of doing this well is lower than it's ever been. The question is whether your organization treats non-functional requirements as the serious architectural artifact they are or keeps hoping they'll appear by magic. They won't; they never did.

Explore a snapshot of today's tech landscape