30초 요약
Theo discusses Sean Goedecke’s argument that partial understanding is unavoidable in large codebases. He considers Peter Naur’s theory-building idea, the risks of rewrites, and how developers reconstruct knowledge of unfamiliar systems. Using examples from Twitch, TypeScript and an AI-assisted mobile rewrite, he argues that tools can reduce cognitive load while engineers retain the context needed to make and verify changes.
- 1Findability over memorizationTheo values a codebase where less familiar developers can locate the right area quickly.
- 2Programming as theory-buildingThe discussion draws on Naur’s idea that developers hold knowledge that code and documentation only partly capture.
- 3Rewrite incrementallyTheo agrees that a new system can lose important edge cases and that changing the old system is part of replacing it.
- 4An imperfect mental modelA Twitch example shows that an effective engineer can lack knowledge of one particular generation step.
- 5AI is a tradeoffLanguage models may help build a partial understanding quickly while making detailed theory harder to maintain.
- 6Mobile rewrite exampleTheo describes steering an AI-assisted SwiftUI rewrite through behavior and his broader knowledge of the system.
핵심 정리
- In a large codebase, architectural intuition and the ability to find relevant code can matter more than memorizing every line.
- A rewrite can lose accumulated quirks and user dependencies; understand and change the existing system before replacing it.
- Teams can rebuild knowledge incrementally by tracing a flow and making careful changes.
- Type checkers and other tools can free attention from routine details, but do not remove the need for task-specific understanding.
- AI may accelerate learning a partial model while also making detailed understanding harder to maintain.
- Predictions about fully hands-off coding are forecasts, not established outcomes.
챕터별로 다듬은 전문 읽기
Why complete understanding is unrealistic
Theo distinguishes memorizing code from architectural intuition. He introduces Goedecke’s argument for working effectively with partial understanding.
If you understand every line of a project, you may be working on a smaller or simpler system than the ones that underpin operating systems, platforms and databases. Nobody holds all of a sufficiently large codebase in their head. The engineers who appear to know everything often have something different: an architectural intuition for where a feature or failure is likely to belong.
A useful codebase does not require everyone to memorize every file. It makes the right place relatively easy to find, including for someone less familiar with the project. I have areas I understand better than ever and others I barely understand; I want to examine that tension rather than defend careless, completely uninformed development.
Sean Goedecke's article 'In defense of not understanding your codebase' asks how much understanding engineers need. He contrasts smaller, stable projects with large systems where teams change and nobody can know every detail. His argument is that partial understanding is normal in large systems. I broadly agree, while emphasizing that before changing a local area you should understand enough of the overall relationships to orient yourself.

Theory-building and rewriting
The discussion considers Naur’s theory-building idea and challenges a wholesale rewrite after knowledge is lost. Existing systems carry many user-visible edge cases.

The article discusses Peter Naur's 'Programming as Theory Building'. As Goedecke presents it, programmers build an intuitive theory of what a program does and why; code and documentation capture only part of that knowledge. Experience with a particular system adds intuition about failure modes and history that cannot simply be written down in one perfect file.
An agent thread resembles a new developer arriving without the previous thread's accumulated context. That makes the design problem interesting: how do we arrange the repository and tools so a capable newcomer can investigate and contribute effectively? Each fresh thread has to reconstruct relevant context, even if files and other durable information remain available.
Goedecke argues against Naur's suggestion, as he reads it, that a new team should discard a program and rebuild rather than reconstruct the lost theory. In a large user-facing system, accumulated edge cases, integrations and quirks are hard to reproduce. Even unintended behavior may have become part of someone's workflow.

The familiar spacebar joke illustrates the problem: a user finds a strange dependency on a bug, and fixing it breaks their setup. Real systems contain less comical versions of this. If the person who remembers a special case has left, a clean rewrite can easily omit behavior that existing users depend on.
Goedecke's proposed pattern is to isolate pieces of the old system and replace them incrementally. Even when I favor a rewrite, I first want to work on the existing code and understand its failures, the team and what matters to users. If you cannot change the old system meaningfully, I am skeptical you can safely replace it.
I recently saw someone assert that T3 Code, VS Code and Cursor were doomed because Electron supposedly spawned a separate app for every agent thread. That premise was wrong, yet they used an AI-generated argument to promote a Rust replacement. A rewrite based on an invented diagnosis is not the same thing as a deliberate rewrite grounded in the existing system.
Reconstructing knowledge
A team can learn an abandoned system incrementally. Theo shares a Twitch example and explains how type checking reduces cognitive load.
Goedecke's second objection is that apparently abandoned systems do get revived. He describes starting with one end-to-end flow, making careful changes and gradually expanding understanding. I think AI can help a developer ramp up by answering questions and examining code, although it does not automatically recover every former maintainer's historical knowledge.

