How I Build Software with AI, According to My Transcripts
Context
Over the past few months I've built and hardened four Rust projects with Claude Code: rusty-maths (a math library with an expression engine), rm-repl (a terminal calculator and grapher built on it), a terminal chat client, and pi-watcher (a network watcher daemon for a Raspberry Pi). Real projects, real merged PRs, one of them running on my network right now.
Everyone has opinions about how to build software with AI. Most of that advice is generic, and most of it is written from memory, which flatters. But every Claude Code session leaves a transcript on disk. So instead of writing down what I think my workflow is, I had Claude extract every prompt I typed — about 700 of them — and look for the patterns that repeated across projects and correlated with the sessions that produced the best results.
Problem
The question is not “can AI write code?” It obviously can. The question is what the human side of the loop looks like when the collaboration works — specifically, which habits show up in the sessions that shipped, and which prompts preceded the results I was happiest with.
Approach
The transcripts are JSONL files under ~/.claude/projects/. Filter to user-typed messages, strip the tool noise, and what's left is a longitudinal record of one practitioner prompting one AI across four codebases. Patterns that appear once are anecdotes. Patterns that appear in every project, unprompted, months apart — that's a method, even if I never wrote it down.
Process
1. Prime before you ask
Almost every session starts the same way: not with a task, but with context-loading.
HI Fable, I want you to familiarize yourself wit this codebase to prepare to do a new feature
please read the other sibiling rust projects in the same parent directory to get ideas on how i code, look at the cargo.toml for ideas as well
That second one is the interesting habit: pointing the AI at the rest of the portfolio, not just the repo at hand. “How I code” lives across projects — the lint rules, the CI shape, the naming instincts. Loading it up front means the generated code lands in my style instead of a generic one. The payoff showed up concretely when I asked, for pi-watcher, “looking at my other codebases, what CI would be good for this?” — the answer compared all four repos, kept the best ideas from each, and flagged which older repos should borrow improvements back.
2. Plan twice, then build once
The biggest single result in these transcripts — a ground-up rewrite of rusty-maths' function-catalog into a single-source-of-truth macro system — came from the most heavily front-loaded planning. The sequence of prompts, in order:
Give me a solid plan first
I want you to do a second pass over this idea and make sure it is robust, I love it but want to make sure first
THis is looking very good, one final pass to make sure. I trust you but the more we prep the better it goes
Okay, I want you to look over the whole chat one more time and do a solid, granular to do list of what you will do.
Three review passes on the plan before a line of code changed. Then, and only then: “agressive yes, go big or go home. make sure you do this in a branch so I can revert if needed” — maximum ambition paired with a cheap undo. My reaction afterward, verbatim: “it is wild to me that my simple ask lead to a total rewrite” — and the rewrite stuck. The pattern generalizes: effort spent scrutinizing the plan buys the right to be aggressive in the execution.
3. Delegate in numbered batches
The single most common prompt shape in the whole corpus: the AI proposes a menu, I pick by number.
Do 1-3, 6,7,8,9, sqrt, pop and the catch all.
do 1-3 and then lets talk
Do A and I want to think more about B while you do it
no 5 yet
This keeps the division of labor clean. The AI is good at enumerating options exhaustively; I'm the one with taste and context about what this project actually needs. Every decision stays mine, but I never have to generate the option space myself. Note the last two: batching also creates natural checkpoints (“then lets talk”) and lets me defer decisions without losing them.
4. The second-pass ritual
After every substantial build, the same move appears — in every project, phrased slightly differently:
Do a second pass to make sure everything you just did is high quality, no new features, make sure you did your best work
please go back over everything you just built in a highly granular fashion and make sure that it is top notch
do another pass to make sure the code is tight
The key constraint is “no new features” — the second pass is a different activity from building, and mixing them dilutes both. For pi-watcher I escalated the ritual: switch models mid-session and ask for “fresh eyes”, on the theory that a different model has different blind spots. Same instinct as asking a different colleague to review, and it repeatedly surfaced things the builder-pass had glossed over.
5. Keep the surface for yourself
One thing I consistently refuse to delegate: being the user.
dont run any terminal session, do all the testing you can with tools and then tell me what you want me to check visually
dont worry about testing the repl, i can do that visually
Then I sit in the actual REPL, type real expressions, and paste the output back. That's how the best bug of the batch was found. The AI had built span-carrying errors that pointed at the offending token — and my manual poking noticed that sin(2,2) failed with a generic stack error while ch(2,2,2) failed with a precise span. My entire bug report: “Hmmm, sin/cos dont act like ch”. That one line of observed inconsistency drove a consistency refactor across every function in the catalog. Tools can run tests; only the human notices that something feels wrong at the surface.
6. Argue about boundaries, not syntax
The conversations that most shaped the architecture weren't about code at all — they were about where things belong:
user defined equations that are callable just like sin etc... that may be for the repl layer though... yeah that doesnt belong in this engine
do you think the pipe belongs in the repl layer? that consumes this library?
yeah, this is supposed to be a functional library that gives the calculations, not user state management
Notice I'm thinking out loud and answering my own question mid-prompt. The AI's role here is sounding board with perfect knowledge of the codebase — it pushes back when the boundary I'm drawing contradicts something already in the code. Design details got the same treatment: when a proposed pipe operator |> bothered me (“is there a simpler char to use then |>? that is hard to type”), the fix came from me (“what about just |, unix style”), and the synthesis — accept both — from the conversation.
7. Fence the scope
Scattered through every session, small guardrail prompts:
dont touch rmr yet
dont make any functional changes, but just make sure the whole app is currently in allignment with the rest of it
To be honest, I only truly care about the equation work, the rest is less important to be highly robust. Filter down your review to just that
dont custom fit it so tightly to my internet, make the tiles configureable
Each one is cheap to type and prevents an entire category of unwanted work. The last one is my favorite: catching the AI over-fitting a solution to my exact situation and steering it toward the general tool. Telling the AI what not to do turns out to be as load-bearing as telling it what to do.
8. Own the code anyway
The strangest and maybe most valuable session in the corpus produced no code at all. I walked Claude through the terminal-graphing internals of rm-repl — code I hand-rolled before AI assistance — and just… talked about it.
i was pretty proud to hand roll all that normalization stuff to go from real coordinates to braille
what do you think is the most blessed line of code here
yeah that visited flag was an idea i came up with when I was making minesweeper in the browser
Part rubber-duck, part code archaeology, part — honestly — wanting a knowledgeable audience for work I was proud of. But it's also maintenance of ownership: if the AI writes more and more of the code, deliberately re-reading and re-explaining the codebase is how it stays mine. The inverse prompt shows up too: “tell me how the new algorithm works, i think I have seen it before but i dont remember” — never letting generated code stay unexplained.
9. Know when to stop
Mid-way through planning a linear-algebra expansion, one prompt kills the whole thread:
ykw, I am going to just use matlab
The cheapest feature is the one you realize you shouldn't build. AI makes building so frictionless that the discipline of not building matters more, not less.
Sources & References
- rusty-maths — the math library; site of the macro rewrite and spanned-error work
- rm-repl — the REPL/grapher; site of the surface-testing and code-archaeology sessions
- pi-watcher — the network watcher; site of the fresh-eyes reviews and CI cross-pollination
- Local Claude Code transcripts under
~/.claude/projects/— the raw evidence, ~700 user prompts across nine sessions
Outcome
Written down, the loop is: prime → plan (twice) → delegate in batches → build → second pass → fresh eyes → test the surface yourself → commit. None of it was designed; all of it was discovered in the transcripts, repeating across four projects that didn't share a session between them.
The three best results each trace to a different part of the loop. The rusty-maths rewrite came from the planning ritual — the most scrutinized plan produced the most aggressive change I trusted. The spanned-error system came from curiosity plus delegation — “I quite like the position carrying error.. expand on it for me” followed by “Go all out” turned an implementation detail into the library's flagship feature. And pi-watcher came from the priming pattern at its purest: the project started as three sentences of plain English about my home network and the thing I couldn't see — “I have no way of knowing if the cellular internet is bombing out”. No spec, no architecture. Just an honest description of the problem, context about the environment, and the loop applied from there.
Open Questions
Does the second-pass ritual have diminishing returns? By pass three the findings get cosmetic, but the pi-watcher fresh-eyes passes with a different model kept finding real issues — I don't yet know whether the value is in the repetition or the model diversity.
How much of this loop should become automation? Some already has: the review passes are drifting into skills and slash commands. But the parts I refuse to delegate — surface testing, boundary arguments, the kill decision — may be load-bearing precisely because they're manual.
And the older exploratory chats (CUDA experiments among them) live outside these local transcripts; mining those is a follow-up post if the patterns there disagree with the ones here.