To Code is Human: Why AI Can’t Automate the Soul of Engineering

What Henry Petroski’s Lessons on Failure, Foresight, and Revision Teach Us About Engineering in the Age of AI.Right now, there is a lot of talk about the “AI Agent” revolution. We are being offered tools that claim to do more than just finish our code; they say they can design whole systems…

What Henry Petroski’s Lessons on Failure, Foresight, and Revision Teach Us About Engineering in the Age of AI.Right now, there is a lot of talk about the “AI Agent” revolution. We are being offered tools that claim to do more than just finish our code; they say they can design whole systems for us.But every time I hear that software engineering is dead, replaced by Large Language Models, I return to a book that has sat on my shelf for decades: To Engineer is Human by Henry Petroski. Petroski wasn’t writing about Python or Kubernetes; he was writing about bridges, paperclips, pencils, and cathedrals.Yet his central thesis is the most important counterargument we have against the commoditization of our craft: Engineering is not a calculation. It is a deeply human act of desire, hypothesis, and revision.AI is a synthesizer of the past. Engineering is the art of forcing the future to exist. Here is why the “soul” of software engineering will remain a strictly human endeavor.1. Engineering as HypothesisWhen we let AI write our functions, we reduce system architecture to mere syntax. Petroski argues that every bridge built is essentially a hypothesis: “If I build this structure with these materials, it will stand against the wind and the weight.”In software, every microservice and every database schema is a similar hypothesis. We are hypothesizing that this abstraction will handle a traffic spike on Black Friday, or that this encryption model will withstand a brute-force attack.AI cannot form a hypothesis because AI does not understand consequence. An AI agent can generate the code to build the bridge(the implementation), but it cannot formulate the hypothesis of why that bridge should exist or the intuitive leap that suggests a suspension design is better than a cantilever for this specific gap.The Human Element: We don’t just write code to work; we write code to test our understanding of reality. We stake our reputation on the hypothesis.2. Success is Foreseeing the FuturePetroski famously analyzed failures like the collapse of the Tacoma Narrows Bridge in 1940 to prove that success is actually the result of obviating failure. To be a principal engineer is to be a professional paranoid. It is the ability to look at a pristine design and see where the cracks will form three years from now.AI is trained on the data of what has worked. It is a retrospective engine. It struggles to predict the “unknown unknowns.”The AI sees a login form and generates the standard code.The Engineer sees the login form and foresees a race condition that only happens when two users update their profiles simultaneously while the third-party auth provider is experiencing latency.Success is not compiling without errors. Success is the human ability to mentally project the system into a chaotic future and protect it.3. Design is “Getting From Here to There”One of Petroski’s simplest yet most profound definitions of engineering is the act of “getting from here to there.” It is the traversing of a gap. In civil engineering, the gap is a river. In software, the gap is the distance between a user’s pain point and a technological solution.AI creates the path of least resistance. It gives you the average route. Humans create the path of elegance. Sometimes the best way to cross the river isn’t a bridge, but a tunnel, or a ferry. An AI agent does exactly what it is told; a human engineer understands that sometimes the problem itself needs to be redefined, not just solved.4. Design as RevisionPetroski’s best lesson comes from the history of re-designing the pencil. The pencil was not invented in a stroke of genius; it was iterated upon over centuries. The lead broke, the wood splintered, the eraser was added.Design is revision. It is the editorial process. In the age of AI, we run the risk of accepting the “First version” as the final product because the code looks syntactically perfect. But as any senior engineer knows, the first draft is rarely the right architecture.The Artist’s Eye: A painter steps back from the canvas, squints, and realizes the composition is off balance.The Engineer’s Eye: We look at a class hierarchy, “squint,” and realize it’s too coupled. We refactor not because it’s broken, but because it is “ugly” and unmaintainable.AI does not have a sense of aesthetics or maintainability. It doesn’t care if the code is readable for the junior developer who will join the team next year. Only a human can revise with empathy for the future maintainer5. The Dangerous Anti-Pattern of “Vibe Coding”The industry has spawned a dangerous new trend: “Vibe Coding”. This is the practice of prompting an AI until the output “feels” right: code that compiles and passes the happy path test, without the engineer ever truly understanding the underlying logic or constraints.Through the lens of Petroski, Vibe Coding is the ultimate engineering anti-pattern. Petroski warns us that “successful” designs can be dangerous because they mask latent flaws. When we write code based on “vibes”, accepting an AI’s output because it looks plausible, we are skipping the critical step of failure analysis.We are building the Tacoma Narrows Bridge without understanding aerodynamics, simply because it looks like other bridges that haven’t fallen down yet.The Reality Check: Engineering is not about getting the code to run; it is about knowing exactly why it runs and, more importantly, exactly when it will break.If you cannot explain the trade-offs in the generated code, you haven’t engineered a solution; you have merely successfully guessed. In a profession where edge cases cause data breaches and race conditions cause financial loss, “vibes” are not a strategy; they are a liability.6. The Verdict: The Human in the LoopPetroski taught us that to engineer is to be fallible, but also to be visionary. AI will undoubtedly change how we build. It will lay the bricks; it will mix the cement. It will calculate the load-bearing stress of the steel beams. But it cannot decide where the bridge goes, or why we are crossing the river in the first place.Do not let the tools fool you into thinking the craft is gone. The syntax may be automated, but the hypothesis, the foresight, and the revision, the soul of the work, is yours to keep.7. The “To Engineer is Human” Code Review ChecklistHere is the Human-Centric Code Review Checklist, designed to operationalize the philosophy of Henry Petroski in your engineering team.This is not a style guide (linting handles that). This is a thinking guide meant to catch “Vibe Coding” and ensure that every PR remains a deliberate human hypothesis.Objective: To ensure code is not just syntactically correct (AI can do that), but structurally sound, resilient, and clearly understood by its creator (only humans can do that).The "To Engineer is Human" Code Review ChecklistObjective: To ensure code is not just syntactically correct (AI can do that), but structurally sound, resilient, and clearly understood by its creator (only humans can do that).1. ** The Vibe Check (Anti-Pattern Detection)** Targeting the "it looks like it works" mentality.[ ] The "Explain Why" Rule: Can the author explain why a specific library or complex function (especially Regex or bitwise operations) was chosen without referring to "it’s what the suggestion gave me"?[ ] Dependency Audit: If a new package/dependency is introduced, has the author verified its maintainability, license, and security, or was it just the first import suggested?[ ] The Hallucination Test: Are the comments describing logic that actually exists? (AI often writes comments for code it planned to write but didn't).2. ** Hypothesis Verification (Engineering as Hypothesis)** Targeting the architectural intent.[ ] The "Why This, Not That" Defense: Does the PR description articulate the hypothesis? (e.g., "I chose a Strategy Pattern here because we anticipate X changing in the future," rather than just "Added feature X").[ ] Boundary Definition: Does the code clearly define the boundaries of the system? Are we explicitly stating what this code is not supposed to handle?3. ** Foreseeing the Future (Success is Avoiding Failure)Targeting Petroski’s concept that engineering is the study of failure. **[ ] The "Tacoma Narrows" Test: The code handles the "Happy Path" (sunny day), but what happens during the storm? - Network timeouts? - Database locking? - Third-party API rate limits?[ ] Error Handling vs. Error Swallowing: Does the code actually handle the failure, or does it just catch (e) and log it to avoid crashing? (A silent failure is worse than a crash).[ ] Scalability Horizon: Will this logic hold up if the data volume increases by 10x? If not, is there a // TODO acknowledging this technical debt?4. ** Design as Revision (The Human Editorial Eye)Targeting maintainability and empathy for future engineers. ** [ ] The "Junior Engineer" Readability Test: Could a new hire understand the control flow without having to ask the author? AI tends to generate dense, clever code; Humans should request simple, readable code.[ ] Logic Decoupling: Is the business logic separated from the framework glue? (AI often mixes them).[ ] Commenting on Intent, not Action: - Bad (AI style): // Increments i by 1 - Good (Human style): // We increment here to bypass the header row during parsingImplementation tip for the Principal ReviewerI recommend adding a mandatory section to your GitHub/GitLab Pull Request template titled “The Human Element.” It requires the engineer to answer the following questions:Explain the problem that you are trying to solve and why?What are the boundary conditions?What is the most likely way this code could fail in production, and how have you mitigated it?How does your system fail gracefully, and how does it recover?This forces the engineer to stop “generating” and start “foreseeing.”Here is a Pull Request (PR) template designed to force the “pause and think” moment that is often lost in the age of AI coding.You can save this as PULL_REQUEST_TEMPLATE.md in your .github or .gitlab directory.## 1. The Hypothesis*(What problem are we solving? Why do we believe this specific implementation is the right solution?)*- **Ticket/Issue:** [Link]- **The Gap:** What was missing or broken?- **The Solution:** Why this architecture/pattern? (Explain the *why*, not just the *what*)## 2. Design: "Getting From Here to There"*(Briefly describe the problem that you are trying to solve and why?. Did you traverse a specific constraint?)*- [ ] New Migration/Schema- [ ] Refactoring (No functional change)- [ ] Feature Implementation- [ ] Bug Fix**Key Technical Decisions:**> *e.g., "I chose to use a Queue here instead of a direct API call because..."*## 3. The Human Element (Mandatory)*In the spirit of "To Engineer is Human," please answer the following:***A. Foreseeing Failure***Henry Petroski argues that success is the result of anticipating failure.*> **What is the most likely way this code could fail in production (edge cases, scale, latency), and how have we mitigated it?**>> *[Your answer here]***B. The "Vibe Coding" Check***If AI tools (Claude, Copilot, ChatGPT, etc.) were used to generate any part of this code:*- [ ] I certify that I have read and understood every line of generated code.- [ ] I have verified that no hallucinated dependencies or methods were introduced.- [ ] I can explain the trade-offs of the generated logic without relying on "it works."## 4. Design as Revision (Checklist)- [ ] **Readability:** Could a junior engineer understand this control flow without asking me?- [ ] **Error Handling:** am I handling errors gracefully, or just swallowing them to silence the linter?- [ ] **Tests:** Do the tests cover the failure scenarios, not just the "Happy Path"?- [ ] **Documentation:** Have I updated the docs/comments to explain the *intent* behind complex logic?---*“Engineering is not the art of constructing; it is the art of not failing.”*This story is published under the Generative AI publication. Connect with us on LinkedIn and follow Zeniteq to stay in the loop with the latest AI stories. Let’s shape the future of AI together!To Code is Human: Why AI Can’t Automate the Soul of Engineering was originally published in Generative AI on Medium, where people are continuing the conversation by highlighting and responding to this story.

Source: Generative AI Pub — Published — Category: Image AI

🔗 Read full article on Generative AI Pub →