Software Engineering Is About Managing Complexity (hack8s)

title
Software Engineering Is About Managing Complexity (hack8s)
type
summary
summary
hack8s.com on why cheap AI-generated code makes engineering judgment and real ownership of a codebase scarcer instead of less needed
tags
software-engineering, llm, ai-coding, complexity
created
2026-09-14
updated
2026-09-14

An unsigned 2026 post on hack8s.com restates an old claim for the LLM era: writing code and building software are different jobs, AI is very good at the first, and the second is where engineering begins software-engineering-managing-complexity. Writing code turns an idea into instructions a computer can run. Building software decides which instructions should exist at all, how they interact, which constraints matter, what each decision costs, and how the system can change later without collapsing.

Context decides

The example is an ordinary requirement: process incoming events and update some data. Before anyone types a line, the team has to settle whether processing is synchronous or queued, whether at-least-once delivery is enough or exactly-once is required, whether eventual consistency is acceptable, what happens when processing fails halfway, how retries work, what happens if the consumer is down for three hours, whether ordering matters, and what a duplicate costs. None of it is syntax.

The same feature requested by two companies can have two correct designs. One has 500 users, three engineers, a single application server with PostgreSQL, and three weeks. The other has 20 million users, 200 engineers, Kafka and Kubernetes already in place, and expects the system to run for fifteen years. The impressive design for the second is irresponsible for the first. So the real question is never the best way to implement X, but the most appropriate way given this team, business, infrastructure, budget, risk and expected evolution, today.

Ask an LLM to design that system, choose the database or decide on a queue, and it will answer. The author's point is that an answer is not a solved problem. The context that settles the question is mostly undocumented: conversations with customers, the history of the product, the team's skills, an incident from three years ago, contracts, a legacy system nobody wants to touch, a feature a customer will probably ask for in six months. It doesn't fit into one more paragraph of prompt. Since every design choice trades one problem for another (caching buys latency and costs invalidation, splitting a monolith buys independent deploys and costs distributed-system complexity), the engineer's job is deciding where complexity belongs.

Ownership

The sharper half of the post is about what cheap code does to a codebase. Producing code and maintaining it are separate economic activities, and only the first got cheaper. A team can merge thousands of generated lines, watch the tests pass and the feature work, and still not know the architecture, the data structures, why an abstraction exists, how it fails or what it assumes. If they couldn't change it confidently six months later without asking another model to explain what the first one wrote, they have added complexity, not removed it. A 3,000-line generated pull request is 3,000 lines added to what the team must understand, and a green test suite mostly supplies false confidence.

Hence the author's rule: never ship code you do not own, where owning means having understood and validated every part. Generated code gets no lower bar for having been generated quickly. The open question the post leaves is whether reviewing very large generated pull requests is worth the time at all, or whether it is cheaper to move in small, controlled iterations between a person and a model.

The paradox it ends on is that AI makes programming easier while it may make software engineering harder, because the bottleneck moves from how fast code gets written to how much complexity an organization can understand and control. A team producing five times the code is not five times as productive. The author concedes there isn't reliable data yet and offers the early-adoption experience as the evidence.

The rest is advice in list form: ten principles of what the author calls algorithmic thinking (decompose the problem, find invariants, follow data flow and contention, understand failure modes, separate essential from accidental complexity, ask what happens when assumptions stop being true), and a case for picking a language the team knows deeply over one LLMs are assumed to write better, while using LLMs to learn other languages.

Against other pages

The argument is Brooks's essential/accidental split applied to generated code, and no-silver-bullet-llms makes the same case with numbers from DORA and CircleCI. The ownership section is the team-level face of cognitive-debt. owning-ai-written-code also argues that shipping generated code means owning it, from the individual side: writing code used to force understanding it, and agents remove that.

Its definition of ownership, complete understanding of the codebase, runs into not-understanding-your-codebase, where Sean Goedecke argues that in any large system nobody has that and partial understanding is the honest baseline. The two can be reconciled narrowly: Goedecke's partial understanding is built by reading and tracing the system, while this post worries about code no human has read. As a general standard, though, "complete understanding" is stricter than anyone working in a large codebase can meet, and the post doesn't say how it applies there.

On languages it disagrees with language-choice-for-agents and if-ai-writes-your-code-why-use-python, which argue the choice should move toward what agents write and check well. This post puts the team's fluency first.