Old Farm, New Seeds

I got exhausted by several messages on social media explaining:

How to use loops. How to use skills. How to use plugins. How to let agents code for you.

Most of them felt like clickbait.

Not because every idea was wrong. Some of them are useful. Some are even impressive. But most of them felt generated. Not only in the literal “ChatGPT wrote this” sense, but in the deeper sense: people repeating the same ideas without really stopping to understand what changed and what did not.

And I noticed I was strongly against one particular thing: letting AI do the understanding for me.

That was the part that bothered me. It is also hard to resist, I admit.

I like writing code. I also like writing code with AI since GPT-3. I am fine with AI explaining APIs, generating drafts, refactoring, writing tests, finding boring mistakes, and even opening pull requests. These are tools. Useful tools. Sometimes very powerful tools. I am also building some, so I still feel super excited.

But I do not want to outsource the act of understanding.

Then I did something old fashioned. I started looking at old programming books again, as if no LLM existed. As if we had never entered this current cycle.

Then I noticed Code Complete sitting on the shelf.

I picked it up without a purpose and started checking random pages.

That book shaped my view of programming more than I realized. I read it years ago, underlined some parts, moved on, and probably thought I had absorbed it. I even wanted to translate it to Turkish. But reading it again in the AI era feels different. Many sentences now have a new meaning, not because the book changed, but because our tooling changed around it.

Lately I have been focusing more on development tools. Spending more time in that field pushes me to think differently about programming. Not only “how do I build this feature,” but “what kind of environment makes good software more likely?”

I am already building a local AI agent with this ambition. But I do not want to build another thing that is just the same shit with a different wrapper. Another chat box. Another agent that writes code fast but does not help me think better.

So my curiosity is also about expanding my own understanding: how could a local AI agent actually be better for developers? I have some instincts, but I need to validate them.

I want to put some special sauce in it.

And when I started looking through those old books again, I realized that a lot of what I want is already backed by them. Not directly, of course. They were not written for LLMs. But the messages are there. I have been following them unconsciously for years.

One idea from the book got me again: the hardest part of programming is not typing the code. It is conceptualizing the problem. Many errors are conceptual errors, the book says.

conceptual errors-conceptual errors-conceptual errors

That sounds obvious until you watch how we use AI today.

Most AI coding workflows are optimized around implementation speed. Ask, generate, run, fix, retry. The loop is faster. The waiting time is smaller. The cost of producing code is lower.

But conceptual mistakes do not disappear because code appears faster. Conceptual errors disappear with “why?”, but AI mostly gives you “how?”

Actually, those mistakes might become easier to hide.

If the initial understanding is wrong, AI can help you build the wrong thing faster, more confidently, and with more files. The output can look polished. Tests can pass. The PR can look professional. But the wrong model of the problem is still there, now spread across the codebase.

Another phrase I had underlined was “software penmanship.”

I really like that phrase.

It sounds old, but in the current context it is a strong metaphor. Penmanship is not just about writing letters. It is about care, discipline, readability, and respect for the person who will read it later. In software, that person might be your teammate, future you, or now maybe another AI agent trying to modify your work.

When I first read it, I probably thought about clean code, naming, formatting, and comments. Now I think about it differently.

If AI writes more of our code, software penmanship becomes more important, not less. The amount of code can grow faster than our ability to understand it. A messy paragraph is annoying. A messy codebase is a debt machine.

There is another comparison in the book that I keep thinking about: writing is usually one person’s activity, while software projects involve many people.

Today I would add: writing can now also involve AI.

And maybe this is why AI coding feels so seductive for solo developers. When team size is small, when you are a solo founder, or when you are building a prototype, writing-like workflows are useful. You can sit with the model and produce something quickly. The whole system can still fit inside one person’s head.

But that only works until you hit one person’s conceptual limit.

After that, the problem is no longer “can we produce more code?” The problem becomes “can we still understand what we produced?”

That is where a lot of AI coding advice feels shallow to me. It focuses on the first release. It focuses on the magic moment where an idea becomes a working prototype. And yes, AI is very good there. The first version is much faster now. Skills are good. MCPs are fantastic. But all of them are still tools to do X. Nothing more.

Another old idea from the book is that most development effort comes after the first release.

That is the part people in quick demos do not talk about enough.

How many internal AI projects go beyond the first release? How many demos survive contact with real users, real data, real edge cases, real maintenance, real deployment, real security, and real teams?

The first 10 percent now moves at light speed. We have light-speed prototypes. We have V1s everywhere.

But I do not see the remaining 90 percent changing at the same rate.

The long tail is still there. The maintenance is still there. The understanding is still there. The cost of wrong abstractions is still there. Maybe it is even worse because now we can create those wrong abstractions faster.

While writing this post, I randomly encountered a Bun workshop video on X.

I saw creator of Bun working in a loop. An issue is opened. A coding agent takes the task, reproduces the bug, implements a fix, and opens a PR. Then another agent reviews it. Then another agent responds to the review and updates the PR. The loop continues.

Robobun gets the issue, reproduces it, commits the fix.

This is fascinating.

When I checked the repository insights, I saw something like 1,000 commits, with the top maintainer around 100. Then I checked other repositories on GitHub. I did not see the same pattern everywhere. In repositories like React, Axios, and similar mature projects, maintainers may have something like 10 to 100 commits in a month.