The article argues that everyone in a sufficiently large codebase operates with an incomplete, sometimes incorrect mental model. One of the best full-stack engineers I worked with at Twitch once got stuck on client type errors after adding a GraphQL query. He knew the frontend and backend but had not previously needed to generate updated TypeScript definitions for both together.
When I asked whether he had run the GraphQL generation command, he realized the missing step and fixed it. His unfamiliarity with that particular step did not make him a bad engineer. Nobody can keep every operational detail in working memory while also doing useful work.
TypeScript is an example of reducing that cognitive burden. A type checker catches many wrong argument types and simple mistakes, so I do not need to manually rehearse each check whenever I call a function. In one sense I am thinking less about a detail; in another, that frees attention for larger changes. Compilers, linters and other checks can help in similar ways, provided we preserve the understanding needed for the task.
New developers often struggle when they move from a project they wrote themselves to a codebase older than their career. In a large system, waiting for someone with a perfect mental model is not a reliable strategy. Goedecke argues for making the best informed decision available and dealing responsibly with the consequences as you learn.
Scale also matters when interpreting Naur's 1985 paper. Goedecke notes examples of programs around 100,000–200,000 lines and contrasts them with a much larger later GCC. A compiler has inputs and outputs that can support extensive behavioral tests; user-facing software also has interactions and data expectations that may be much harder to capture comprehensively.
Understanding as a tradeoff
Goedecke argues that language models and other necessary tools affect mental models in different ways. The discussion considers the constraints of different engineering work.

Goedecke treats theory-building as one tradeoff among many. Language models may make a detailed mental model harder to maintain, but may also help people build and use a partial model more quickly. He and I are both still thinking through that tradeoff; it is not simply that any tool which changes what you remember is automatically bad.
Many ordinary necessities also complicate a complete mental model: colleagues writing code or leaving, security upgrades, external dependencies, accessibility and data-protection requirements. Teams still need to meet those obligations. Sometimes understanding takes priority; elsewhere it competes with delivery, compliance or support for additional platforms.
Goedecke describes 'pure' engineering as pursuing a technical problem as perfectly as possible, and 'impure' engineering as delivering a solution to a real-world need under constraints. These are ways to frame different work, not a ranking of people. A library or game-engine project and a product team working toward a deadline can reward different decisions.

I recognize the tension: building an elegant mental model can feel like the essence of engineering, while paid work often requires compromises to meet a user's needs on time. There is nothing wrong with pursuing small, deeply understood projects for enjoyment. At work, the theory of the codebase is one value among others, including the goals and constraints of the team.
The discussion of Goedecke's article also highlights local reasoning: engineers have long tried to work effectively on one part of a system without understanding every other part. I agree that communication with teammates and understanding what a project needs are practical engineering skills, not distractions from real work.
AI and a mobile rewrite
Theo discusses a prediction about AI-generated code and his own SwiftUI project. He closes with the tension between broad understanding and unread implementation details.
Nick Dobos predicts that rapidly increasing amounts of AI-generated code will make complete mental models even less feasible, and that highly hands-off coding may become the default. That is a forecast, not a demonstrated inevitability. I am already experiencing a version of the problem while moving the T3 Code mobile app from React Native to SwiftUI.

I say I have not read the 60,000-plus lines of the mobile implementation. Instead, I use the app, observe failures and compare behavior with the existing system to steer changes. My knowledge of data flows and failure cases from the rest of T3 Code still matters; a couple of bugs required more than simply asking the agent to mirror the old behavior.
The result is a strange balance: in some ways I understand my codebases better than ever, and in others less. I am still working out that balance. For me, learning to navigate it has been rewarding, though it can also feel stressful, and I expect the workflow to keep changing.
같은 채널의 다른 글
36:07EN
30:37EN
0:43EN
29:22EN
31:13EN
31:47EN