Build with data. Test as a stranger. Ship clean.

Build with data. Test as a stranger. Ship clean.

Three disciplines from building a portfolio app with AI coding agents.

In the old world, two people built software: a developer who wrote it, and a tester who tried to break it. AI coding agents collapsed those two roles into one person. You prompt, the agent builds, and you are the only one left to catch what it got wrong. That collapse is the whole opportunity and the whole risk.

Over the last month I built a portfolio desktop app this way — Muse Code on my Windows PC doing the building, Meta’s Muse as the thinking partner — and three disciplines emerged that make the one-person workflow actually work. They are: separate the data from the app, front-load your tokens into the prompt, and keep three environments, not one.

1. Start with data — then engineer the separation.

Every app starts the same way: with data. A game, a financial tool, anything — you need data in the first cycle, because data is what makes behavior visible. An empty app tells you nothing. You cannot see whether the net worth math works, whether the chart draws, whether the tax view makes sense, until real positions flow through it. So you build with your own data. That is correct. It is also the trap.

The trap is that the data you build with has a way of becoming part of the app. It leaks in through seeded defaults, through settings files, through a folder you copied instead of cloned. The moment of truth for the portfolio app came when I cloned it into another folder to test it as a new user. The “empty” clone showed a full net worth, a spending capacity, a drift chart with real history — my financial life, presented to a stranger as if it were theirs. The clone had no positions loaded, yet it knew my home value, my Social Security numbers, my tax budget. That is what happens when data separation is an afterthought.

The fix is a discipline, not a feature. Data must live in files that are never part of the app itself — ignored by version control, never committed, never shipped. And the app must have a delete-data function that returns it to a true blank: no account names, no numbers, no charts, no cheerful “all complete” message for zero positions. Delete-data is the boundary line. On one side, development with your data. On the other, a stranger’s first run.

Then comes the test that replaces the tester you no longer have: clone the app into another folder, delete the data (or start clean), import data — maybe the very same data you built with — and watch how the application behaves from a new user’s perspective. In the portfolio app, that clone test caught real bugs that never showed up while building with data: account names surviving delete-all, a Save counter nobody could decode, an Accounts tab that never refreshed, a guided view pointing at an account that no longer existed. None of those appeared in the builder’s view. All of them appeared in the stranger’s view.

The rule is simple, and it follows from the collapse: you are the developer and the tester now. So you need both views in front of you. Data separation plus delete-data plus clone-and-import is how you get the second view.

2. Max out your input tokens; starve your output tokens.

Before the method, the landscape — because AI has split into two worlds, and the workflow only makes sense once you see both.

The first world is the chat buddies: Gemini, Grok, ChatGPT, DeepSeek. These come with generous free coverage — you pretty much never run out of quota — and they are very capable of looking at your GitHub repos, or wherever you store your code, and analyzing that code well. This is the helper.

The second world is the coding agents: Muse Code, Claude Code, Codex, Antigravity. These can reach different models on the back end, or they are fixated on one — Muse Code, for example, always works with Muse models. Either way, they consume a lot of tokens, and that is where the main feast for AI is right now: these are the expensive tools. This is the builder.

So you have a helper and a builder. The helper is cheap and nearly unlimited; the builder is expensive and metered. The entire economics of the workflow follows from that split: maximize your input tokens, minimize your output tokens — do your thinking with the helper, and spend the builder only on building.

Input tokens cost roughly half what output tokens do, and if you are on a lower or free tier, rate limits decide how much you can build in a day. The coding agent’s output is the expensive, limited resource. So do not spend it on the agent guessing what you want. Spend the cheap input instead: make the prompt as long and as clear as possible, and make it suggest the fixes, not just describe the symptoms.

The practical method is two agents, not one. During testing, keep a chat model open — Meta Muse, Gemini, Grok, whichever you like — and feed it everything as it happens: screenshots, the exact tab and state, what you expected, what actually happened. Do not batch it in your head. Let the issues accumulate through the session, with the chat model helping you sharpen each one: what is the real defect, what is the fix, what does “done” look like. Then, when testing is done, turn the whole session into one big prompt for the coding agent — Muse Code, Antigravity, Codex, Claude Code, whichever builds for you.

What you are doing, in effect, is maxing out input tokens to save output tokens. The agent does not burn output guessing, re-asking, or rebuilding the wrong thing three times, because you already told it exactly what to build: the tab, the state, the screenshot, the expected behavior, the definition of done. In the portfolio app, the sixth build prompt came out exactly this way: a morning of clone testing, screenshots fed to the chat model, issues collected, argued over, corrected — SpaceX, it turned out, is public after all, ticker SPCX, and the chat model checked that — and finalized into a single prompt. One input, one build, instead of five rounds of “no, not that.”

The discipline, stated bluntly: the prompt is the spec. If it takes you an hour to write, that is the cheap hour. The expensive hour is the agent rebuilding.

3. Keep three environments, not one.

If you come from traditional enterprise development — SAP, Oracle, any large application — this part is not new. The standard landscape has always had three systems: development, QA, and production. You build in dev, you prove it in QA, you run it in production. That separation was the sanity mechanism: each stage had a different job, a different audience, a different risk.

AI collapses the jobs. Development, testing, QA, UI — work that used to sit in separate roles and separate teams now happens in one conversation with one agent. So how do you keep the sanity when the roles have merged? You keep the environments even though you lost the roles. The logic is exactly what it always was; only the people changed.

The three places, kept for the same reasons:

The first is the development environment: the folder where you build with your data, iterating until the app works and until data separation and delete-data work. This is your workshop. It is allowed to be messy, because it is yours.

The second is the QA environment: the clone in another folder, where the data has been removed and you test from a new user’s perspective, creating or importing user data there. This is the stranger’s chair. Nothing here is allowed to be yours except what you deliberately bring in.

The third is the production environment: the shipped artifact — the repo release, the installed app, the web app. It carries no developer data by construction, because the first two environments already proved the separation.

The three tiers map to three questions: does it work (dev)? Does it work for a stranger (QA)? Does it work for everyone (production)? Skip the middle tier and you ship your own data, your own assumptions, and bugs that only a stranger would notice — because you never looked at it as one.


The old workflow had two people and three environments. The AI workflow has one person — so the workflow itself has to supply the second person (the clone test), the spec (the big prompt), and the boundary (data separation). Build with data. Test as a stranger. Ship clean.


Write a comment