{"slug": "the-myth-of-complete-specifications", "title": "The Myth of Complete Specifications", "summary": "Specification-driven development's goal of a complete upfront specification is a myth, as demonstrated by Winston Royce's 1970 paper which argued that waterfall methods are risky and invite failure. Royce showed that later development phases inevitably reveal unknown constraints, making complete specifications impossible and requiring iterative refinement.", "body_md": "Specification driven development (SDD) encourages a \"complete\" spec written up-front in the hope that the detail can be used to more accurately drive AI agentic code generation.\n\nThis article suggests that producing a complete specification flies in the face of reality and argues that spec-driven development can be used incrementally.\n\n## What we have always known about waterfall\n\nWaterfall does not work. If you agree with this, [skip this section](#tinyslice).\n\nIn Winston Royce's widely quoted paper from 1970, \"MANAGING THE DEVELOPMENT OF\nLARGE SOFTWARE SYSTEMS\", the author states that a software development process\nbased on \"requirements → design → coding → testing → operations\" does *not*\nwork. He explicitly says: \"I believe in this concept, but the implementation\ndescribed above is risky and invites failure.\"\n\nThe concept *is* sound. In software engineering, requirements must be captured\nbefore designing a solution that a software engineer will then code, test and\nrelease into production (operations). But a strict forward-only *implementation*\nof this does not work. Completing all requirements before moving on to design\nand completing that 100% before coding does not acknowledge the learning that\nwill take place during the separate phases. When coding it is common for\nquestions to arise that affect requirements that, in turn, impact the design.\n\nBased on Royce's nine years of experience back in 1970 he knew that waterfall was risky and invites failure.\n\nIn the fifty years since, history has conspired to lay the Waterfall Method at Royce's door when, in fact, he was arguing for the opposite.\n\n## Royce was *not* advocating for waterfall\n\nHe described why Waterfall was risky and invited failure with an example. He said that when testing happens too late, unknown constraints only appear at the end, and the result is a need for costly rework.\n\nAs a strawman, he presented the classic waterfall diagram (figure 2 of his paper, not included here) with work proceeding forwards-only, from \"analysis → design → coding → testing\". He was not advocating waterfall as a realistic approach.\n\nHe was presenting what really happened on software delivery projects and showed that a forward-only waterfall did not acknowledge the reality of developing software where later events raise questions about earlier decisions.\n\nIn figure 3 (not included here) he showed that activities in process neighbours, such as program design and coding, affect and influence one another.\n\nHe then presented wider ranging effects in figure 4:\n\nto illustrate what goes wrong with waterfall and why a siloed and stepwise sequence of \"analysis → design → coding → testing\" does not work.\n\nRoyce said:\n\n\"The testing phase which occurs at the end of the development cycle is the first event for which timing, storage, input/output transfers, etc., are experienced as distinguished from analyzed. These phenomena are not precisely analyzable.\"\n\nThis is a statement that you do not know what you have until you test it. This is because such phenomena are not analyzable and they only surface under test. There are certain aspects of your system that you cannot know at the analysis stage, and you will only discover what they are, and their wider impact, during testing.\n\nFor example, specifications describe intended user inputs but users provide edge-case inputs.\n\nUnexpected Unicode characters can break a parser or a device sends malformed packets that a specification never anticipated or a user performs an action sequence no analyst imagined.\n\nA specification defines a number of assumed input types. But only at the coding stage does it become clear what set of input instances can be entered, and the set of instances will highlight a number of missing input types. In short, the specification identifies the happy path, and only at coding do we see all paths.\n\nHe then says:\n\n\"If these phenomena fail to satisfy the various external constraints, then invariably a major redesign is required… The required design changes are likely to be so disruptive that the software requirements upon which the design is based and which provides the rationale for everything are violated. Either the requirements must be modified, or a substantial change in the design is required.\"\n\nRoyce was noting that the testing that you can see in figure 4 was too late and that testing late in delivery may require a substantial (and costly) change.\n\n## The 5 steps that introduce iterative, incremental engineering\n\nRoyce then presents 5 steps that break the idealised approach.\n\n- Step 1: program design comes first\n- Step 2: document the design\n- Step 3: do it twice\n- Step 4: plan, control and monitor testing\n- Step 5: involve the customer\n\nWaterfall assumes \"requirements → analysis → design → code → test\" so placing a\nprogram design phase at the start *breaks waterfall*.\n\nRoyce is clear that documentation must be kept up to date, that it is\n*evolving* and not a one-off per phase. He is clear that it is not fixed once\nproduced, never to be touched again.\n\nIn step 3 the author states \"Arrange matters so that the version finally delivered… is actually the second version insofar as critical design/operations areas are concerned.\" This is iterative prototyping, not waterfall.\n\nIn talking about testing for step 4 he says testing must be planned and staged with multiple test steps. He is clear that testing must be prepared for from the beginning.\n\nRoyce warns that \"The testing phase… is the first event for which timing, storage, input/output transfers… are experienced… If these phenomena fail… a major redesign is required.\"\n\nThis is an anti-waterfall argument. Royce was arguing that testing cannot be left to the end because the end is too late to fix whatever you discover. Testing must be throughout the process and this implies testing must be incremental. What you learn from testing is fed back into earlier stages and you iterate. This is software engineering reality and Royce knew this in 1970.\n\nFor step 5, \"Involve the customer\", Royce stated: \"It is important to involve the customer in a formal way so that he has committed himself at earlier points before final delivery.\" In his summary, he lists \"Involve the customer\" as one of five core guidelines, making customer involvement a first‑class concern rather than a one‑off at the end.\n\nThis is the opposite of waterfall because waterfall assumes customer involvement only at the beginning and end.\n\n## What Royce was describing\n\nIn describing steps 1 to 5, Royce is describing an early form of iterative, risk-driven development.\n\nHe is saying that if you try to run waterfall, you will fail. And that if you add everything you need to make that failed process work (steps 1 to 5), you no longer have waterfall: you have iterative delivery.\n\n### He was presenting a strawman\n\nHis presentation is a strawman. He describes a theoretic *ideal* in figure 2,\nthe forward only process. This was picked up as the Waterfall Method. But Royce\nwas not advocating for it. He was presenting it as an idealised theory, and\nthat to do real software delivery, another approach was required that he outlined\nin steps 1 to 5.\n\n### Royce was advocating an iterative approach\n\nTo show what this other approach was, he elaborated figure 2 into figure 3, with backward steps between neighbours in the classical Waterfall.\n\nThe author then stated:\n\n\"there is an iteration with the preceding and succeeding steps [from figure 2] but rarely with the more remote steps in the sequence. The virtue of all of this is that as the design proceeds the change process is scoped down to manageable limits.\"\n\nHe is stating that there can be iteration between any pair of stages: \"rarely with the more remote steps\" does not rule out that iteration cannot occur at any stage, only that such iteration is rarer than for stages that are neighbours.\n\nHe is also pointing out that things will change: \"as the design proceeds, the change process is scoped down to manageable limits.\" Royce knew in 1970 that change was fundamental to delivery, and that effort had to be expended to explicitly handle it.\n\nHe goes on to say:\n\n\"At any point in the design process after the requirements analysis is completed there exists a firm and closeup, moving baseline to which to return in the event of unforeseen design difficulties.\"\n\nRoyce is acknowledging that there may be unforeseen design difficulties and that those involved may have to return to earlier phases to mitigate this.\n\nThe caption for figure 3 shows his grasp of reality: \"Hopefully, the iterative interaction between the various phases is confined to successive steps.\" This acknowledges the reality that this is not always the case.\n\nRoyce explicitly states this reality in the caption for figure 4: \"Unfortunately, for the process illustrated, the design iterations are never confined to the successive steps\". Royce knew that software engineering did not proceed neatly, forward-only step-by-step, and that progress in one activity may require another to be revisited.\n\n## What Royce presented\n\nWinston Royce gives a summary of his approach in figure 10:\n\nHe says:\n\n\"Figure 10 summarizes the five steps that I feel necessary to transform a risky\ndevelopment process [figure 2, classical Waterfall] into one that will provide\nthe desired product. I would emphasize that each item costs some additional sum\nof money. If the relatively simpler process without the five complexities\ndescribed here would work successfully, then of course the additional money is\nnot well spent. *In my experience, however, the simpler method [Waterfall] has\nnever worked on large software development efforts* and the costs to recover\nfar exceeded those required to finance the five-step process listed.\"\n\nHis last sentence says it all. Italics have been added.\n\n## Why does waterfall fail\n\nWaterfall fails for two main reasons.\n\n- it is not possible to know everything about a product before you start coding\n- facts that come to light today necessitate revisiting earlier decisions\n\n### Attempting to know everything is a fool's paradise\n\nIf a system contains even a single component capable of unbounded variation, then a finite specification cannot capture all possible behaviours, and any claim to completeness contradicts itself.\n\nAssume we have fully specified a system called S. Every possible behaviour is\nknown and listed. This complete specification is called Spec(S). Because any\nwritten specification is finite 1, Spec(S) contains only finitely many\nbehaviours.\n\nWithin S, there is a component A that can produce specified behaviour at random. Randomness gives A unbounded variation. Component A can generate arbitrary sequences of behaviours. Such sequences are not described in Spec(S), because Spec(S) is finite and cannot list everything in a set with no end.\n\nTherefore, the specification is not complete.\n\nThis is a self-contradiction. No finite specification can describe everything about a system that contains unbounded variation.\n\nEven if the components of the system do not exhibit unbounded variation, the design of the environment that the implementation of S is deployed within introduces it.\n\nReal multi-service, distributed systems contain effective unbounded variation through timing jitter, concurrency interleavings, randomness, and the combinatorial explosion of partial‑failure sequences.\n\nIn a distributed system nodes fail, messages can be delayed, reordered, duplicated or dropped, clocks drift, partitions break and heal, and nodes recover. Each of these can occur in any order, at any time, with any overlap. This is effectively unbounded variation.\n\nA distributed system on its own can generate more behaviours than any finite specification can enumerate.\n\n### If there is no randomness\n\nIf component A has no unbounded variation, then Spec(S) can be complete.\n\nThis requires A to be fully deterministic, have no randomness and be subject to no timing jitter, be unaffected by concurrency, cannot learn or adapt, and has no interaction with other non-deterministic components.\n\nIf this is true, A's behaviour space is finite.\n\nIf *every* component in S is like this, then Spec(S) *can* enumerate all\nbehaviours, and Spec(S) in this case is complete.\n\nHowever, this is not a real-world system. It is the world of finite automata, simple synchronous circuits, textbook Turing machine examples, and closed, trivial, non-interactive systems. Such systems have value, but they are toy systems. They are not real systems.\n\nIn short, you cannot fully specify a real system because that system will contain unbounded variation and the runtime environment that hosts that system will definitely introduce such variation.\n\n## Royce's key observation\n\nRoyce's key insight was that Waterfall does not work because you cannot know whether some aspects of your work are right until you test them.\n\nThis may be the explicit test of code or it may be the implicit test of your idea by deploying to production.\n\nEither way, attempting to do a complete job is risky because that completeness pushes your ability to test your ideas out too far.\n\nWhat is preferable is to do a tiny slice, test that code and get it into the hands of your users, and if their signals are positive, do more.\n\nIf you design more up front, code all of it and deploy that you risk aspects of that fuller deployment not being used or liked. You could have avoided this with the tiny slice approach.\n\n## TinySlice\n\nI define TinySlice to encourage you to think in the smallest of terms possible. In the TinySlice approach, much less is more.\n\nTake a coherent tiny slice that solves a user problem and perform all the work from product and engineering to refine that into production. You will then get valuable feedback from your customers, and you can go from there.\n\nTinySlice is compatible with Agile. You can do TinySlice within Agile. TinySlice sizes the work to be done, erring on the side of less not more. We only do more when we have had the feedback that says expending effort on more is warranted.\n\nWe may *think* we know what is required but this will only be known after we\nhave tested our ideas. A specification is just documentation for our ideas.\n\nWe do this test by taking a TinySlice: refining, building and deploying it to get something into the hands of our users.\n\nThey use it and give us feedback. This feedback leads to two broad categories of what can be done next: new features, or changes to existing ones. And then we iterate.\n\n## What is SDD?\n\nAs of June 2026, the main vendor promoting Specification Driven Development (SDD) is Cognition Labs. This section focuses on Cognition's approach to SDD.\n\nCognition’s SDD is fundamentally a technique to generate code using their AI tool, Devin. SDD is not a full software‑engineering methodology, not a lifecycle model, and not a requirements discipline. It is a workflow designed to support how Devin operates.\n\nCognition's SDD is:\n\n- specification as input\n- agent-driven code generation\n- code regeneration from an update specification\n\nIt defines none of the disciplines that keep code generation safe and accurate. Such disciplines are: requirements, design, testing, governance, iteration, risk, and architecture.\n\n## Cognition and SDD\n\n### SDD is not an engineering method\n\nCognition’s SDD is a code‑generation loop, not an engineering method. It treats the specification as a prompt for Devin, generates the system from it, and regenerates the system when the specification changes. It is a technique for driving an AI agent, not a process for discovering requirements, managing risk, or iterating design.\n\nThe output of Cognition's SDD is code, not understanding. At the code generation step, there is no support for:\n\n- architectural reasoning\n- trade‑off analysis\n- risk mitigation\n- incremental discovery\n\n### Cognition hints that SDD requires a full specification\n\nCognition describes the specification as the main input from which Devin generates a plan, produces tasks, and provides the code implementation.\n\nBy doing this, Cognition implies that the specification must be complete enough to accurately drive the generation steps without ambiguity.\n\nThis nudges teams towards writing as full a specification as possible \"just in case\".\n\n### Distinguishing SDD from the competition\n\nTo distinguish Devin from Cognition's competitors — Copilot, Cursor, Replit, Claude Code, Jetbrains AI — Cognition positions other approaches as generating code from prompts whereas Devin generates systems from specifications.\n\nFor this approach to be meaningful, the specification must appear formal, complete, and central.\n\n### Using Devin\n\nCognition state that the Devin pipeline is:\n\n- write specification\n- Devin generates plan\n- Devin produces tasks\n- Devin outputs code\n\nThere is no Devin-based loop, no iteraction, no feedback cycle. The approach is spec → Devin → system. If things change, you update the spec and re-run: spec → Devin → system.\n\nThis implies that SDD and Devin are waterfall in style.\n\n## TinySlice and SDD\n\nTinySlice assumes incompleteness is normal. You cannot know enough upfront, so you deliberately work in the smallest possible increment. Working with small increments gives you evidence that what you are doing is the right thing.\n\nAs Cognition describe and demo it, SDD is an authorative input, and that the pipeline is linear and waterfall-shaped.\n\nYou can use TinySlice with SDD if you treat SDD as a code generator inside your own iterative loop.\n\n## Conclusion\n\nComplete specifications are an illusion. Real systems contain unbounded variation.\n\nReal engineering requires learning from what the system actually does, not\nfrom a specifiction that tries to capture what we *think* it should do.\n\nTinySlice accepts this reality. TinySlice gives us a disciplined way to move forward in the smallest increments possible, gathering evidence at every step.\n\nPairing agentic code generation with an incremental, evidence‑driven engineering practice is a safe way forward given the volume of code that AI can generate.\n\nCreating a complete specification delays learning and insight, increases risk and pushes project discovery too late. Winston Royce understood this in 1970.\n\nTinySlice acknowledges his insight. By working in the smallest viable increments, we surface unknowns early, reduce rework and can steer more accurately to quickly react to change.\n\nSDD can play a role, but only when we stop treating the specification as\nauthoritative and start treating it as provisional, as a living document that\n*must* change.\n\nRead next:\n\n[Why Junior Engineers Matter More as AI Expands]\n\nAI means code generation is now trivial but speed cannot decide what should exist, why it matters, or whether it is safe. Junior engineers cannot bypass the discipline to gain this judgement.\n\n## Related Articles\n\n**If this was useful**, you can get more pieces like it in the Phroneses newsletter.\n\nI work with leaders and teams on clarity, capability, and momentum.\n[Work with me →](/pages/services.html)\n\n## Table of Contents\n\n[What we have always known about waterfall](#what-we-have-always-known-about-waterfall)[Royce was not advocating for waterfall](#royce-was-not-advocating-for-waterfall)[The 5 steps that introduce iterative, incremental engineering](#the-5-steps-that-introduce-iterative-incremental-engineering)[What Royce was describing](#what-royce-was-describing)[What Royce presented](#what-royce-presented)[Why does waterfall fail](#why-does-waterfall-fail)[Royce's key observation](#royces-key-observation)[TinySlice](#tinyslice)[What is SDD?](#what-is-sdd)[Cognition and SDD](#cognition-and-sdd)[TinySlice and SDD](#tinyslice-and-sdd)[Conclusion](#conclusion)[Related Articles](#related-articles)[Table of Contents](#table-of-contents)[Further Reading](#further-reading)\n\n## Further Reading\n\nWinston Royce, 1970, \"MANAGING THE DEVELOPMENT OF LARGE SOFTWARE SYSTEMS\"\n\n- https://www.praxisframework.org/files/royce1970.pdf\n\n-\nA\n\n*written*specific must be finite. Is not possible to complete the writing of an infinite specification.[↩](#fnref:note)", "url": "https://wpnews.pro/news/the-myth-of-complete-specifications", "canonical_source": "https://phroneses.com/articles/build/notes/the-myth-of-complete-specifications.html", "published_at": "2026-06-22 00:00:00+00:00", "updated_at": "2026-06-24 00:00:34.943699+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "ai-research"], "entities": ["Winston Royce"], "alternates": {"html": "https://wpnews.pro/news/the-myth-of-complete-specifications", "markdown": "https://wpnews.pro/news/the-myth-of-complete-specifications.md", "text": "https://wpnews.pro/news/the-myth-of-complete-specifications.txt", "jsonld": "https://wpnews.pro/news/the-myth-of-complete-specifications.jsonld"}}