Internal publication

We've Seen This Before

Jonatan Wallgren · 25 September 2026

Short version

A few days ago I read a complaint from a software engineer, shared on Reddit. Their company was producing specifications, tickets, code, tests and reports through Claude Code. There was barely time to read the output. Management wanted to know why delivery was still slow if generating code was no longer the bottleneck.[1]

I cannot verify the workplace account. But I recognised the pressure: keep delivering, deal with the consequences later. The software works, the next request arrives, and examining what successive changes have left behind can wait.

We've seen this before.

Early in my career I worked somewhere that treated “quick and dirty” as a development philosophy. I also worked on betting products where domain data was represented in multidimensional arrays. To give an invented example, a selection in a football-pools game might have ended up behind `game[2][0][5]`. The route to the value was in the code. The meaning took more work.

I had come to Flash because it made substantial interactive browser clients practical when ordinary browser technology made them difficult to build. Their complexity made architecture a practical problem. Through the Flash and ActionScript community, including Flashcoders, I learned architectural ideas and applied them successfully in a frontend system, separating responsibilities and controlling data flow.

Then, in 2007–2008, I maintained substantial Flash clients with poor structural boundaries and conditionals hundreds of lines long. Investigating a symptom exposed hidden dependencies; local fixes had unexpected consequences elsewhere. I already understood architectural ideas. Maintenance taught me what the absence of useful structure costs.

01

The Next Change Inherits the Last One

Imagine a subscription service. Initially, one part of the system decides whether a customer has access. Cancellation stops renewal, but access continues until the paid period ends. The rest of the application asks for that decision.

Then reporting needs to count active customers. Support needs to explain why somebody still has access. A promotion introduces an exception. An integration needs to work without calling the original service. Each request makes sense. Gradually, several parts of the system carry their own version of what an active subscription means.

Now somebody asks for a pause button.

You have to find those versions, understand their differences and decide which still matter. Missing one can produce a bug. The service may have been operating successfully throughout.

Eick and colleagues studied the change history of a successful telecommunications system that was already fifteen years old. It was still receiving features, but changes were spreading more widely and modularity was weakening, without dramatic, widespread decay.[2] Success and deterioration could occupy the same system.

Sometimes accepting that future cost is sensible. With six months of runway and no certainty that anybody wants the product, building for ten years of maintenance may be bad engineering. A rough implementation can buy information. The bargain changes if the experiment succeeds and customers come to depend on what was supposed to be temporary.

The original decision may have been good. Whether it remains good is a new question. Answering it requires remembering enough of the bargain to recognise when circumstances have changed.

02

Agreement Can Be the Same Mistake Repeated

This is where the new tools make the old problem interesting. AI can accelerate changes and help us understand their consequences. It may also produce much of the material through which we expect to check them.

Suppose we ask an agent to implement cancellation. Customers should retain access until their paid period ends. Somewhere in turning that requirement into a specification, it becomes “cancellation ends access immediately”. The implementation follows the specification. Generated tests check for immediate loss of access. Documentation describes it, and review confirms that the code matches the specification. Everything agrees. The customer still loses access they have paid for.

Agreement can be the same mistake appearing several times. Controlled research has shown a narrower version: tests generated with faulty implementation context can inherit mistakes from that context.[3] This demonstrates a propagation mechanism, not years of organisational drift. A person or another model invocation could catch our cancellation error if it consulted the original request. What matters is whether checking has evidence that can contradict the mistake.

The cancellation error concerns behaviour; the scattered access rules concern later change. Suppose today’s implementation becomes tomorrow’s explanation, guiding the next change. A temporary arrangement can acquire authority simply because later work keeps building on it. How well do we notice and revise those assumptions when changes arrive much faster?

I do not know the answer. The speed of production could make the problem worse. The speed of examination and repair could make it better. Both belong in the question.

03

A Software System Is Also Being Taken Somewhere

Each decision helps determine which future changes will be easy, which dependencies we accept and which options remain practical. Boundaries and temporary compromises express an understanding of what we are building.

Imagine that we want to reduce dependence on a cloud provider. A new managed service makes one feature easier to build; another solves another problem. Each addition works and is straightforward to maintain. Together, they make leaving substantially harder. Staying might still be the right choice. But deliberately changing direction requires bringing those decisions back into contact with the aim they are changing. Otherwise we may discover much later where accumulated local choices have taken us. Nothing needs to break for that to matter.

Our understanding should change as we learn what customers need or discover that a boundary is in the wrong place. The question is whether we can reconsider it without losing track of the choices involved. Can this change be challenged by evidence? Can we recover the constraints and reasons relevant to it? Are the cumulative choices still serving goals we can recognise and revise?