So the Bun example looks like a glimpse of something different. I think many will follow. Having an ensemble of agents always attracts me.

But it also made me think: what is actually scaling here?

Maybe the implementation loop is scaling. Maybe bug fixing is scaling. Maybe small, well-scoped issues are becoming more automatable. That is real. That matters.

But does understanding scale the same way?

I am not sure.

farm from the book

The book talks about software farming as a metaphor and pushes against it. The idea is that you plant code seeds and somehow harvest software later. But that metaphor was not suitable because you do not have direct control over how the software develops.

This feels very relevant now.

Some AI workflows sound like software farming. Put issues in. Let agents work. Come back later and harvest PRs.

But software is not a field of crops. You cannot just plant prompts and collect architecture in the fall.

Software needs construction. It needs intention. It needs decisions that fit together. It needs a structure that someone understands.

The construction metaphor in the book also mentions how large systems require a huge amount of documentation, requirements, and coordination. The exact numbers belong to another age, but the underlying math does not disappear.

If you have a million lines of code, that million lines requires a significant number of brains around it.

Or, if you do not have those brains, you end up building something you do not understand.

That is the uncomfortable part. With LLMs, you can build more than you understand. You can generate a system that exceeds your own mental model. At first this feels like leverage. Later it becomes a trap.

Either you do not understand the system, or you become the understanding bottleneck for the LLMs.

Both are problems.

A good craftsman knows the right tool for the job and knows how to use it correctly. This sounds simple, but it is exactly where we are weak right now.

We are treating AI as if it is the answer to every software problem.

But if the work is not being done well in the first place, doing more of it will not help. More code does not fix bad thinking. More agents do not fix unclear goals. More iterations do not fix the wrong problem definition.

Programmers have always had the urge to begin coding as soon as possible. AI makes that urge stronger.

Before, there was friction. You had to set up the project. Search documentation. Think through the interface. Write the boilerplate. Make decisions one by one.

Now the friction is lower. You can ask for the implementation and get something immediately.

That feels like progress, and in many ways it is. But it also means the trap is closer.

The trap is building before understanding.

Planning is often misunderstood by developers. When people hear planning, they think about sprint planning, tickets, project management rituals, estimates, meetings, and documents nobody reads.

But the definition I like is simpler: planning means understanding what you want to build so you do not waste money building the wrong thing.

That is better in software than almost any other domain.

Because in software, we can build wrong things very easily. We can iterate. We can patch. We can refactor. We can deploy. We can convince ourselves that because movement exists, progress exists.

And now AI makes movement cheaper.

This is where the famous Jevons paradox comes in. When something becomes cheaper, we often consume more of it. If implementation becomes cheaper, we may not spend less time coding. We may just build more things, more often, with less thought.

Cheap implementation can make us skip planning.

But what we are skipping is not planning in the corporate sense. We are skipping understanding.

In the pre-AI era, spending maybe 20 percent upfront thinking through the problem was already recommended. Not because planning was fashionable, but because it reduced the chance of building the wrong thing.

Does that change now?

I do not think the direction changes. If anything, the need becomes stronger.

Because AI makes coding faster, the relative importance of understanding increases. The bottleneck moves. The question is no longer “can we implement this?” The question becomes “is this the right thing to implement, and can we preserve the integrity of the system while implementing it?”

So you need to build the full pipeline, not just write code or ship features.

Again, the essential problem with large systems is maintaining conceptual integrity.

That phrase explains a lot.

Conceptual integrity means the system feels like it was designed by a coherent mind. The parts fit. The abstractions make sense. The behavior is understandable. The system has a shape. Not countless stateless agent runs.

Large teams struggle with this. Organizations struggle with this. AI agents will struggle with this too.

Design — I do not mean UI — is not deterministic. Programming is not fully deterministic either, but design is even less so. LLMs are also not deterministic. That means there are several moving parts at the same time. The degree of freedom is almost unlimited. There are many possible solutions, many possible tradeoffs, many possible futures.

AI can suggest options, but it cannot remove the need for judgment.

Projects do not usually fail because people cannot type code.

They fail because people struggle to manage complexity. They fail because teams and organizations do not want to spend time on upfront thinking. They fail because goals are unclear, abstractions leak, ownership is messy, and nobody protects conceptual integrity.

LLMs do not automatically solve this.

Used blindly, they create more complexity over time. You pour code into the repo, and at first it feels productive. Then the repo starts pushing back. The system becomes harder to change. The explanations become longer. The tests become fragile. The agent needs more context. You need more rules. More prompts. More guardrails. More cleanup.

The complexity did not disappear. It moved.

So the goal should not be “let AI write as much code as possible.”

The goal should be to minimize the amount of essential complexity a person has to handle at any time.

That is what good design does. Clever design is not design that looks impressive. Clever design is design that is easy to understand. It lowers complexity. It makes the next change safer. It helps both humans and tools work inside the system without constantly breaking the mental model.

This is where I think AI development tools should go. I think a lot before landing on a proposition.

The real opportunity is helping developers understand better while producing faster.

Help me see the conceptual model. Help me notice when the implementation is drifting from the design. Help me reduce complexity before adding more code. Help me ask the question I am avoiding. Help me not build the wrong thing.

Because in the AI era, writing code is becoming easier.

Understanding software is not.

Author

Osman Orhan