Skip to main content
Back to philosophy

The Craft Continues

The looming shadow of AI has many people focused on jobs and market impact. Our concern is different: when the compiler comes, what happens to the craft of building software?

The Concern That Matters

The looming shadow of AI over society has many people focused on economy, markets, jobs, and GDP impact. Those are important questions, and I don’t dismiss them.

But they’re not my question.

My question is different, and more personal: when the compiler comes, what happens to the craft? Not “will there be jobs?” but “what does it mean for those of us who have dedicated ourselves to the practice of building software?” This is a question for developers with years of experience who feel the ground shifting beneath them, and for CS students with a genuine passion for building things who wonder whether that passion has a future. It’s for anyone who chose this work because they find something satisfying in solving hard problems with well-designed systems.

Many foresee that AI will eventually master the specification layer too, handling design judgment without human direction. They may be right. But they’re concerned with the human’s future in the craft. I’m asking about the craft’s future in the human.

The Traddev / Vibe-Coding Spectrum

The current landscape presents two extremes, and both miss the mark.

On one side, you have developers who dismiss AI tools entirely, insisting that “real engineering” can’t be delegated to a language model. They’re defending something real: the discipline and accumulated wisdom of decades of software engineering practice. But they’re defending it by refusing to engage with a shift that is happening regardless of their participation.

On the other side, you have the vibe coders.1 They send off three-word prompts into the abyss with their fingers crossed, accumulating a pile of generated code that nobody fully understands. They’ve embraced the speed and leverage of AI, but they’ve abandoned everything that makes software engineering a discipline: structure, accountability, verification, design.

The answer operates on a different axis entirely. The question is what engineering discipline looks like when your implementation medium changes.

The engineering discipline doesn’t split the difference between tradition and automation. It evolves into something both rigorous and accelerated, because the structure is no longer overhead layered on top of the work… it is the work.

Where Human Judgment Still Matters

Twenty-five years of professional development experience is no longer needed for writing TypeScript. What it’s needed for:

When a clean-looking design is going to paint you into a corner three features from now. Whether a feature is too much work for its value and should be descoped. Which bugs are known shippables to hit a deadline. Whether a team is building for hypothetical scale instead of actual need. When to stop designing and start shipping, and when to stop shipping and revisit the design. That a stakeholder’s stated requirement and their actual need are often different things.

For now, this is where the human adds the most value, and where decades of accumulated experience still express themselves, even after the medium has changed from code to specifications.

The Feedback Loop Problem

In the implementation domain, feedback is immediate. Code doesn’t compile, the tests fail, and the bug reproduces on the first attempt. You touch the stove and feel the burn instantly. This tight loop between action and consequence is why implementation skills develop relatively quickly. The cost of mistakes is paid immediately, and instincts form through rapid repetition.

The specification domain has a very different feedback loop. When a specification fails to be future-proof, such as when it contains a quiet assumption that conflicts with a requirement you haven’t yet imagined, the pain may arrive days or weeks later. You specified a clean interface that seemed elegant at the time. Three features later, you discover it precludes an integration you now need, and the cost of redesigning it has compounded with every piece of work that built on top of it.

How do you build instincts when the burn happens a month after you touch the stove?

This may be the central challenge of skill development in the specification domain. The implementation domain had the advantage of rapid feedback to surface flaws in thinking. The specification domain does not. Missing quiet assumptions and anticipating unknown future requirements are limitations of the human mind in any domain. But where code surfaced these failures quickly, specifications surface them slowly, after the cost of correction has multiplied.

The tooling response to this problem is still being invented. There are mechanisms that artificially tighten the feedback loop: systems that force immediate attention when a specification flaw surfaces during implementation, institutional memory that captures design lessons at the point of impact rather than letting them fade. But these are early attempts to compensate for what the specification domain naturally lacks.

Learning the New Craft

The implementation domain had a mature ecosystem for developing engineering skill. Formal education taught atomic units of knowledge: data structures, algorithms, systems programming. Mentorship from senior engineers provided pattern recognition. Books cataloged best practices and anti-patterns. Code reviews forced exposure to better approaches. Coding challenges like LeetCode provided structured practice with immediate feedback.

What are the equivalents for the specification domain?

What does a specification anti-pattern look like? The implementation domain had catalogs of these, like god objects, spaghetti code, and premature optimization.2 The specification domain presumably has its own, but they haven’t been enumerated.

Are there design patterns for specifications? The implementation domain had the Gang of Four.3 Are there recurring structural solutions to common specification-level problems: how to decompose a system, how to specify an interface boundary, how to structure a design document so it remains viable under future pressure?

What would a “LeetCode for specs” look like? A challenge format where you write a specification for a complex system, and your spec is tested against hidden future requirements, the way a coding challenge tests your function against hidden inputs. Can you design a system that accommodates additions you didn’t anticipate?

Early answers are beginning to emerge from practice. The implementation domain had a vocabulary of operations, repeatable transformations you perform on code: refactor, extract method, inline variable. A similar vocabulary is forming for specifications: decomposition of a monolithic spec into modular sections that can evolve independently, multi-perspective review to catch cross-cutting concerns, structured extraction of design knowledge from unstructured sources, consistency checking between what a specification promises and what the implementation delivers. These aren’t design patterns yet, but they’re the raw material from which patterns will eventually be cataloged. The craft vocabulary of a field that is just beginning to recognize itself.

The fact that these questions can be formulated, and that early answers are already emerging, means the field is real and worth taking seriously as a discipline. The craft is moving to a domain where the tools for developing mastery are still being built.

New Instruments

Every paradigm shift has felt like an ending to those living through it. Assembly programmers surely mourned the loss of register-level control as the direct relationship between their instructions and the machine’s behavior. Systems programmers who spent years mastering memory management watched that entire skill set become invisible, handled by a runtime they never touched. For those closest to the old way of working, the loss was genuine.

But the music continued. New instruments and new compositions. Forms of virtuosity that the previous generation couldn’t have imagined, because the creative space didn’t exist until the old constraints were removed.

The craft of building software was never the craft of typing code, even when typing code was most of what we did. It is the craft of solving problems, designing systems, and making things that work and hold up under real pressure. That craft continues. The medium changes. The satisfaction of building something well does not.

Footnotes

  1. A. Karpathy (@karpathy), “There’s a new kind of coding I call ‘vibe coding’…,” X (formerly Twitter), Feb. 2, 2025. [Online]. Available: https://x.com/karpathy/status/1886192184808149383. Karpathy described a workflow where one can “fully give in to the vibes, embrace exponentials, and forget that the code even exists.”

  2. D. E. Knuth, “Structured programming with go to statements,” ACM Comput. Surv., vol. 6, no. 4, pp. 261–301, Dec. 1974. The oft-quoted maxim “premature optimization is the root of all evil” appears on p. 268, though Knuth attributed the underlying sentiment to C. A. R. Hoare.

  3. E. Gamma, R. Helm, R. Johnson, and J. Vlissides, Design Patterns: Elements of Reusable Object-Oriented Design. Reading, MA, USA: Addison-Wesley, 1994. The four authors became known as the “Gang of Four,” and the book’s 23 cataloged patterns became the canonical vocabulary for object-oriented design solutions.