From Rewrites to Greenfield: Building watgo With Agent Help

A few months ago I described using LLM agents to help restructure pycparser. That rewrite has since proven successful, and I've continued maintaining the project without issue. More recently, I completed a different kind of project with significant agent assistance: watgo, a WebAssembly toolkit for Go. Unlike the rewrite, this was a from-scratch project in a new language. The experience differed in several important ways.

Design-First, Then Incremental CLs

A new project needs extensive design work, so I began by iterating with the agent on an API sketch. I recommend committing the design notes as a Markdown file in the repository for future reference — something like doc/notes.md.

From there, I instructed the agent to produce change lists (CLs) in a logical order, keeping each one small enough to review comfortably. That's not always easy to achieve in a single pass; multiple revision rounds can confuse the agent. In those cases, I commit the initial CL, then go back and ask for modifications or refactors as separate, follow-up CLs. If the direction turns out wrong, the sequence can be reverted entirely. Branches help for more complicated scenarios.

The key point: sometimes a single CL is a huge step forward but needs a lot of cleanup to become viable. I've seen an agent generate several days of work in one CL, and then I've spent hours directing refactoring rounds. It's still a net productivity win — just not the dramatic gain some would claim.

Two Tiers of Agent-Driven Projects

Given current agent capabilities, I split projects into two categories. The first includes low-importance prototypes or throwaway code where deep understanding isn't necessary; here "vibe-coding" is acceptable. The second includes high-importance projects I actually intend to maintain. For those, I insist on reviewing and guiding all code the agent writes before submission — or shortly after, as discussed above.

watgo falls firmly into the second category. I plan to maintain it long-term, so I require code I fully understand. With very few exceptions, no code lands without a full review and often multiple revision cycles.

Writing code is only part of maintenance. The real work is triaging bugs, deciding what needs to be done rather than how, and keeping the codebase healthy over time. As Brian Kernighan put it:

Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it?

Agents may eventually handle category-two projects autonomously, but we're not there yet. I suspect that will require crossing the AGI threshold, after which few assumptions hold.

A More Disciplined Workflow

Reviewing only the agent's pull request makes it hard to stay thorough. A more reliable method: run a CLI agent locally in the repository and ask it to modify code in place. Meanwhile, keep a VSCode window open on the same project so you can:

  • Review changes in the diff view
  • Apply your own tweaks directly

Once the change looks right, create the commit manually.

Small CLs and the "Big Picture"

Progress must stay incremental, with CLs small enough for a human to grasp fully in one review. The urge to sprint ahead with thousands of lines per day is tempting but must be resisted. Coding with an agent is like speed-reading — you cover more ground, but comprehension suffers.

For refactoring specifically, agents tend to take the shortest route to a destination. They need explicit guidance to consider the big picture, finding all instances where X should become Y, not just the single spot noticed during review. That's why it's sometimes fine to submit a CL before you fully agree with every detail, then revisit it for refactoring rounds. Source control works remarkably well as a pairing tool with agents.

Tests Come First

A solid test suite is the single biggest factor in agent success. Agents perform best when they have reliable tests to check their work against.

For the pycparser rewrite, an extensive existing suite was in place. For watgo, the first step was figuring out how to adapt the test suites from the WASM spec and the wabt project. If no such tests exist for your project, building or borrowing one should be your priority. However, beware of self-reinforcing loops: trusting agents to write both tests and the implementation they verify is risky.

Go: A Readability Advantage for Agent Code

Go is an excellent language for agent-written projects because it's designed for human readability. Its biggest strengths align perfectly with the experience of reviewing agent output:

  • The language changes infrequently, so there's little doubt about idiomatic approaches.
  • Fewer ways to accomplish a given task lower cognitive load.
  • The standard library covers a lot, reducing pressure to track the latest package fashion.
  • Go's design priorities — explicit error propagation, uniform formatting, opinionated defaults — make for predictable code.

Humans working with agents spend most of their time reading, not writing, code. That makes readability compound into a huge advantage. When a project is 99% reading and 1% writing, a language optimized for writability is a poor fit. Go's readability focus keeps code review practical and efficient.

Don't Learn New Subjects With Agents

For a subject you're learning from scratch, this approach is strongly discouraged. Genuine understanding requires working through the material yourself — reading, designing, writing the code. Agents don't change that. Copying from Stack Overflow was never a way to truly learn a topic, and delegating to an agent isn't either. Agents can serve as learning aids, but they can't learn for you.

Junior engineers should be especially careful. There's no substitute for the difficulty of mastering challenging material. If the process feels too easy, you're probably not gaining depth. For senior engineers, agents are a genuine boon when used judiciously — increasing productivity, reducing drudgery, and overcoming procrastination.