04

What Needs to Survive

During that 2007–2008 maintenance period, version-control history was often one of my few clues to why strange code existed. The diff showed what changed. A message saying `committing fix` preserved almost nothing about why.

Recently, during a mob-style technical interview, I remember being told that plans used to steer coding agents were committed to version control. I initially thought of a committed agent plan as a gigantic commit message. But a plan describes what we intend to do. Pages of procedural detail may preserve very little about why a consequential choice was made.

What matters is whether later work can recover information that could change its decision and would be difficult to reconstruct.[4] A person or agent needs to find the relevant record, distinguish a proposal from an accepted or superseded decision, and challenge it against current evidence. Continuity can live in the process around the work: accessible goals and reasons, constraints enforced by checks, and feedback that prompts reconsideration.[5] Each agent invocation can end while that process continues. Stored history alone does not provide that continuity.

A developer may truthfully say, “I just tell the agent what I want,” while working inside an environment that supplies considerable direction already. Architecture and framework conventions suggest patterns; types, tests, database constraints and deployment checks reject some mistakes. Short prompts do not imply an unsteered process.

AI may also make understanding and repair cheaper: recovering architecture, finding dependencies, retrieving relevant history and helping refactor code.[6] I would have welcomed tools that could recover meaning from the systems I maintained. The fact that the work taught me something does not make its cost desirable.

If AI-heavy systems remain reliably cheap to understand and change over years, even as individual humans remember less of them, that would weaken the concern. If AI-assisted repair keeps total maintenance costs falling, structural deterioration may matter less than historical experience suggests.

The people in the opening account felt they had lost the time to examine what they were shipping. Maintenance taught me how much earlier decisions can make a small request cost. Continued delivery alone will not tell us what those decisions are leaving behind.

I want to know what we will inherit from all this activity. Later people and tools will need to make reliable changes without first reconstructing an increasingly tangled world. They may also want to reconsider what the system is becoming. What interests me is whether they can still recover the choices that brought it there, judge which ones still serve them, and take it somewhere else.

Sources

  1. Account shared on r/ClaudeAI, reproducing a post attributed to voxium (@v0xium), dated 20 September 2026. The workplace account is unverified. The author’s career and maintenance experiences are personal testimony; the football-pools lookup is an invented illustration.
  2. Eick et al. (2001), Does Code Decay? Assessing the Evidence from Change Management Data, found increasing change span and declining modularity, without dramatic widespread decay; its feature-effort analysis was suggestive. Parnas (1972), On the Criteria To Be Used in Decomposing Systems into Modules, provides the design rationale for containing the effects of change. The subscription service is an invented example, not a measured case.
  3. Konstantinou, Tambon and Papadakis (July 2026), On the Risk of Coding Before Testing: An Empirical Study on LLM-Based Test Generation Workflow, an arXiv preprint using controlled Python benchmark workflows. Faulty implementation context biased generated assertions and reduced fault detection compared with independently generated tests. This supports a bounded propagation mechanism, not a longitudinal organisational outcome.
  4. Al Safwan, Elarnaoty and Servant (2022), Developers’ Need for the Rationale of Code Commits, documents reported needs for reasons beyond the diff. Fan et al. (2026), VibeMemBench, an arXiv preprint, studies selected coding targets: direct-experience gains were uncertain, with every resolution-effect interval crossing zero. Tested memory systems fell below memory-off resolution in 11 of 12 observed comparisons; none established superiority. It concerns usable coding context, not long-term organisational memory. The committed-plan practice is the author’s unverified recollection of an interview; the preservation principle is the essay’s synthesis.
  5. Nygard (2011), Documenting Architecture Decisions, discusses decision status and retained context. Leith (2026), Between the Commits, an arXiv preprint, examines one human-directed project over weeks. Its archive shows cross-session handoffs being consumed and earlier plans reassessed against newer code and documentation. Raw-session coverage is incomplete. The continuing human steward supplied direction and coordinated work; this does not establish autonomous stewardship or long-term conceptual integrity.
  6. Recovering Software Architecture Intent from Historical Work Items Using Generative AI and Agentic Refactoring are preprints supporting bounded components of understanding and repair. Recovery was evaluated in two industry projects; the observational refactoring study reported modest structural improvements with attribution limitations. Borg et al. (2026), Echoes of AI, found no significant downstream maintenance time or quality penalty in a bounded preregistered study. These results do not establish equivalence or falling total maintenance costs over years.