Recently, whilst watching The Not Very Grand Tour, I found myself reaching for my notebook. The opening has stayed with me ever since.
“We’re here to celebrate the brilliance of the engine, because I think I’m right in saying that an engine is the most complicated and yet most dependable thing that most of us will ever own.
If you were to leave your mobile phone out in the searing sun of Death Valley for eight hours, it would stop working. But a car engine is expected to spring immediately into life or it’s not good enough.
Imagine if you’d left your dishwasher out in the Arctic winter all day. That wouldn’t work. Your printer won’t work anywhere, and yet a modern car engine can have over 800 parts and they just never let you down.”
“Car makers routinely test down to minus 40. At those temperatures, a human being would get hypothermia and die within five minutes. But a car engine has to work perfectly.”
Excerpt adapted from The Not Very Grand Tour, Series 1, Episode 1, “The Glory and The Power” (Prime Video).
I haven’t been able to shake that opening and how it applies to software development.
Software can evolve, improve, and adapt in ways that physical products never could. In many respects, that is exactly what we’ve spent decades trying to achieve. What stayed with me most was the expectation surrounding all that engineering.
For all their complexity, we expect engines to work. Most of us couldn’t explain every moving part, but we trust them without needing to. If an engine fails to start, we don’t shrug and wonder whether the next update will sort it out. We consider that a failure rather than an inconvenience.
Our relationship with software today feels very different. That applies to how we build it, consume it, maintain it, update it, and ultimately define quality around it. Our ability to continuously improve products has created enormous opportunities, but I also wonder whether it has changed our relationship with confidence, ownership, and what “good enough” means.
When Completion Felt Different
I remember a time when reaching the end of something felt different. Whether it was better is debatable, but it certainly felt different.
Projects had clearer beginnings, middles, and endings. Release notes felt significant because releases themselves were significant. I still remember sitting at EuroSTAR 2013 during the closing session when my HTC One lit up with a notification for a new OS update. I was genuinely excited to read what had changed because those updates felt meaningful. They represented progress that you could see, understand, and look forward to.
That same feeling extended beyond software. I now own my Dad’s leather-bound Encyclopaedia Britannica from 1988. It was already out of date the moment it was printed, and everybody understood that. Yet it represented something that feels increasingly rare today: a coherent body of knowledge. It was a shared reference point. People accepted its limitations whilst also accepting that, for the time, it represented the best understanding we collectively had.
Today, most of our products, services, and information sources exist in a state of continuous evolution. Software updates arrive weekly, daily, or sometimes several times a day. Documentation is maintained rather than published because living documentation is rightly seen as the goal. Products evolve through countless small iterations, while features appear, disappear, and change with very little ceremony.
This has solved genuine problems, although I think we’ve lost something along the way: a sense of completion. I miss the satisfaction of seeing a piece of work through and the confidence that came from accepting trade-offs, making decisions and standing behind the result. I miss the collective understanding that this was the thing we had built. Everyone understood what it did well and where its limitations lay, along with the decisions that had shaped it. There was a shared acceptance that this chapter was complete, and we could turn our attention to the next one.
Perhaps that was inevitable. After all, the world that produced those encyclopaedias, those release notes, and those earlier generations of software was very different from the one we live in today. We can’t return to that world, nor would I want to. The challenge is recognising what we’ve learned along the way and which of those lessons we need to retain as we continue to move forward.
What We Gained
It would be easy to read this as nostalgia. It isn’t.
The move towards continuous improvement has delivered genuine benefits. Security updates and accessibility improvements can reach people faster. Bugs can be fixed sooner. Products can evolve alongside customer needs instead of forcing people to wait months or even years for meaningful improvements.
Cloud computing, observability, feature flags, canary releases, continuous delivery and AI-assisted development have helped make this possible. They’ve lowered the barriers to experimentation and shortened the distance between an idea and a working solution. We can learn from reality rather than rely on prediction alone.
The world that produced boxed software, fixed-time encyclopaedias and lengthy release cycles also came with limitations and missed opportunities. There are many things we were right to leave behind. Being able to improve something later gave us options that weren’t previously available to us. We can respond quickly when circumstances demand it and learn from what actually happens when the software reaches the people using it.
Many of the practices we celebrate today have emerged because organisations recognised that certainty was often an illusion. They created more opportunities to learn and adapt as our understanding developed.
How Completion Changed
The ability to improve something later inevitably changes the decisions we make today. Learning and adapting as we go means making those decisions knowing another iteration remains possible.
If a product can be updated tomorrow, there is less pressure to get everything right before release. We can respond to new information, revisit mitigations and adjust our approaches as our understanding develops. That flexibility gives us more options when thinking about risk and how we develop software. It can also make deferring a decision feel less consequential than it might once have done.
Iteration itself isn’t the problem. Some of the most significant advances in software delivery have come from embracing feedback and learning as we work rather than trying to predict everything upfront. That same adaptability has changed how we think about quality. We accept technical debt knowing we can revisit it and release products that are “good enough” for now. Sometimes those compromises are deliberate and informed. They can also be shaped by delivery pressures, commercial realities or simple optimism about the next iteration.
This discussion can easily be oversimplified as a choice between quality and speed, when most teams want both. The tension is really between certainty and adaptability, and the trade-offs we make between them. As our ability to respond to change has grown, so has our ability to defer decisions or accept risks that teams may once have felt compelled to resolve before release.
Those earlier approaches weren’t necessarily better. The environment has changed, and our relationship with quality has changed alongside it.
The Explosion of Context
These changes aren’t limited to software. They extend to how we learn, how we communicate, and ultimately how we decide what to trust.
Earlier, I reflected on my Dad’s Encyclopaedia Britannica representing a coherent body of knowledge. A shared reference point that people collectively understood, whilst accepting it represented the best understanding available at that moment in time.
Today, we’ve largely accepted that anything we publish is already beginning to age. Documentation is expected to evolve, articles are revised, knowledge bases are living resources, AI can generate answers in seconds, and social media continuously reshapes how those answers are interpreted.
We have access to more information than any previous generation, but we also have access to more competing interpretations of that information. Access to knowledge has become dramatically more democratic. We can learn from experts on the other side of the world, collaborate across continents, and build products with people we may never meet in person. The opportunities are extraordinary, although that abundance also makes understanding harder. The amount of context required to understand almost anything has grown enormously.
Software development reflects the same pattern. Every week seems to introduce a new framework, methodology, AI capability, or prediction about the future of engineering. Before organisations have fully understood one wave of change, another has already arrived behind it. The challenge is working out what deserves our attention and trust based on what applies to our own context.
There’s a growing temptation to treat every successful practice as universally applicable. Organisations copy engineering cultures without sharing the same constraints. Teams adopt delivery models because successful companies use them, not because they solve the problems immediately in front of them. AI-generated recommendations can reinforce the same behaviour, confidently producing answers without understanding the environment in which those answers will ultimately be applied.
The amount of information has increased, but the context required to interpret it has increased even faster. Abstraction becomes essential. Nobody can understand every dependency, framework, AI suggestion, emerging technology, or architectural decision. We increasingly rely on people, tools, and systems to help us navigate that complexity, which makes trust more important than ever.
That thought crystallised for me after reading a recent article by Kristoffer Nordström, who captured it perfectly:
“Trust is a lubricant. Where it’s high, you can leave things unsaid, assume good faith, and skip the paperwork. Where it’s low, you write everything down, prove everything, and get it stamped.”
(Read Kristoffer’s article, A Grand Unified Theory of Metal and Software Testing)
I keep coming back to that observation because it feels increasingly relevant to software development. Trust doesn’t remove the need for evidence, replace accountability, or eliminate the need for testing, observability, and verification. Instead, it allows teams to move with confidence because they understand the systems and people they’re working with.
As our systems become more capable and more complex, trust becomes one of the few things that allows us to continue moving forward without being overwhelmed by the sheer volume of context surrounding us.
What Remains True
One of the most interesting conversations I had at EuroSTAR 2026 was with an attendee returning to the conference after more than 15 years. What they found both reassuring and frustrating was how familiar many of the discussions still felt.
The tooling, terminology, and scale had all changed, yet the underlying conversations sounded familiar. People were still discussing uncertainty, wrestling with quality, and balancing delivery pressure against confidence. Testers, developers, product managers, and leaders are still trying to understand complex systems well enough to make informed decisions.
That observation stayed with me because it reinforced something I’ve believed for a long time. Good principles tend to outlive the technologies that inspired them. The mechanics, implementation, and constraints change, yet the underlying human challenge often remains consistent.
We still need to understand risk and explore products, uncovering useful information that gives people enough confidence to make informed decisions. Quality has never been a fixed destination. It’s always been contextual, shaped by purpose, consequence, expectation, value, and risk.
Those conversations haven’t become less important because AI exists. If anything, they’ve become more important because the pace of change has increased so dramatically. The physical act of building software will continue to evolve. The need to understand what we’re building and why we’re building it, and whether we should release it, remains exactly the same.
The Opportunity in Front of Us
I’m optimistic. AI won’t solve software development, but moments like this give us permission to revisit assumptions that have become embedded in our industry over the years.
AI represents one of the most significant shifts many of us will experience during our careers. It’s changing how software is designed, built, reviewed, tested, and maintained. More importantly, it’s changing the economics of creation. The effort required to turn an idea into working software has compressed dramatically. That’s remarkable progress. But it immediately raises another question: what do we choose to do with it?
SmartBear CEO Dan Faulkner explored this idea in his article, The Levels of Autonomy in Software Development, borrowing the language of autonomous vehicles to describe how intelligent systems gradually take on more responsibility. What interested me most was what that progression towards autonomy implies. As our ability to create software accelerates, our ability to understand, assure, and trust that software has to evolve at the same pace. Otherwise, we haven’t removed risk; we’ve simply moved it. I think that observation extends well beyond AI.
For years, quality has often been implied rather than explicitly discussed. We all agreed quality mattered, but we spent far less time discussing what quality actually meant in particular contexts, which risks were acceptable, and what confidence looked like. This feels like an opportunity to change that by becoming more deliberate about those conversations, without introducing governance for its own sake or pretending every organisation should work exactly the same way.
Quality remains contextual, and so do risk and confidence. The practices and tooling we choose, along with the level of autonomy we aim for, should reflect that context. I’ve explored these ideas previously in Comfort in the Unknown and throughout my Quality Engineering Adoption Framework series. I believe the same principles apply to engineering practices. Copy-and-paste solutions rarely survive contact with reality because they were designed to solve somebody else’s problem.
The opportunity now is to become better at understanding our context and making deliberate trade-offs, while bringing quality into the conversation explicitly. If we can do that, we’ll be in a much stronger position to embrace the opportunities AI presents without losing sight of the principles that have always helped us build confidence in the software we create.
Application Integrity as an Outcome
Earlier this year, I wrote about application integrity as an outcome of teams consistently making informed decisions throughout the lifecycle of building, operating and evolving software (Application Integrity: When Speed Outpaces Understanding). The more I think about it, the more I believe it helps make sense of the shift we’re seeing in how software is built.
Application integrity isn’t something a team achieves simply by adopting AI or buying a particular tool. Following somebody else’s blueprint won’t provide it either. It emerges from understanding the systems we’re responsible for and making deliberate trade-offs. What matters is having confidence that those decisions are appropriate for our own context.
That confidence matters because certainty is becoming increasingly difficult to achieve. Software doesn’t exist in a stable environment. The product we understand today may operate under different conditions tomorrow, whether those differences come from the technology itself or the world around it. AI adds further complexity to something that was already difficult to predict. Absolute certainty feels unrealistic, but we can still achieve confidence through evidence and a shared understanding of the systems we’re responsible for.
For years, we’ve measured success by how quickly we can deliver software, how much of the delivery pipeline we can automate, and how effectively we can reduce the cost of change. Those have all been worthwhile goals. What they mostly tell us, though, is how capable we’ve become at delivering and adapting. We also need to understand the consequences of the decisions we’re making and whether we have sufficient evidence to justify confidence in the result.
That’s why quality cannot remain an implicit assumption. It needs to become an explicit conversation, particularly as the environment in which we make those decisions becomes more complex. AI has accelerated that complexity, but it didn’t create it. If anything, it has exposed assumptions that have existed beneath the surface for years.
Quality, after all, has always been contextual. The right decision for one organisation may be entirely wrong for another. A start-up trying to validate an idea will make different trade-offs from a bank protecting millions of customers, just as a medical device manufacturer operates under different constraints from a gaming studio. What matters is whether those trade-offs have been made consciously and with an understanding of their consequences. That also requires a shared understanding of what success looks like.
Thinking about software as a whole system brings these conversations together. Security, quality and performance contribute to the same outcome instead of competing for our attention as separate concerns. For me, this is where application integrity becomes useful as a way of describing the outcome we’re trying to achieve.
Does the software we’re running still align with the intentions we started with, and do we have sufficient confidence in that answer?
Answering that question requires us to understand what we’re trying to achieve and which risks matter in our context. We need to make trade-offs consciously and use evidence from the software we’re building and operating to understand their consequences. As the software and its context evolve, we need to revisit those decisions and consider whether they remain appropriate.
Testing, observability, security, performance and user feedback can all contribute to that understanding. None provides application integrity by itself. They give us different sources of evidence to help teams make informed decisions about whether the software continues to justify their confidence. AI and automation can support those practices, as can the tools we choose. The confidence we achieve depends on what we understand and learn from the evidence they provide.
So when I think back to the dependability of the modern engine from the opening of this article, I don’t see an argument for software becoming static. Software should continue to evolve and improve. We should embrace the ability to learn from users, respond to change and continuously refine what we build. These aren’t new ideas. They’ve underpinned much of how we’ve thought about software development for decades. What I hope we don’t leave behind is the mindset that made dependability worth celebrating in the first place.
Change has always been inevitable. What’s different now is the pace at which we can respond to it and the expectation that we always will. We still need to understand what “done” means in that environment, whilst ensuring our expectations of confidence and accountability keep pace with our ability to create
What “Done” Means Now
Perhaps “done” was never really about something becoming immutable. It was about reaching a point where we understood what we’d created and the trade-offs we’d made, with sufficient confidence in the result.
We’ve become remarkably good at building software that can change. That progress has changed what completion can reasonably mean. Software will continue to evolve, and the context around it will evolve too. “Done” can still mean that the decisions we’ve made are appropriate based on what we know, the risks are understood, and the software justifies the confidence we place in it.
Tomorrow may give us new information and another decision to make. That’s the advantage of adaptability. What matters is that the possibility of tomorrow doesn’t become an excuse for avoiding the responsibility of today.
Perhaps that’s what remains important about the older idea of completion. We can accept that the software will change tomorrow while still having the confidence to say that today, this is what we’ve built, this is why we’ve built it this way, and we’re prepared to stand behind it.
Leave a comment