hjr265 recently published an account of building GitTop, a terminal TUI that displays git repository activity the way htop displays processes, using a fully agentic coding workflow. The agent wrote the code; hjr265 directed and evaluated. The tool works. The experiment succeeded on its own terms.
The part worth dwelling on is not whether the agent got the code right. It clearly did well enough to produce something usable. The part worth dwelling on is what “fully agentic” means for the several hundred small decisions that exist inside any non-trivial program, decisions that nobody explicitly made.
Every Program Is a Pile of Micro-Decisions
When you write a tool yourself, you make continuous small choices without registering them as decisions. You pick a refresh rate. You decide how many commits the activity window looks back. You choose whether authors are deduplicated by email or by name, case-sensitively or not. You decide what happens when the working directory is not a git repository: hard exit with an error, fallback to a friendly message, silently poll until one appears. You choose a color scheme based on what looks readable to you in your terminal.
None of these choices appear in a specification. They are not documented anywhere. They fall into the code through implementation, and the developer who wrote them could reconstruct the reasoning if asked.
In a fully agentic project, the agent makes all of these choices by drawing on priors from training data. It builds what a git activity tool “usually” looks like. The developer gets the aggregate of those choices without having made them.
For GitTop specifically, the primary Go TUI framework is bubbletea from Charm, which uses an Elm-inspired Model/Update/View architecture. Every field in the Model struct is an implicit design decision:
type Model struct {
repos []RepoActivity // which data to show
selected int // navigation state
viewport viewport.Model // scroll handling
width int // terminal width tracking
height int // terminal height tracking
sortBy SortField // default sort order
tickInterval time.Duration // how often to refresh
loading bool // loading state indicator
err error // error display state
}
Each of these fields represents a choice the agent made. The tick interval might be one second; it might be 250 milliseconds. The default sort order might be by commit count, or by recency, or alphabetically by author. The agent applied its priors and produced something coherent. Whether it produced something that matches what hjr265 would have built from scratch is a separate question.
Inheriting a Codebase You Didn’t Write
The experience of maintaining agent-written code resembles inheriting code from a competent stranger. The code builds. Tests pass. The logic is readable. But you did not make the design choices embedded in it, so before you can modify anything substantively, you must first reconstruct those choices through reading.
This is different from using a library. With a library, the boundary is explicit: you call an API, the library’s internals are someone else’s concern. With agent-written application code, the boundary is diffuse. The code is nominally yours. It lives in your repository. You are responsible for it. But the design judgment inside it came from somewhere else.
For a small tool like GitTop, this is manageable. The codebase is compact enough that a developer can read the whole thing in an hour and reconstruct the reasoning. The micro-decisions are visible, correctable, and not load-bearing at scale.
For larger projects, the inheritance problem compounds. A ten-file codebase has tens of embedded choices. A hundred-file codebase has hundreds. At some scale, the developer who nominally owns the project becomes more of a reviewer than an author, continuously catching up with decisions that were made without them.
What bubbletea’s Architecture Reveals About Agentic Legibility
One thing that works in GitTop’s favor is the framework itself. Bubbletea’s Elm architecture forces explicit state. The Model struct is a complete, readable inventory of what the program tracks. The Update function is a total function over messages, which means the agent cannot hide state in implicit mutation. Every decision about what data to maintain and how to update it is visible in one place.
This is a form of agentic legibility that framework design can either help or hinder. Compare a bubbletea application to the same tool written with a more imperative TUI library, where state lives scattered across goroutines and global variables. The agent can produce both, but the Elm architecture makes the inherited decisions much easier to audit.
This suggests something practical for teams considering fully agentic development: framework choice affects how legible the agent’s output will be to you afterward. Libraries that enforce explicit, centralized state (bubbletea, Redux, XState) produce agent output that is easier to review and own than libraries that allow distributed, implicit state.
The Verification Gap for TUI Tools
There is a specific problem in TUI development that sharpens the micro-decision issue. The agent cannot run the code visually. It compiles, it runs go build, it executes against test cases. But it cannot see whether the layout looks correct at 80 columns, whether the color choices work in a dark terminal, whether the information density feels right at a glance.
So the agent fills those gaps with defaults: standard Charm color palettes, conservative padding, straightforward list layouts. These are reasonable defaults, which is exactly the problem. They are good enough not to trigger correction, but they represent the agent’s aesthetic judgment rather than the developer’s.
In a standard software development context, visual defaults get adjusted through iteration: you run the tool, you decide something looks off, you change it. In a fully agentic context, the developer has to actively interrogate the visual output, not just accept it because it works. The invisible decisions in a TUI are the visual ones, and they require extra effort to surface.
What the Skills Shift Looks Like
Building with a fully agentic workflow does not reduce the cognitive load; it redistributes it. Before the agent starts, you carry the weight of specification: articulating what you want clearly enough that the agent’s defaults align with your intent. After the agent finishes, you carry the weight of evaluation: reading code you did not write and assessing whether the embedded decisions match what you would have decided.
These are real skills. Writing a clear technical brief is not trivially easier than writing the code it describes. Reading unfamiliar code with critical judgment is not trivially easier than writing familiar code from scratch.
What changes is the timing and mode of engagement. The developer’s work concentrates at the beginning (specification) and end (evaluation) rather than being distributed across the implementation. For projects where implementation is mechanical and the interesting decisions live at the requirements level, this is a genuine gain. For projects where the interesting decisions emerge during implementation through direct contact with the material, something is lost in the translation.
GitTop is a good example of the first category. The interesting decisions about what to display and how to navigate are in the requirements. The implementation, shell command invocation, bubbletea wiring, output formatting, is largely mechanical. The fully agentic approach fits the problem shape.
The harder question is what happens when you build something in the second category: a project where you only discover what you want by writing it. That is where the specification-first model of fully agentic development starts asking more of the developer than it gives back, and where the inherited-codebase problem stops being manageable and starts being a genuine liability.