<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Quality-Assurance on scripting.pro</title><link>https://scripting.pro/tags/quality-assurance/</link><description>Recent content in Quality-Assurance on scripting.pro</description><image><title>scripting.pro</title><url>https://scripting.pro/images/og-featured.png</url><link>https://scripting.pro/images/og-featured.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 30 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://scripting.pro/tags/quality-assurance/index.xml" rel="self" type="application/rss+xml"/><item><title>The Tipping Point</title><link>https://scripting.pro/posts/the-tipping-point/</link><pubDate>Mon, 30 Mar 2026 00:00:00 +0000</pubDate><guid>https://scripting.pro/posts/the-tipping-point/</guid><description>Partial AI integration in software development creates a structural instability that leads to a tipping point: a discontinuity in how organizations must configure themselves. This article examines the two stable configurations, the hierarchy of durable assets, and the organizational implications of choosing deliberately versus drifting.</description><content:encoded><![CDATA[<h1 id="the-tipping-point">The Tipping Point</h1>
<p><em>What AI Cannot Replace in Software Development, Part 3</em></p>
<hr>
<p>In a previous article in this series, I proposed a redefinition of legacy: legacy is not a property of the code itself, but a state of the relationship between the code and those expected to maintain it. A system becomes legacy the moment no one in the organization mentally inhabits what they are nonetheless expected to evolve. The problem lies less in the age of the technology than in the developer&rsquo;s lack of deep cognitive engagement with their own code.</p>
<p>This definition raises an urgent question: if generative AI produces code in place of developers, and if those developers only supervise the output without having genuinely thought through the underlying reasoning, are we creating the conditions for legacy at scale from the very first generated line?</p>
<p>The purpose of this article is to examine this question and its organizational consequences. Partial integration of AI into the development process tends to create a structural instability, one that leads logically to what I call a <em>tipping point</em>: a discontinuity in how an organization must configure itself. Getting through this transition also requires a precise understanding of which organizational assets are truly durable, and the answer is less obvious than it appears.</p>
<hr>
<h2 id="cognitive-engagement-as-a-condition-of-maintainability">Cognitive Engagement as a Condition of Maintainability</h2>
<p>When a developer writes code, they do more than produce text: they build a mental representation of the problem, its constraints, edge cases, and trade-offs. This representation lives in procedural memory and enables effective maintenance: the ability to anticipate where things will break, to understand why a decision was made, and to assess the impact of a change without simulating the entire system.</p>
<p>When a developer merely supervises AI-generated code, this mental representation does not fully form. They can read the code, validate its apparent logic, and approve a pull request, but they have not traversed the reasoning that produced it.</p>
<blockquote>
<p><em>Supervising AI-generated code without engagement in the reasoning that produces it is functionally similar to maintaining a legacy system: one understands what the code does, but not why it does it that way.</em></p>
</blockquote>
<p>I am not criticizing generative AI as such. I am describing a structural property of the situation: intellectual ownership of code is a consequence of the creation process, not of reading the result, and review cannot supply it after the fact.</p>
<hr>
<h2 id="the-tipping-point-a-structural-discontinuity">The Tipping Point: A Structural Discontinuity</h2>
<p>Organizations that integrate generative AI without changing the structure of responsibility tend to drift into an unstable intermediate state, which typically becomes visible only during the first serious incidents.</p>
<p>Developers believe they are supervising, but have progressively lost the capacity to intervene autonomously. The system keeps growing, technically modern and cognitively orphaned. In several AI-assisted transitions I have observed, the pattern is consistent: productivity is high for months, velocity metrics look excellent, confidence is strong. Then comes the first non-trivial evolution (a scaling constraint, an architectural shift, or a subtle behavioral regression), and no one can confidently explain why the system behaves as it does.</p>
<p>The problem with gradual transition is precisely that it produces this situation without anyone having made the deliberate choice to accept it. The organization bears the costs of both models without benefiting from the advantages of either.</p>
<p>The relationship between human intellectual ownership and AI integration is not linear. Below a certain threshold of engagement, maintainability tends to collapse in a way that is difficult to reverse once the accumulated gap reaches critical mass. This threshold is the tipping point. It separates two internally stable configurations from a fragile intermediate zone.</p>
<hr>
<h2 id="the-two-stable-configurations">The Two Stable Configurations</h2>
<p><strong>The Human-Author Model</strong></p>
<p>Humans remain the cognitive authors of the code. Generative AI serves as an accelerator for boilerplate, refactoring, or exploration, but the developer still traverses the reasoning. They can explain every significant decision, debug unexpected behaviors, and anticipate the consequences of changes. This model preserves long-term maintainability and integrates naturally with existing quality practices. Its main constraint is speed: AI amplifies productivity but does not replace the human traversal of reasoning.</p>
<p><strong>The Agent-Author Model</strong></p>
<p>Agents become responsible for producing the code. Humans step out of the traditional technical loop. In exchange, the organization reconfigures itself deeply: code loses its status as a durable strategic asset and becomes a temporary instantiation of behavior defined elsewhere, rewritten on demand from specifications and behavioral tests, which now form the primary reference. Classical technical debt tends to be largely replaced by a different form of accumulated cost centered on specification quality and test completeness. Architecture becomes declarative: focused on <em>what</em> the system must do, not <em>how</em>.</p>
<p>Which of these assets, then, are truly durable over time? Current agent-oriented frameworks largely leave this question unanswered, and it deserves careful examination before committing to this model.</p>
<hr>
<h2 id="the-hierarchy-of-durable-assets">The Hierarchy of Durable Assets</h2>
<h3 id="specification-drift-and-the-limits-of-natural-language-stability">Specification Drift and the Limits of Natural Language Stability</h3>
<p>Current agent-oriented frameworks tend to treat specifications as a stable abstraction layer above the model. The assumption is that you write the spec once and can reliably regenerate the system across model versions and technology changes.</p>
<p>This assumption deserves scrutiny. Practitioners already observe <em>prompt drift</em>, <em>LLM drift</em>, and <em>context drift</em>: the gradual degradation in how a specification is interpreted as models evolve. A specification that worked reliably with one model version can produce subtly different behaviors in its successor, not because the spec changed, but because the model&rsquo;s implicit understanding of its constructs has shifted. The long-term stability of a specification is coupled, implicitly, to the stability of the model that interprets it.</p>
<p>In systems meant to last years or decades, this <em>specification drift</em> becomes more than a prompt engineering inconvenience; it threatens the long-term reproducibility of the system itself. Subtle divergences can accumulate in the spaces between explicit requirements, even when tests continue to pass on covered behaviors. Current frameworks do not yet formally manage this coupling.</p>
<h3 id="the-asset-hierarchy">The Asset Hierarchy</h3>
<p>This leads to a clear hierarchy of durability:</p>
<ul>
<li><strong>Code</strong> is ephemeral by design, the least durable asset. It is regenerated, not evolved.</li>
<li><strong>Specifications</strong> are semi-stable. More durable than code, but subject to semantic drift relative to evolving models. They require active, periodic re-validation.</li>
<li><strong>Behavioral tests</strong> constitute the most stable anchor. A well-designed test yields a binary, objective verdict (it passes or it fails), independent of any model&rsquo;s interpretation of intent.</li>
</ul>
<p>However, the durability of tests ultimately rests on the quality of the human oracle that defines them. A poorly conceived test can protect incorrect behavior as reliably as a good one protects the right one. This brings us back directly to the oracle problem examined in the first article of this series: tests are only as strong as the human reasoning behind them.</p>
<blockquote>
<p><em>In the agent-author model, the true organizational anchor is the behavioral test suite, but only insofar as it crystallizes genuine human understanding of expected behavior. Tests are the formal record of the oracle&rsquo;s judgment, not a substitute for it.</em></p>
</blockquote>
<h3 id="quality-assurance-as-a-foundational-discipline">Quality Assurance as a Foundational Discipline</h3>
<p>This inversion is structural. In traditional development, QA is positioned as downstream validation. In the agent-author model, defining, maintaining, and evolving behavioral tests becomes the first step in the process, and the most consequential one.</p>
<p>The quality engineer who designs solid behavioral test suites is no longer in a support role. They steward the behavioral knowledge that makes reliable system regeneration possible across time, model versions, and technology generations. QA shifts from a verification function to a core strategic competency.</p>
<hr>
<h2 id="the-human-role-in-the-agent-author-model">The Human Role in the Agent-Author Model</h2>
<p>Agents operate within a bounded context, a necessary reduction of reality that always implies information loss. The real world is structurally larger than any context an agent can receive: regulatory constraints, internal political dynamics, implicit contractual commitments, strategic directions, stakeholder relationships. None of this is fully visible to a system operating within a defined context.</p>
<p>A concrete example: agents might correctly choose a technically superior tool within their context, yet overlook a token cost ten times higher, an unevaluated vendor dependency, or a strategic direction not yet formally communicated. These elements simply were not in their context.</p>
<p>The human role is therefore not to supervise code, but to maintain alignment between the space of agents and the real world that will never be entirely captured in a context. It is a <em>translation role</em>: transposing the constraints, objectives, and values of the real world into clear intentions for systems that operate within bounded spaces. Humans retain responsibility for the <em>what</em> and the <em>why</em>. Agents manage the <em>how</em>.</p>
<p>In this model, IT professionals do not disappear; they migrate. Their expertise moves from writing code to mastering specification quality, behavioral verification, and domain knowledge. The longstanding comprehension gap between business and IT dissolves here through a deeper reconfiguration of the IT role itself.</p>
<hr>
<h2 id="a-historical-precedent-the-transition-to-deep-learning">A Historical Precedent: The Transition to Deep Learning</h2>
<p>The shift I describe has a direct parallel in AI&rsquo;s own history. For several decades, symbolic expert systems emphasized full interpretability: every rule was explicit and traceable. The transition to deep learning abandoned this property. Neural networks produce impressive results through mechanisms their creators cannot fully explain. The debate was settled by results rather than philosophy: deep learning produced capabilities that symbolic systems could not reach.</p>
<blockquote>
<p><em>AI became what it is today because the scientific community collectively accepted abandoning internal interpretability as a necessary condition of a system&rsquo;s validity. Observable performance replaced transparency of mechanism as the primary evaluation criterion.</em></p>
</blockquote>
<p>The parallel with the tipping point is direct. In the agent-author model, one abandons code comprehensibility as a condition of maintainability. It is replaced by the quality of specifications and, above all, the completeness of behavioral tests. Observable performance replaces internal understanding.</p>
<p>This precedent does not prove the tipping point is inevitable everywhere, but it shows that abandoning one form of comprehensibility for another form of validation can produce significant gains, and that resisting the shift can carry a competitive cost.</p>
<hr>
<h2 id="the-organizational-question-the-greenfield-model">The Organizational Question: The Greenfield Model</h2>
<p>For large organizations with decades of technological history, transforming the existing base is rarely feasible in the short term. Legacy systems (those for which intellectual ownership has already been lost) do not lend themselves to migration toward the agent-author model without massive prior investment in specification.</p>
<p>The coherent pattern is the <em>greenfield model</em>: creating a new entity, such as a division, a subsidiary, or a distinct organization, configured according to the agent-author model from day one. This entity develops the competencies in specification, declarative architecture, and behavioral testing while the existing organization continues under the human-author model.</p>
<p>This pattern is not without precedent. Large financial institutions have used it for digital transformation initiatives. Cooperatives have created subsidiaries to explore new business models without risking their operational core. When transformation requires a reconfiguration too deep to be achieved from within, one creates something new alongside.</p>
<p>The resulting coexistence, with units in human-author mode managing the existing systems and units in agent-author mode building the future, is stable when the boundary between the two models is explicit and deliberate. The danger lies in blurring the line between them, not in having two models.</p>
<hr>
<h2 id="implications-for-practitioners-and-decision-makers">Implications for Practitioners and Decision-Makers</h2>
<p>Three practical observations emerge:</p>
<p><strong>First</strong>, diagnose honestly. The relevant question is not &ldquo;what percentage of our code is AI-generated?&rdquo; but &ldquo;can our developers intervene autonomously and confidently in the code that exists?&rdquo; An uncertain answer signals that the organization is likely already in the unstable intermediate zone, without having made the deliberate choice to be there.</p>
<p><strong>Second</strong>, choose deliberately. Maintaining the human-author model requires frameworks that preserve developers&rsquo; traversal of reasoning: not excluding AI, but ensuring they remain genuine authors of what they maintain. Moving to the agent-author model demands significant prior investment in specification quality and behavioral tests <em>before</em> the transition, not after.</p>
<p><strong>Third</strong>, protect the right asset. Resist the temptation to treat specifications as the primary investment. The behavioral test suite, grounded in rigorous human judgment, is the more stable and strategically critical anchor. Specifications communicate intent to agents; tests verify that the intent was correctly understood. Only the latter survives model evolution without active re-validation.</p>
<p>The intermediate zone, where humans supervise code they have not genuinely inhabited without strong specifications and tests, is a trap rather than a transitional state. It is precisely where tomorrow&rsquo;s legacy forms, at the accelerated speed of generative AI.</p>
<hr>
<p>In the previous article in this series, I argued that the capacity to judge the correctness of a result is an irreplaceably human competency. Machines can evaluate outputs; what they cannot do is define what constitutes a correct output, because that requires an understanding of the real world that exceeds any formalizable context.</p>
<p>The tipping point does not contradict this thesis. It extends it upward. In the agent-author model, humans no longer judge the correctness of code. They define the behavioral tests that encode what correctness means, and they translate the real-world constraints that no bounded context will ever fully capture. The oracle does not disappear: it moves upstream and becomes the organization&rsquo;s most critical competency.</p>
<p>AI is already transforming software development.<br>
The question is whether your organization will deliberately choose its tipping point, or simply drift into one without realizing what it has surrendered.</p>
<hr>
<p><em>Gabriel Mailhot</em><br>
<em>Organizational Engineering for the AI Era<br>
Researcher (2005–2010): Image Processing &amp; Creative AI<br>
Business Expert / Domain Expert (2010-2026): Software Architecture, Software Development and Quality Practices</em></p>
<p><em>Series: <a href="/series/what-ai-cannot-replace-in-software-development/">What AI Cannot Replace in Software Development</a></em></p>
]]></content:encoded></item><item><title>Unit Testing and Artificial Intelligence: The Oracle Problem</title><link>https://scripting.pro/posts/the-oracle-problem/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><guid>https://scripting.pro/posts/the-oracle-problem/</guid><description>A perspective on the structural limits of automated test generation, and what they reveal about the nature of work in software engineering.</description><content:encoded><![CDATA[<p><em>What AI Cannot Replace in Software Development, Part 1</em><br>
<em>A perspective on the structural limits of automated test generation, and what they reveal about the nature of work in software engineering.</em></p>
<hr>
<h2 id="the-problem-nobody-names">The Problem Nobody Names</h2>
<p>A few years ago, I reviewed a software development contract between an organization and a vendor. The terms were standard: a fixed delivery date, a penalty clause for late delivery, and an obligation to maintain 80% code coverage. The intent was twofold. It would protect the organization from negligence, and guard against the kind of deliberate opportunism that governance frameworks exist precisely to prevent.</p>
<p>When the project fell behind schedule, the vendor found a way to satisfy the coverage requirement without slowing down: they had the AI generate unit tests after the developers had written the code. The coverage metric turned green, the delivery date was met, and the penalty was avoided.</p>
<p>Then came UAT, and the acceptance phase surfaced problem after problem. The tests had protected nothing, because they had been written to describe what the code did rather than what the system was supposed to do.</p>
<p>The contract had specified a metric, and the metric had been satisfied. The organization had paid, contractually and technically, for a test suite that institutionalized its own blind spots.</p>
<p>I am often asked whether it is a good idea to let AI generate unit tests. That experience is part of my answer. The complete answer is more interesting, because it touches on the nature of testing, the source of truth in a software system, and what AI actually changes in the work of a developer.</p>
<hr>
<h2 id="the-test-oracle-problem-what-research-already-knows">The Test Oracle Problem: What Research Already Knows</h2>
<p>In the software engineering literature, the problem has a precise name: the test oracle problem. It designates the central challenge of any automated test generation. How do you automatically distinguish correct behavior from incorrect behavior?</p>
<p>Automated generation tools, including those based on large language models, produce what are called regression oracles: tests that capture what the code does today, not what it should do.</p>
<p>When you ask AI to generate tests from source code, you invert the causality of testing. The test becomes a mirror of the implementation, and if the implementation contains a bug, the test will capture it in order to protect it rather than flag it. Beyond introducing a bug into the system, you put in place an infrastructure that resists its correction.</p>
<p>Alan Turing demonstrated formally that one can never prove a program is free of all bugs. This is a consequence of undecidability: no general procedure can determine whether a program behaves correctly in all cases. In practice, this means there will always be incorrect behaviors the code produces without anyone having intended them. When AI takes the code as its source of truth, it freezes these invisible behaviors at industrial scale.</p>
<p>The test oracle problem is not new; what AI changes is its scale. A developer writing tests manually is constrained by the time it takes. An AI generating tests from code can institutionalize incorrect behavior at industrial speed, producing in seconds a test suite that would have taken days to write and that is wrong in exactly the same way throughout.</p>
<hr>
<h2 id="what-kent-beck-understood-and-what-automated-generation-ignores">What Kent Beck Understood, and What Automated Generation Ignores</h2>
<p>Kent Beck, in his Test-Driven Development philosophy, establishes a distinction that remains underappreciated: a test must speak to behavior, not implementation. Behavior is the very reason the code needs to exist. Unlike code, it is stable: it survives refactorings, technology changes, and complete rewrites.</p>
<p>A behavior-based test is a living document of the system&rsquo;s intent. Future developers will refer to it to understand what the system must do, as opposed to what it happens to do today.</p>
<p>A test generated from code lies about that intent, documenting the accident rather than the design.</p>
<p>This has an organizational consequence the technical literature does not make explicit. An untested bug can be discovered and fixed freely. A bug protected by a test becomes a norm. Any attempt to correct it will cause the test to fail, creating institutional pressure not to fix it. At that point the problem is one of governance as much as of technique.</p>
<blockquote>
<p>A test generated from code does not protect against bugs. It protects against change, including the change that would fix the bug.</p>
</blockquote>
<hr>
<h2 id="the-limits-of-specifications-as-a-substitute">The Limits of Specifications as a Substitute</h2>
<p>One might think the problem is solved by asking AI to generate tests from specifications rather than from code. This is a direction academic research is actively exploring, enriching prompts with documentation, developer comments, and semantic context. It is better, but it is not enough.</p>
<p>A specification is always incomplete. Consider a typical example: a spec describes how a search feature should return results ranked by relevance. It says nothing about what happens when two users submit the same query simultaneously, or how the system should behave when the underlying index is being updated, or what &ldquo;relevance&rdquo; means when the user&rsquo;s implicit intent differs from their explicit query. No negligent author forgot these edge cases. They belong to the class of conditions that only become visible when the system meets real users in a real environment.</p>
<p>Human judgment detects these gaps naturally, by confronting the spec with lived experience of how systems fail, how users actually behave, and what the production environment will impose. AI generates tests that are consistent with what is written, without the ability to signal what is missing.</p>
<p>A better model will not remove this limitation, because it is structural rather than temporary: understanding the real world, with its complexity, ambiguity, and unspoken assumptions, remains a capability current systems do not possess.</p>
<hr>
<h2 id="the-real-asset-of-a-software-organization">The Real Asset of a Software Organization</h2>
<p>In a world where AI generates code, the real asset of an organization becomes its specifications and its tests.</p>
<p>The code itself will be rewritten, migrated, replaced. What endures is the knowledge of expected behavior, captured by humans who understand the problem in its full complexity.</p>
<p>This conclusion does not appear in the technical literature or in analyst reports, which measure the value of AI in terms of volume produced. It is a thesis about the nature of a software organization&rsquo;s intellectual asset, and it radically changes what is worth investing in.</p>
<p>Organizations that have understood this invest in the quality of their specifications and in the human rigor of their tests. Those that delegate both to AI, working from existing code, leave their technical debt in place while making it harder to see and harder to correct.</p>
<p>The question of what the developer must retain, and what can legitimately be delegated, extends beyond the problem of tests alone. It touches on the cognitive division between human and machine, which is the subject of the next article in this series.</p>
<hr>
<blockquote>
<p>If the real asset of a software organization is not its code but its understanding of expected behavior, who in your organization is responsible for building and protecting that understanding? And what happens to it when the pressure to deliver is high enough?</p>
</blockquote>
<hr>
<p><em>Gabriel Mailhot</em><br>
<em>Software Architect and Software Engineering Quality Advisor</em><br>
<em>Series: <a href="/series/what-ai-cannot-replace-in-software-development/">What AI Cannot Replace in Software Development</a></em></p>
]]></content:encoded></item><item><title>Legacy Is Not a Property of Code</title><link>https://scripting.pro/posts/legacy-is-not-a-property-of-code/</link><pubDate>Sun, 15 Mar 2026 00:00:00 +0000</pubDate><guid>https://scripting.pro/posts/legacy-is-not-a-property-of-code/</guid><description>Legacy code is not about age, language, or missing tests. It is the state of a system whose meaningful relationship with its human maintainers has been broken.</description><content:encoded><![CDATA[<p><em>A sociotechnical perspective on what makes code legacy, and what actually keeps it alive.</em></p>
<hr>
<p>In the organization where I work, there is a mainframe COBOL system that has been running at the core of operations for decades. By every conventional definition, it should be legacy: old language, old architecture, a technology that most developers under forty have never touched.</p>
<p>It is not legacy. The team responsible for it is among the most mature and capable in the organization. They understand every decision embedded in that system: the constraints that shaped it, the business rules it encodes, the edge cases it handles. They can explain why a specific field is structured a certain way, what regulatory requirement drove a particular branching condition, and exactly what would happen downstream if you changed it. There is no question about the system they cannot answer.</p>
<p>Contrast that with a microservices architecture I reviewed at another organization. It had been built two years prior on a modern stack, with 85% test coverage and a full CI/CD pipeline. The team that built it had since been reorganized. No one could explain why the service boundaries had been drawn that way. Modifying anything felt like defusing a bomb. That system was legacy from the inside out, despite being less than two years old.</p>
<hr>
<p>Michael Feathers defined legacy code as code without tests. The definition is pragmatic and useful, since tests reduce the uncertainty of change, but it is incomplete.</p>
<p>Tests are not the cause of human engagement with code. They are a partial substitute for its erosion.</p>
<p>When a team genuinely understands a system (its decisions, its constraints, its intended behaviors), tests are almost redundant as a knowledge preservation mechanism. When that understanding has eroded, tests become the last line of defense against the unknown. They matter enormously in that role. But their presence does not mean the understanding is there.</p>
<hr>
<p>Legacy is not a property of the code. It is the state of the relationship between the code and the people responsible for it.</p>
<p>A system becomes legacy at the moment when no one can confidently answer: <em>why does it work this way?</em> Not <em>how</em>, since any developer can read code, but <em>why</em>: the reasoning, the trade-offs, the domain constraints that shaped the implementation. When that knowledge is gone, whether through team turnover, disengagement, or the gradual accumulation of changes nobody fully understood, the system has crossed the threshold.</p>
<p>This distinction matters because it changes what the problem actually is. If legacy is a technical property, the solution is technical: rewrite, refactor, add tests, modernize the stack. If legacy is a relational property (a broken link between a system and its human maintainers), then the solution requires restoring that link. Sometimes that means tests. More often it means something harder: rebuilding the shared understanding of what the system is supposed to do, and why.</p>
<hr>
<p>Tests, documentation, and architecture diagrams are mechanisms for transmitting intent across time and team boundaries. They matter, but they are proxies for something more fundamental: the capacity of a human being to understand a system well enough to change it with confidence.</p>
<p>As long as that capacity exists, the software is alive, regardless of its age, its language, or its test coverage.</p>
<p>The moment it disappears, the system becomes legacy. And no amount of refactoring will fix that without first addressing the human dimension.</p>
<hr>
<p><em>This is the foundation on which the rest of this series is built. The next article takes up the question that follows: what happens to that human capacity when AI generates the code?</em></p>
<hr>
<p><em>Gabriel Mailhot</em><br>
<em>Software Architect and Software Engineering Quality Advisor</em><br>
<em>Series: <a href="/series/what-ai-cannot-replace-in-software-development/">What AI Cannot Replace in Software Development</a></em></p>
]]></content:encoded></item></channel></rss>