The Authorless Codebase
When nobody can explain an AI-built system, recovering the old design may be the wrong job.
Suppose you’re inheriting an AI-built product whose login screen works. Behind it sit three authentication functions: two appear unused, while the third stores a session token you can’t find a reader for. Do you preserve the tangle until you understand its design, or start taking it apart?
Now suppose the person who assembled it accepted each change by clicking through the screen, never reviewed the implementation, and kept none of the agent sessions. They can explain the product they wanted. They can’t explain how these functions ended up together. You’re holding the output of a conversation nobody kept.
You know where to look next: commit history, old tickets, whoever might remember the decision. A strange workaround can make sense once you find the constraint that produced it. The danger is assuming every strange line will yield that kind of answer.
In his 1985 essay “Programming as Theory Building”, Peter Naur argued that a programmer’s understanding goes beyond the source code. It includes how the program relates to the world it serves, why its parts are shaped as they are, and how to adapt it to a new requirement. His account explains why handing someone the files can leave so much of the job undone.
Applying that distinction to agent-built software raises a practical question: what understanding survives the session? A coding agent can gather context, make a plan, and check its work. Anthropic’s November 2025 account of long-running coding agents describes those capabilities alongside a failure in its web-app experiments: an agent could leave a feature half-implemented and undocumented, forcing the next session to guess at what had happened. Later sessions could also see a partly built application and declare the job done.
Anthropic reports better continuity after introducing explicit feature requirements, progress notes and git history for later sessions to read, and browser testing before declaring a feature complete. The account also records limits: their browser tools couldn’t see browser-native alert dialogs, and features relying on them remained harder to verify. Keeping records helped the next session continue; the checks still depended on what the agent’s tools could observe.
Agents can help preserve an explanation as well as produce code; human-written code can lose its explanation too. A codebase is authorless when nobody can explain the system its accumulated changes produced. The question for the inheriting engineer is whether any surviving records agree with the system they’re taking over.
Back in the hypothetical authentication file, the functions might be successive attempts rather than parts of one design. A change that switches login to server cookies could leave an earlier local-storage write behind. The browser sends the cookie, the server accepts it, and the dashboard opens. Accepting that login as proof of the change would say nothing about whether the old write was still needed. Each attempt could have had a plan; nobody necessarily chose the arrangement you inherited.
That is a possible history, not a diagnosis of the file. The token might have a consumer outside the code you’ve inspected. Even if you prove the write is unused, you still haven’t proved why it was generated. But you also don’t owe it an elaborate design justification just because it survived.
Archaeology is useful when you’re recovering decisions from evidence. Geology is the better metaphor for accumulated layers whose purpose you can’t establish: investigate what remains and how it behaves, without assuming every layer belongs in the system you need now. The trap is doing archaeology on geology, defending every leftover line as though someone had deliberately chosen the final arrangement. Where a design record survives, use it; where the record runs out, leave the reason unknown.
Unknown origin and unknown dependency call for different responses. You can make a present-day decision without discovering why a line first appeared. Removing it as unused requires establishing what still depends on it. A supported client that needs the token is a reason to retain the write, even if nobody remembers whether that dependency was intended.
For the login flow, start by tracing a successful sign-in from the browser to the server and back. Establish which credential subsequent requests send and where the server validates it. Then exercise the refusal paths: a request with no credential, an expired session, an attempt to read another user’s data. A dashboard appearing after a click tells you little about those boundaries.
Record current behavior with characterization tests, tests written to describe what an existing system actually does. Keep those observations separate from required behavior. If an expired token still grants access, preserving that response would preserve a bug. The test gives you something concrete to change deliberately; deciding who should have access requires an understanding of the product.
Before treating the unexplained write as redundant, check the other clients and deployed versions that might consume it. A search of one repository can miss a reader elsewhere. An older frontend still in use could make an apparently abandoned token part of a compatibility arrangement.
In the cookie example, remove only the local-storage write in a test build and sign in with fresh browser storage. Leaving an old token in storage could let a remaining reader keep working and make the deletion look harmless. Compare the credential flow and refusal behavior with the original build, including the path that renews a session if the product has one. Repeat those checks for the client versions you still support.
If you can’t establish whether a supported client uses the token, the deletion remains unresolved. A successful check of the current browser app cannot settle that dependency. Make the smallest change whose consequences you can exercise, and record both the evidence for it and the behavior you still haven’t checked. That gives you a bounded decision about this write, with no claim to have reconstructed the whole system’s design.
An agent can help with that investigation. Ask it to trace the credential, identify callers, and propose tests, then inspect the paths and results it supplies. Accepting a plausible explanation without checking it would repeat the original handoff problem in prose. The next maintainer needs your decision attached to the checked client versions and a way to rerun the checks, not another unexamined conversation.
A founder can have good reasons to build with an agent. Taking responsibility for the result doesn’t require condemning how it was made or replacing every generated line. You may never learn why that token write arrived. You can leave behind a reason it stays, or evidence for removing it, and your name on that decision.
Want this looked at in your business?
Start with the rough map: thirty minutes, owner to owner, and a written report on where AI pays off for you and what it's worth. It's free, and if you don't need us the report says so.
Get your rough map, freeNot ready to talk? Stay sharp anyway.
We send insights like this to technical leaders every week or two. The thinking we bring to our engagements, no fluff, no spam.
You're in. Check your inbox to confirm, and for what we sent.
