Skip to content

Latest commit

 

History

3 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 

Repository files navigation

Building a Commercial App with Developer Agents

How I built and shipped a real product in 65 hours — without writing a single line of code

With mature agents, the prompt only carries intent. Everything else the agent needs already lives in its operating environment: the skills, the memory, the test harness, the gates. Twenty years ago I built software frameworks so developers could write features fast on hardened foundations. The agent's operating environment is that framework's successor — and the features it lets me build fast are two-line prompts.

This repository is a primer. It tells the story of how I built Curoo — an iPhone-first management app for auto repair shops — in roughly 65 hours over a week and a half, using Claude's developer agents, with not one line of code written by my hand. It is live today, in beta, running in a real garage. The skills/ folder contains working, generic versions of the skills that made it possible. Take them, adapt them, and build your own.

Contents

Chapter What it covers
Prologue: Six Months of "AI Can't Code (For Me)" The skeptic's road to the experiment
The Context What was actually being built, and why it's hard
Synopsis The whole story in one page — start here if short on time
The Autonomy Ladder Five rungs from tool user to autonomous process
The Agent Setup CLAUDE.md, the pipeline, Gitflow, and automated gates
The Demo, the Customer, and the Second Machine The backend, the handoff protocol, Slack, and maturing agents
The Methodology Thirty years of method, translated to agents — and token economics
Production Two clouds, the diff I photographed, and the App Store
Where the Time Actually Went The honest accounting of 65 hours
Enterprise Guardrails The eight-item checklist for governing agentic development
Start Here Replicating this setup, step by step
Repository Layout What's in this repo and how to use the skills

Prologue: Six Months of "AI Can't Code (For Me)"

Before any of this, I was a skeptic with receipts.

I had been using GitHub Copilot for about six months. Everyone around me kept saying AI can code now, and I kept not seeing it. A colleague at work showed me a small app he built with Copilot — visualize and search data, working, real. So I tried. And tried. I could not figure out how to get AI to build. Not autocomplete a line — actually construct something. Whatever my colleague had unlocked, I could not reproduce it.

What I did not realize at the time: behind the Copilot interface, my colleague had selected Claude as the model doing the work. Same facade, different engine. I was concluding "AI can't build apps" from an experiment where I did not know which AI I was testing.

The correction came over a beer. A college buddy was raving about how Claude was writing code for him — whole features, not suggestions. I had heard enough secondhand hype by then. I told him, now I must try Claude. I went home, bought a subscription, and set up the fairest test I could think of: my existing codebase, the same one I had been working on with Copilot, as the baseline. Same code, same me, same kinds of asks. Only the tool changed.

I spent that entire Saturday validating his claim, and being honest with myself about whether it was really doing what people said. It was. Claude Code did, on my own codebase, what six months of Copilot had not done for me.

Once the claim held, my natural instinct kicked in: what is the art of the possible here? So I raised the stakes. I handed Claude one of my most complex ReactJS front-end apps and asked it to review and upgrade it. Not a toy — a real, gnarly codebase with history. The outcome amazed me. That project is still ongoing, and it is a story for another day. But it settled the question that mattered: this was not a tool that only worked on small, clean problems.

After that Saturday, my curiosity was too high to stop. I did not want to keep testing Claude on code that already existed. I wanted to know what it could do from zero, hands-free, on a clock. What I needed was the right project.

It found me. Picking up my car from the garage — the same shop I have been going to for twenty years — my mechanic was complaining about writing invoices. How long it took. How it ate his day. I said, let me see what I can do.

It was an honest offer, because I was not guessing at his problem. I have hung around that shop enough to understand the workflow at the counter. I helped with their website, so I knew the business side — not the mechanic work, but how the money and the paperwork moved. On our outings I ask him questions about his business, the way you do with a friend whose world interests you. Two decades of that adds up to something no market research buys.

As an experiment, it was the clean slate I wanted: a greenfield build, a real business, a real user waiting, and three questions to answer from zero:

  1. Can it go hands-free? A complete application from an empty project, with not one line of code written by my hand.
  2. How fast? Real elapsed time, honestly counted, for a commercial-grade product.
  3. What is agent-based coding, operationally? I needed to understand it firsthand, because part of my professional role is designing engineering guardrails for a large enterprise — governance that keeps engineers out of the failure modes that cause production outages. Guardrails, in my practice, are not gates that block. They are checklists that catch. You cannot design honest guardrails for agentic development from conference talks. You have to have lived it.

Curoo was that experiment. A week in, the mechanic who complained about invoices was asking to run his shop on it. Here is how.

Two lessons from that first Saturday shaped everything that follows. First: "AI" is not one thing. The model doing the work matters more than the interface wrapping it. If you have concluded agents cannot code, make sure you know which agent you tested. Second: baseline on your own code, then probe the ceiling. The same tool on a codebase you know intimately is a test you can trust — and once it passes, the next question is not "does it work" but "how far does it go."


The Context: What Was Actually Being Built

Before the agent setup makes sense, you need to understand this was not a to-do app or a weekend CRUD demo. This was a commercial product for a real industry with real workflow complexity.

The problem. Most independent auto repair shops still run on paper. A customer walks in, the owner scribbles the complaint on a ticket, the mechanic writes diagnostic notes on the same ticket, someone calls the customer to describe the estimate over the phone, waits for a callback, does the work, and hand-writes an invoice. Every step is slow, error-prone, and interrupts the actual business of fixing cars. The owner is the bottleneck — every approval, every callback, every piece of paperwork goes through them.

What the software has to do. Digitizing that workflow sounds simple until you enumerate it:

  • A relational data model with real depth. Customers own multiple vehicles; vehicles accumulate a service history across multiple visits; each visit produces a job with the customer's original complaint, diagnostic findings, an itemized estimate, and eventually an invoice. Every entity links to the others, and the history has to be queryable years later ("what did we do to this truck last time?").
  • A document lifecycle with rules. An estimate is not just a document — it is a state machine. It is drafted, sent, viewed, approved (or declined, or revised and re-sent), and only an approved estimate can become an invoice. Skipping or reordering states creates legal and trust problems for the shop. The software has to enforce this, not just display it.
  • Communication with people who don't have the app. Estimates and invoices go to customers by text or email, and the customer approves from their own phone with nothing to install. That means generating clean, professional documents, delivering them over SMS and email, and capturing an approval the shop can rely on.
  • An AI drafting layer. Mechanics write in shorthand; customers need plain language. The app takes the raw intake notes and diagnostics and drafts both the formal job write-up and a customer-friendly message — which the owner reviews and approves rather than writes. Getting AI output into a trust-critical workflow (these documents have prices on them) means the human-review loop has to be designed in, not bolted on.
  • iPhone-first, for a hostile environment. The user is standing in a garage with greasy hands and ten interruptions an hour. Every flow had to survive being used in thirty-second bursts on a phone. There is no training session — a shop owner either gets it immediately or deletes the app.
  • The unglamorous production surface. A commercial iOS app also needs everything around the code: a privacy policy, App Store privacy declarations, an icon set in 18 sizes, listing copy, screenshots, a support channel. None of it is hard; all of it is mandatory; all of it eats time.

The constraint. One person, roughly 65 hours of working time across a week and a half, no team. The bet was that developer agents could carry enough of this — the code, the documents, the assets, the research — that one person's judgment could stretch across all of it.

That bet is what the rest of this primer is about.


Synopsis: 65 Hours from Blank Screen to a Live Shop

Curoo was built by one person in roughly 65 hours over a week and a half, using Claude's developer agents across two machines: a Mac for the iPhone app, and an Ubuntu box for the server side.

The stack. A SwiftUI iPhone app — SwiftUI on Claude's own recommendation — talking to a Python backend with a Postgres database. The server carries the business logic: the UI asks it to perform everything from record-keeping to document generation and the AI drafting layer.

The approach. Small increments, always. The first request was not "build me a shop management app" — it was "build me a view for customer entry." From there, features grew one at a time toward the full workflow: customers, vehicles, jobs, then the estimate → approval → invoice pipeline, building out what each role in a garage needs — the mechanic writing up diagnostics, the owner or manager sending estimates and collecting payment — until the paper ticket and the hand-written invoice had a full digital replacement.

The pivot that saved the project's economics. I started in Xcode with the Claude integration. It worked — but it was so token-hungry I hit my usage limits in under 10 minutes. The hint came from my own setup: the Claude CLI on my Ubuntu box, doing server-side work, barely dented the same limits. Same model, different surface, wildly different token economics. I installed Claude Code CLI on the Mac and moved iOS development to the terminal, keeping Xcode for building and the simulator. Sessions went from 10 minutes to about an hour. The terminal also worked better as an agent surface: features like plan mode exist in the Xcode plugin too, but in the CLI they behave properly and — crucially — you can always see what mode Claude is in. In the plugin, I often could not tell.

The launch surface. Building the app is half the job. The other half — naming (with live trademark, domain, and App Store conflict checks), market research, a complete logo and brand system, the iOS icon set in all 18 sizes, the privacy policy, and a fully ASO-optimized App Store submission pack — was also produced with Claude, in chat and Cowork sessions. The agents did not just write code; they carried the entire commercial surface of shipping a product.

The result. Curoo is live today, in beta, running in a real garage — the first customer being the shop it was built for. Paper tickets out; the phone in the owner's pocket in.


The Autonomy Ladder: Growing Into Agentic Development

I want to be honest about something before the technical chapters: I did not arrive at a fully agentic workflow. I grew into one, slowly, and mostly by accident. Every bit of autonomy I eventually gave the agent was earned by the step before it going well — and a few times by a step going badly enough to teach me something. Looking back, I can see five distinct rungs on that ladder. I am laying them out here because I think the ladder, more than any config file, is the thing worth copying.

Rung 0 — Tool user. This is where everyone starts, and there is no shame in it. Claude lived inside the Xcode plugin, I made small asks — build me this view, fix this error — and reviewed everything it gave back. Nothing about this felt "agentic"; it felt like a very capable autocomplete. But this rung did its quiet work: it is where I learned how the agent responded to instructions, and where I ran into the token economics that would push me to the terminal. Even the frustrations of Rung 0 were teaching me things I would need later.

Rung 1 — Supervised planner. Moving to Claude Code in the terminal, I began using plan mode formally. The rhythm was deliberate to the point of tedium: Claude drafts a plan for the feature, brings it to me, and nothing happens until I approve it. Then, during execution, I approved every single command as it ran. It was slow. It was also, I now think, the most important stretch of the whole project — because this is where the alignment happened. Every plan I corrected taught the agent my conventions, and those corrections accreted into CLAUDE.md as standing memory. Meanwhile, watching every command taught me the agent's habits and failure patterns. We were, in a real sense, onboarding each other.

Rung 2 — Conversational delegation. Somewhere along the way the ceremony fell away. I stopped reaching for plan mode as a formal switch and simply said, in conversation, "go plan this out and come back to me before you build." Same discipline, lighter touch. The gate never moved — no approved plan, no code — but the relationship had become fluent. If Rung 1 was reading from a script, Rung 2 was two colleagues who had found their shorthand.

Rung 3 — Autonomous execution. About a week in, I discovered auto mode, and it genuinely changed my life for that stretch — because I no longer had to sit in front of the computer. I would approve the plan and walk away. Claude wrote the code, built it, tested it, and fixed its own compile errors, driving Xcode from the command line the whole time. I would come back to a finished feature and judge it the only way that matters: on my actual phone. Here is the thing, though — auto mode on day one would have produced confident garbage. It worked in week two only because the week of supervised plans had aligned us. The feature did not make the workflow trustworthy; the history did.

Rung 4 — Autonomous process. The last rung was not about code at all. Claude was already pushing to feature branches and then asking me to click through the pull requests — feature to dev, dev to release, release to production. Eventually I asked it, in plain conversation, whether it could do the promotions itself. Getting there took a few real hours spread across several days: setting up a password manager so Claude could use scoped, least-privilege access tokens rather than my credentials, and working together to find the right GitHub and Bitbucket API calls. When it clicked, the agent was running not just the code but the workflow — with me remaining, deliberately, the human approval at every gate.

One more thing about how this actually felt, because the word "ladder" makes it sound tidier than it was. Most of these rungs were climbed in ten- and fifteen-minute fragments, squeezed between the rest of my life, across days. That is the real promise of this way of working — not that it turns you into a machine for 65 straight hours, but that it makes small fragments of attention count, because the agent holds the state between your visits.

If you take one thing from this chapter, let it be this: the ladder is climbed in order. Each rung is earned by the one below it, and the agent's track record — not its feature list — should set your pace. Start slow. The speed comes.


The Agent Setup

The experiment: not one line of code by hand

This started as a deliberate experiment, not just a build: could Claude Code produce a working iOS app from instructions alone, with me writing zero code myself? No backend at first, no multi-agent architecture, no named agent roles — just Claude Code in a terminal, an empty iOS project, and me conversing with it. Everything else in this primer grew out of that constraint holding: through the whole build, I never wrote a line of code by hand.

CLAUDE.md: grown, not written

I did not write the agent's configuration up front. When you initialize Claude Code in a project, it generates CLAUDE.md — the file the agent reads at the start of every session to understand the project. Mine started as whatever initialization produced. From there I grew it through conversation: when I found myself repeating an instruction, or when Claude made a choice I wanted made differently next time, I told it to remember that — and the correction became standing memory instead of something to repeat tomorrow.

The takeaway: treat CLAUDE.md like a senior engineer's onboarding notes, written during the project, not before it. If you are saying something to your agent twice, it belongs in the file.

The pipeline: plan → build → test → QA on the phone → release

Every feature moved through the same five stages:

  1. Plan. Claude plans the feature — what the view needs, what changes where — and brings the plan to me for approval. No approved plan, no code.
  2. Build. Claude writes the code, in small increments — never "build the whole feature" in one shot.
  3. Test. Claude builds and tests autonomously, running Xcode from the command line, fixing its own compile errors and failures before presenting the feature.
  4. QA on the phone. The stage most solo builders skip. The feature goes onto my actual iPhone and gets used the way a shop owner would — thirty-second bursts, real fingers, real interruptions. The simulator lies; the phone doesn't.
  5. Release as production-ready. Only after phone QA does a feature count as done.

The discipline mattered more than any individual stage. Agents make it dangerously easy to keep building — code keeps flowing, everything looks done. The pipeline forced every feature through a gate where I, not the agent, judged it finished on the device it would actually live on.

Release discipline: Gitflow, even for an army of one

Agent-written code got no shortcuts on source control. The project ran Gitflow, with four branch tiers and hard gates between them:

feature/* ──PR──▶ dev ──PR──▶ release ──PR──▶ production
  • Feature branches — the only branches that accept direct commits. All development happens here.
  • Dev — the integration branch. Features arrive only by pull request and merge commit.
  • Release — the QA branch; whatever sits here is a release candidate. Promoted from dev by PR only.
  • Production — live code. Reached only when the release candidate passes the QA gate, again by PR.

Two rules were non-negotiable: every promotion goes through a PR and merge commit, no exceptions — and nothing gets deleted except feature branches, which are removed after merge to keep the tree clean. The repo lives on both GitHub and Bitbucket.

Why bother, alone, in a 65-hour sprint? Because the gates are exactly where a human belongs in an agent workflow. Auto mode meant Claude could produce large amounts of working code without me watching — so the PR points became my checkpoints: deliberate decisions that a batch of agent work is ready to move up a tier. The phone-QA stage maps directly onto the release branch: nothing crossed release → production without having been used on my actual iPhone.

Automating the gates — the same trust curve, again

The git workflow went through the same maturation as the coding itself.

Phase 1 — Claude codes, I click. Initially Claude pushed code to the feature branch and then asked me to create the PR. I did every promotion by hand, in the web UI.

Phase 2 — teaching Claude to run the railroad. Eventually I asked Claude, in plain conversation, whether it could do the promotions for me. Getting there took a few real working hours spread across several days: setting up a password manager on the Mac so Claude could access repository credentials without me pasting secrets into chats, then working with Claude to find the right GitHub and Bitbucket API calls to create and merge PRs programmatically. Once it worked, each passed gate triggered the next promotion automatically — with my approval remaining the gate itself.

Use scoped, least-privilege access tokens for this — fine-grained tokens limited to the one repo, stored in the password manager. That is what I did, and it gives you better control. Never give an agent your account credentials.

Phase 3 — review by skill-equipped advisors. Later, the gates themselves matured. I prompted both agents to develop review skills — explicit definitions of what a PR review must check — and to use advisor agents as the reviewers. The agents hand the reviewer the skills we defined, and the advisor reviews the PR through that lens — our standards, not the model's generic instincts. Every PR, on both repos, is gated through sub-agents this way. The standards live in skills (versioned, improvable, shared between agents), the reviewing is done by advisors who never get tired or rushed, and the human supervises the standards rather than re-reading every diff. I stopped being the reviewer and became the author of what review means.

The takeaway: agents remove the cost of process, not the need for it. Branch gates are the control surface that makes "walk away while it codes" safe — and once the gates are trustworthy, the gates themselves can be automated, with you as the approval.


The Demo, the Customer, and the Second Machine

A working app, phone-first

Roughly a week after starting, the experiment had produced a real, working iOS app. Basic job management, end to end: customers and vehicles could be added, jobs opened against a vehicle, and each job carried its full working detail — services, parts, diagnostics, and so on. Everything the paper ticket held, now on a phone. All of it agent-written; still not one line of code by my hand. In actual working time — those ten- and fifteen-minute fragments added up — this stage had cost only about three hours.

The demo that turned an experiment into a product

Then I did the thing that changed the project: I showed it to my mechanic.

He got excited. Not polite-excited — "I want this now" excited.

That reaction did two things at once. It validated the path — this was not a toy, it was something a working shop owner wanted in his hands immediately. And it converted my experiment into a product with a waiting customer, which meant the honest conversation that followed: what he was looking at lived entirely on one phone. Before he could run his shop on it, I needed to build the services behind it — a server to store the data properly, and security: login, accounts, protecting his customers' information. The app had outgrown the single device it was born on.

That conversation is what summoned the second machine into the story.

The iOS agent designs the server

Rather than starting a fresh agent cold, I asked the Claude that had built the iOS app — the agent that knew every screen, every data shape, every workflow — to design and write the backend. I pointed it at a separate repo, and this time I did not let it improvise the foundations: I gave it explicit architecture parameters, design parameters, and my coding and documentation style up front. It went into planning, produced a very good plan, and I reviewed that plan thoroughly before giving the go-ahead — the Rung 1 discipline, deliberately reapplied at a new frontier.

What happened next honestly shocked me. In under an hour, it implemented the full backend: the Python services, the Postgres schema, the database details — high-quality, well-documented code. My theory on the speed: I chose Python partly because the open-source world is saturated with it, so the agent was operating deep inside its comfort zone. Stack choice is leverage — pick boring, well-trodden technology and the agent repays you in quality and speed.

The catch — and the correction. Flush with momentum, Claude's next automatic move was to install Postgres and stand up the database... on my Mac, which is not where this backend would ever live. The agent was not wrong to want a database; it just did not know my infrastructure. I told it to hold off and only push the code — and then I did what I should have done earlier: I made the topology explicit.

The agents get names. I told the iOS Claude, in its standing instructions, that all server-side work happens on my Ubuntu machine — and I named the two agents so there could be no ambiguity: ios_car_agent on the Mac, ubuntu_car_agent on the Ubuntu box. What began as an unnamed experiment now had a two-agent org chart, each with its own machine, repo, and jurisdiction.

Onboarding the second agent. On the Ubuntu side I pulled the repo and gave ubuntu_car_agent the same deliberate setup its sibling had earned over the first week, compressed into one session: configured Claude Code, configured its memory, configured Gitflow, and prompted its memory into shape until it knew the project the way I needed it to. Then the first real assignment: review the code you have inherited and propose next steps. It reviewed — and, just like its sibling, immediately wanted to set up the database, implement the schema, and test the backend. This time it was the right agent, on the right machine, asking the right question.

TDD as the backbone — and the honest truth about bugs

Early in the project I established a non-negotiable: development happens Test-Driven, full stop — with 100% coverage as the standard across test cases, test code, and code coverage. I reviewed the test cases and test code Claude produced, and was genuinely happy with the quality. In the beginning I reinforced the methodology in nearly every prompt; eventually Claude wrote it into its own memory, and TDD became simply how the project worked. (The same accretion pattern as everything else: repeat it until it becomes standing instruction.)

Gitflow gave the project its gates; TDD gave it its floor. Between them, the implementation stayed solid. But let me be honest about what "solid" means with an agent, because this is where hype and reality part ways:

Claude periodically introduced bugs and shortcomings. Sometimes it broke the app outright. When it did, I asked it to fix what it broke. Sometimes it fixed the problem in one go. Sometimes it took several rounds of prompting and testing to converge. And sometimes its test coverage was not as complete as intended — iOS development is genuinely challenging that way, with many aspects (UI behavior, device states, lifecycle) that are hard to fully capture in tests, and the gaps showed.

This is the truth of the workflow: it is a collaboration between a human and an AI agent toward a shared goal — not a vending machine. The agent writes essentially all the code, but the human supplies judgment: noticing what broke, deciding what "fixed" means, testing on the real device, and holding the quality bar the agent occasionally slips under. TDD and the branch gates are exactly what made the slips affordable — a broken feature was caught by tests or by phone QA in a feature branch, never discovered by a garage owner in production.

If you are planning your own build, budget for this. The agent's speed is real, but so is the convergence loop. The 65 hours in this primer include the rounds of "you broke it, fix it" — that is not overhead on the method; it is the method.

The Ubuntu agent takes over — and a surprise from an old harness

Once onboarded, ubuntu_car_agent did not wait to be micromanaged. It recognized the gaps in what it had inherited and started taking over the implementation.

Two things about the backend phase genuinely surprised me.

The test harness I had seen before — decades ago. The agents — first ios_car_agent, then ubuntu_car_agent following the same pattern — built their test infrastructure around an ephemeral database: for each test run, they created an independent database on the fly, ran the entire suite against it, and scrubbed the database completely after completion. No test ever touched the development environment's data; every run started from a known-clean world.

I recognized this pattern immediately, because I built it myself — back when I worked at MIT Lincoln Laboratory, we used exactly this build/scrub harness so we could test all our code cleanly without worrying about what state the development environment was in. It is a discipline most teams skip because it is tedious to set up. The agent reached for it unprompted. Watching an AI independently arrive at a practice I learned in a national laboratory was one of the moments this project stopped feeling like a toy.

Golden data as a maintained asset. I asked the agents to create and maintain a golden test dataset — a clean, canonical set of data covering all test cases. The key word is maintain: as development uncovered new cases and edge conditions, the agents kept the golden set up to date, treating test data as a living artifact rather than a one-time fixture. Combined with the ephemeral-database harness, every test run meant: fresh database, load the golden set, run everything, scrub. Deterministic, repeatable, and fast.

The payoff compounded. Because tests were trustworthy and cheap to run, the agents could verify their own work aggressively — which raised quality and, counterintuitively, raised speed. The convergence loop got shorter, because a clean harness catches breaks immediately and unambiguously.

The takeaway: ask your agent for the ephemeral-database harness and a maintained golden dataset on day one of backend work. It costs one instruction. It is the difference between tests you run and tests you trust.

The Handoff Protocol: how two agents build one product

This is the part of the workflow I get asked about most: how do two agents, on two machines, in two repos, collaborate on one product without stepping on each other? The answer is not an orchestration framework. It is a discipline we came to call the handoff — the agents write structured documents to each other, through git, with me as the courier and the gate between them.

The cycle, for any feature that spans phone and server — take job estimates as the example:

  1. UI first, fully. ios_car_agent develops the feature completely on the phone side: the UI/UX, the data model, capturing every required piece of information from the user, working through the full user flows. The frontend leads because it is where the requirements actually live — you do not know what the server truly needs until the screens that feed it are real.
  2. The iOS agent writes the handoff. I then ask ios_car_agent to create a request plan — not a full implementation plan, but a statement of what it requires from the backend: the data, the operations, the contract. The agent writes this document into the backend repo. The requirement travels through git, not through my memory or a chat paste.
  3. The Ubuntu agent enhances, not just executes. On the Ubuntu machine, I prompt ubuntu_car_agent to refresh the repo and review the handoff. Here is what surprised me: it does not just take the order. It reviews the ask, understands it, and enhances the plan for implementation — filling in the server-side realities the frontend could not know. I then push it once more: review again, make sure all the cases are covered. Only then does implementation begin.
  4. Build, deploy, and hand back. ubuntu_car_agent completes development fully — TDD, the ephemeral harness, the golden data, all of it — and deploys to local dev (my Ubuntu box is a full dev installation). Then it closes the loop: it writes a handoff of its own into the Ubuntu repo, documenting what now exists and how to call it.
  5. The iOS agent consumes and ships. Back on the Mac, ios_car_agent reads the return handoff, writes the API calls against the real, deployed backend, tests end to end, and produces a full release of the feature.

Notice what the human does in this protocol — and what he doesn't. I never translate between the agents; they speak to each other in documents, in each other's repos, in far more technical detail than I would carry accurately. What I do is sequence and gate: I decide when a handoff happens, I walk it across the machine boundary, and I insert the review pressure ("make sure all the cases are covered") at the moments that matter. The agents collaborate; I conduct.

The takeaway: multi-agent coordination does not require infrastructure. It requires a contract discipline — requirements written down, committed to the consuming side's repo, enhanced by the implementing agent, and answered with a handoff in return. Two terminals and git are enough.

From courier to channel: getting the agents talking

The handoff protocol worked, but it left me with a nagging question: why am I the intermediary?

The dead ends first, because they are instructive. I prompted each agent, at different times, to see whether they could reach each other. Claude Code's web features did not give me what I wanted — one attempt just tried to spin up a scheduled remote agent on the web, which was not my two machines talking. I also had the agents try establishing a network tunnel between the Mac and the Ubuntu box; they could not make that work either. The problem kept bugging me — which, I have learned, is usually the sign I am one insight away.

The insight came from reading the docs. Going through Claude Code's documentation, I hit the section on plugins and got curious. Exploring the plugin ecosystem, I came across Slack — and the idea landed at once: why not make Slack the agents' medium of communication? Not a tunnel, not an orchestrator — a message channel, the same tool human teams already use.

The setup, deliberately simple:

  • One Slack channel: #all_agents.
  • Both agents logged in through my own user account — no separate bot identities, no extra accounts to manage.
  • A message convention: every message declares its route — From: ios_car_agent To: ubuntu_car_agent for agent-to-agent traffic, and From: xx_car_agent To: Leader when an agent needs my approval. Yes, the human's handle in this system is Leader — approvals now happen on Slack, where I can grant them from anywhere, not just at whichever machine is asking.
  • Each agent prompted to handle both directions: write to the channel when it needs to communicate, and poll the channel for messages addressed to it.

The division of labor between channel and repo stayed clean: detailed handoffs still live as documents in the repo — the contract of record does not move to a chat log. What Slack carries is the collaboration layer: the "handoff is ready for you," the "I need this clarified," the "Leader, approve this gate." Documents for contracts, messages for coordination — the same split a good human team keeps between design docs and Slack.

With this working, the proof I was after was in hand: independent agent-to-agent collaboration, running over commodity tools. It needs fine-tuning, and the agents keep getting better at it as we use it — but the human is no longer the wire between them. He is just the Leader in the channel, approving gates from wherever he happens to be. From approving every command, to approving plans, to approving PRs, to approving Slack messages — the same judgment, exercised from ever further away.

Maturing the agents: from amnesia to bootstrap

Something I have not admitted yet in this primer: when this started, I was the amateur. Not at software — I have over 25 years of it, and I know how to build a high-quality team that moves mountains in weeks and ships under budget and under time. But at this — directing AI agents — I was starting from zero, and my hardest-won lesson was about the one thing great human teams give you for free: continuity. Agents forget. Maturing them is a campaign against forgetting, and it went through four escalations.

Stage 1 — Prompts, and the re-prompting treadmill. In the beginning, everything lived in my prompts. When a session's context hit its limit, the agent would lose the thread — and I had to re-prompt from scratch to get it behaving the way it had been. Imagine a brilliant engineer with amnesia: world-class output all afternoon, blank stare the next morning. With my team-building background, this loss of memory really bugged me. You cannot build a team on people who forget the playbook nightly.

Stage 2 — Written memory. The first fix: I figured out the agent can keep things in memory and write them to file. So I explicitly instructed it to do exactly that — persist what matters to disk, do not trust the context window. Agent behavior after a context compaction improved immediately: the file survived what the context did not.

Stage 3 — Skills: the methodology, chunked and loadable. Memory files helped, but I needed something better for the big stuff — how do you get an agent to retain entire methodologies in organized, reusable chunks? I had heard about "skills" constantly but never understood how they worked. So one fine day I sat down and read through the skills documentation properly — and the realization clicked: agents can write their own skills, and load them as needed.

So I prompted both agents to dump everything they held — their methodologies, their architecture knowledge, everything accumulated in memory — into a set of skills. They wrote their own institutional knowledge down as loadable, reusable units. Then I added the team rule: when either agent creates a new skill, it notifies and hands it over to the other agent through Slack. Knowledge stopped being personal; the two-agent team now had a shared, growing library. Every new thing we come across becomes a skill. That, more than anything, is what I mean by a mature agent: not a smarter model, but an agent whose knowledge is externalized, organized, and shared.

Stage 4 — The bootstrap. One pain remained: reboots. When the terminal, the IDE, or the machine restarted, I had to re-prompt the agent back to its previous maturity — sometimes several prompts of "remember, we do TDD... remember, gitflow... remember your skills" before it was itself again. So I prompted both agents to build a bootstrap: on any restart, the agent brings itself back to the latest state — memory loaded, skills available, methodology active — without me reconstructing it by hand. After the bootstrap existed, restarts stopped being an issue. The agent wakes up already knowing who it is.

The arc, compressed: prompts that evaporate → memory that persists → skills that organize and share → a bootstrap that restores. Each stage is the same problem — forgetting — solved one level deeper. If the Autonomy Ladder was about how much I could trust the agents, this is the parallel ladder: how much the agents could retain. A senior engineer is not just someone you trust with the keys; it is someone who does not need re-onboarding every morning. By the end, I had two of those.


The Methodology: Thirty Years in the Making

Where my method comes from: one very long night

I was an Agile practitioner before Agile became a fashion — and like most practitioners of anything, I came to it through pain.

Back in 2006–07, I was building a large system with a small team, myself included as one of the developers. My plan followed the textbook logic of the era: build independent components with well-defined interfaces, develop each fully, and integrate at the end. It is a sound assumption — in a perfect world. In the real one, things move while you build. When the time came to put the parts together, they did not fit. What followed was weeks of long nights getting the system to actually work. A friend stayed with me through those nights, debugging into the early mornings at the office — I remain infinitely grateful to him. We eventually made it all work well.

But I walked out of that experience with a vow: never again.

Risk first: make the scary parts say hello

The insight I landed on was to let risk drive the order of work. I started using risk metrics to identify where things were most likely to go wrong, and attacked those areas first, early, when there was still time to recover.

I was building high-performance trading systems with new technology at the time — and new technology carries a specific kind of risk: you do not know whether it works until it does. So my rule became: wherever there is new technology, and wherever there is an integration point, those get proven before anything else. Without the integrations, there is no application.

The practice: design and develop shell components — skeletons that do nothing but say hello world — and connect them through a vertical or horizontal slice of the application, end to end. The slice is thin, but it is real: it exercises the integrations, the library APIs, the messaging protocols — HTTP and TCP, API-based and event-based alike. Once the skeleton stands and the parts genuinely talk to each other, you flesh it out bit by bit — with the system fully integrated at every step rather than integrated once at the end. The long-nights experience, inverted.

Weekly releases, before that was a thing

By 2007–08 I was applying this at full scale, leading development of a cash trading system at Putnam — among the most advanced systems of its day, with auto-scaling before people were even thinking in those terms, high availability built in, in-memory processing on then-new technology. I made the business a deal that sounded almost like a joke: I would build and release weekly, and they would get to tweak the application as it grew. First week, the system says hello. Next week it says hello, how can I help — and you say hi back. And so on, every week, forever forward. I told them they were in the driver's seat.

It worked perfectly. A critical application, delivered solid, with the business shaping it in-flight rather than discovering at the end that we built the wrong thing.

Years later at SSGM, building Post Trade Reporting for MiFID II, I took one more step and implemented Test-Driven Development — we were the first team to implement TDD successfully in the corporation, and a chosen pilot team. That is why TDD was a day-one non-negotiable with the agents: I had already lived what it does for a team.

That rhythm — thin slice first, risk retired early, always integrated, TDD as the floor, released in small honest increments with the customer in the loop — became how I build software. Eighteen years later, it became how I direct agents.

Product, Platform, Service — twenty years before it had a name

Those lessons compounded into how I have built every high-performance team since. The pillars:

  • Agile first — small honest increments, customer in the loop, always integrated.
  • Risk up front — identify the risks, then mitigate them through early experimentation and prioritized implementation. The scary parts go first, always.
  • Infrastructure and automation before speed — build the CI/CD and tooling early, because speed is bought with infrastructure, not heroics.
  • Frameworks do the heavy lifting — design and build a framework, write the code once, test it until it is solid — then extend that framework to build features as fast as possible. Framework code is reused code, and reused code is hardened code: every feature built on it inherits its solidity and its speed.

The industry now has a name for this — the Product–Platform–Service model. I have been practicing it for twenty years; it is nice that it finally got a title.

The same method, translated to agents

Curoo was my experiment in bringing this exact methodology into the agent space — and it translated almost one-to-one.

Small chunks, skeleton first, iterate to maturity. Just as I once built hello-world shells across an integration slice, the agent gets a skeleton feature first, then iterates it toward mature. The agent works on one small feature at a time — which lets it focus fully, and the focus shows everywhere: in the planning, the building, the testing. It also improves speed, and — because the feature is small enough for its test cases to genuinely cover it — there is very little room left for bugs born of missed cases. Every quality this discipline produced in human teams, it produced in agents: same method, new workforce.

The two-to-three-line prompt. All of which distilled into a working style that surprises people with its brevity: I define the next feature in two or three lines. That is the whole prompt. Then I let the agent research and plan — it explores the codebase, works out what the feature touches, and comes back with the plan for my review.

The brevity is not laziness; it is the methodology paying out. I can spend three lines because everything else is already load-bearing: the skills carry the methodology, CLAUDE.md carries the conventions, the framework carries the architecture, TDD and the harness carry the quality floor, gitflow carries the release path. The prompt only has to carry the intent.

The job changes: from writing code to thinking in features

Notice what this working style demands: I need to know what I am building ahead of time. The thinking has not disappeared; it has moved. Instead of writing code, my working hours now go into working the features and capabilities themselves — thinking through what needs to be there, in what order, and how to prompt for it. The agent absorbed the typing; the product thinking got promoted to being the human's whole job. If you are wondering what a developer does all day when an agent writes every line — this is the answer.

Advisors and adversaries: the agents get their own reviewers

The next maturation step came, again, from reading what the tools could do: Claude Code has sub-agents and advisor agents — agents an agent can call to help with its own work.

One fine day I asked my agents to use advisor agents to review the plans, and to review the PRs as code reviewers. They did a fantastic job — the same second-set-of-eyes function a strong human team gets from peer review, now built into the loop.

Then ubuntu_car_agent went a step further than I asked. During backend work, it automatically called an adversary agent to do deeper poking and testing — playing red team against its own blue team to ensure the backend was hardened. I did not prompt for that; the agent reached for adversarial review the way it had reached for the ephemeral test harness — because the discipline was in the water by then.

All of this is now codified: every skill carries instructions on which advisor agents and sub-agents to use, and when. The methodology does not just live in my prompts or even in the agents' memories — it lives in the skills, reviewers included, so any future session wakes up already knowing that plans get advised, PRs get reviewed, and backends get red-teamed.

It improved development, plainly. In the interest of the honesty this primer runs on: it also consumes noticeably more tokens than before — every advisor and adversary is another mind burning context. Which brings me to the money.

Token economics: tokens are money

Let me say the quiet part plainly: tokens are money, and money is always scarce. Every prompt you send, every file the agent reads, every verbose reply it writes back — all of it is metered. If you are going to run agents as your workforce, token economics is not a footnote; it is your burn rate.

I learned this on day one, the hard way — the Xcode plugin draining my limits in under ten minutes taught me that the same work can cost wildly different amounts depending on how you do it. Ever since, I have been deliberate about it: reading, experimenting, and shaping my working style to minimize usage. The prompting side of my method is itself token-aware — those two-to-three-line prompts are not just a discipline of thought, they are cheap to send. Letting skills and memory carry the standing knowledge means I am not re-explaining the methodology every session. Small features mean small contexts. For a good while, I had the economics at a comfortable point.

Then the advisors arrived and the bill went up. Sub-agents, advisor agents, adversary agents — each one is another mind reading context and writing analysis. The quality gain is real; so is the cost. Multi-agent review is a luxury good, and I am still working through how to prompt and configure it so the advisors earn their tokens.

The current frontier — for me, and honestly for the field — is both directions: what goes to the model and what comes back. A verbose agent is an expensive agent, and you can instruct against it: tighter output, less narration, answer-shaped answers. I am actively experimenting with this now, and keeping my findings in docs/token-economics-notes.md — a living document I will keep updating.

So this section ends unresolved, on purpose. Consider it the primer's open problem: agent quality scales with the minds you throw at the work; cost scales the same way. Tuning that trade is the craft.

The methodology, distilled — and where the human hours really go

Strip everything to its essentials and my method with agents is three rules:

  1. Build small features. Skeleton first, iterate to mature, one focus at a time.
  2. TDD, always. The tests are the floor; the agent does not get to skip them.
  3. Test comprehensively — and then QA like a customer. The suite proves the code; only the phone proves the product.

And here is the honest accounting of my own time: I spend more time on product definition and on QA with the app in my hand than on any other areas. Thinking through what to build, and then standing where the shop owner will stand — thumb on the screen, checking whether the thing actually works the way a busy garage needs it to. The agent absorbed the middle of the job — the typing, the building, the test-writing. What is left for the human are the two ends: deciding what should exist, and judging whether it is right. Which, twenty-five years in, I have come to believe were always the two parts that mattered most.


Production: Where the Experiment Meets the Real World

The topology (and the honest reason for it)

A launchable product means nothing until it is launched, so with the app ready, I turned to production deployment. That meant two motions: the iOS app into the App Store, and the backend into real infrastructure — Postgres and a Kubernetes cluster in the cloud.

Here I had a head start: I have been building reference software for years, and I already had a platform running in the cloud. The topology will make cost-conscious builders smile: Kubernetes on Azure (AKS), database on Oracle Cloud. Why split across two clouds? Cost — and the credits I hold with each. That is a story all its own; the short version is that production architecture in the real world answers to the finance department as much as the whiteboard, and a solo founder's finance department is his credit balances.

Agents plan the deployment

I asked both agents to produce detailed deployment plans — each for its own side of the product. Both delivered.

Starting with the backend: ubuntu_car_agent did an excellent job. Its plan was genuinely production-grade, step by step — how to secure Postgres, how and where to place the certificates, how to set up the IP allow-list for AKS. Not a hand-wavy "deploy the container" sketch, but the kind of runbook you would want from a careful platform engineer.

Assess first, deform nothing

Then I did something that would make most enterprise security teams inhale sharply: I gave ubuntu_car_agent access to Azure AKS itself.

What it did with that access is the instructive part. It did not charge in and start applying manifests. It ran an assessment first — studied my existing cluster and configuration — and then built its plan and deployment scripts to deploy into my current setup without changing it. It treated the running platform as a constraint to respect, not a canvas to repaint. Anyone who has watched an eager junior engineer "improve" a production cluster on day one will recognize how valuable that instinct is.

The shared cluster, the skeptical colleague, and the diff I photographed

Deploying to AKS carried stakes the rest of the project had not: our cluster is not a sandbox. It runs a platform with several different applications on it — and it is not mine alone; I run it with a colleague — a different colleague from the Copilot story, the one I build our cloud platform with. We were both skeptical about letting an agent loose there, and for a scar-tissue reason worth stating plainly: AI agents like to clean everything and start over. They are very good at it. I have personally watched an agent decide to clean a database and create it fresh — and I was not able to stop it in time. On a shared production cluster, that instinct is not a quirk; it is an outage waiting to happen.

So I was very careful, and the gate got a second layer: I had the agent write out every command it intended to use, and I asked my colleague to review them alongside me. Two humans, full command manifest, before anything touched the cluster.

The deployment configuration was where our doubt concentrated. I asked the agent to create the AKS deployment YAML, and it did — but neither of us was sure it captured all the configuration our platform actually requires. So my colleague did the prudent thing: he created a deployment configuration from our existing, known-good setup and pushed it to a branch.

Which triggered a brief, half-serious negotiation — because up to this point, not one line of this project had been hand-coded, and his YAML was about to end the streak. We talked it over: the no-human-coding agenda versus the shared cluster's safety. Safety won, with a compromise that preserved the experiment's spirit — his file would enter the project as input for the agent, not as code I wrote. He pushed it to the remote repo.

Then I asked ubuntu_car_agent to pull.

What happened next is the moment I would point to if you asked me when I started genuinely trusting these agents. The agent pulled the code and — unprompted — recognized that a new deployment configuration had been checked in. Recognized it was an AKS deployment configuration. Found its own YAML, ran a diff between the two, showed me the differences — and told me, in effect: my file is incomplete; this one has configuration mine is missing.

Nobody asked it to audit itself. It noticed a colleague's work, compared it against its own, and reported its own shortfall with the diff as evidence. I was so floored I took a picture of the terminal and texted it to my colleague. His skepticism took the same hit mine did.

That diff was a turning point. Not because the agent was perfect — its own YAML had been incomplete, which vindicated our caution — but because it demonstrated the thing that actually makes a collaborator trustworthy: it could recognize better work than its own, and say so. The failure mode we feared was an agent that confidently bulldozes; what we got, at the moment it mattered, was an agent that self-corrected in public. Trust is not built by flawlessness. It is built by honest diffs.

The kubectl gate, completed: from two humans to a gating skill

The diff moment bought the agent real trust — and trust, in this workflow, always converts into the same currency: more autonomy, behind better gates.

First came the ground rule, set when my colleague and I reviewed the command manifest: no deletes, no removes — only what is strictly necessary to remove, and nothing beyond it. The agent's commands checked out clean against that rule. The instinct we feared most — the clean-slate reflex — was fenced off explicitly, in writing.

But a rule that lives in one review session dies with it. So I did what by now was the reflex: I turned the gate into a skill. The gating skill works like this: before execution, an advisor agent reviews every command and issues a go/no-go against the standards the skill defines. And the agent asked for something in return that made the gate stronger: a set of standard commands — a vetted vocabulary of deployment operations, pre-agreed, so most of what runs is drawn from known-good patterns rather than composed fresh each time.

Together, that is the deployment gauntlet: every deployment, ubuntu_car_agent goes through the gates — standard commands where possible, advisor review with go/no-go on everything. The first few times, I reviewed on top of all that, human gate atop machine gate. Then, once the gauntlet had proven itself: auto mode. The agent now deploys through its own gates without me watching.

Read the full arc of the kubectl story and you can see the whole primer in miniature: two skeptical humans reviewing every command → an explicit safety rule → the rule codified into a skill → an advisor enforcing it automatically → standard commands narrowing the risk surface → human review atop it all → and finally, the human stepping back. This is the huge change — in trust, and in methodology at once. The gate never went away; it became part of the operating environment. I did not learn to trust the agent unsupervised. I built supervision that does not need me in the room — which is what mature governance has always meant, for human teams and now for agents.

The database: where the agent argued with me — and won

Through test and dev, ubuntu_car_agent had been managing schema changes with Alembic — migrations versioned and tracked in the code itself. When I first saw it, I was surprised yet again at the agent's maturity: it had reached, unprompted, for the right tool for one of the most critical disciplines in any system that stores data.

But production initialization was a decision worth making deliberately, so I asked the agent directly: what is our database strategy? Its answer: it would run the migration versions from the code and create the production database that way — the full Alembic history, replayed from zero.

I pushed back with the pragmatic alternative every DBA has reached for: why not just export the DDL from dev and initialize production from that snapshot? One file, one import, done. The agent initially agreed it was a good idea — and this is where I did something that had become instinct by now: I asked it to get an opinion from an expert database advisor before we committed.

It spun up an advisor sub-agent. The advisor came back with a detailed argument — and sided with ubuntu_car_agent's original plan, against mine. Migration-based initialization keeps production on the exact same versioned path as every other environment: the history stays intact, every future change applies cleanly on top, and the database's state is always explainable by the code. A DDL snapshot works once, then leaves you with a production database whose lineage diverges from your migrations on day one. The argument was convincing — so I conceded, and had the agent write the winning rationale into the database deployment plan itself, so the why travels with the what.

Think about the shape of that exchange: the human proposed the shortcut, the agent deferred, the human insisted on expert review, and the expert overruled the human — with reasons. Collaboration with mature agents runs in both directions, and the review structures I built to catch the agent's mistakes proved just as valuable catching mine.

Initialization by container, then the full check-out

One part the agent could not do — configuring the Postgres instance itself on Oracle Cloud — I handled by hand. Then I asked the agent to initialize the database: it created a container to run the setup through, executing the migrations against production from a clean, controlled environment rather than from whatever state my machine happened to be in. The ephemeral-harness instinct, applied to the most consequential database operation of the project.

Then it deployed the backend to the cluster and ran a comprehensive test pass to confirm all was well. It was — and I will say plainly what I felt watching the whole sequence: it was pretty much unbelievable how good the agents had become. The same system that started with "build me a view for customer entry" was now standing up production infrastructure across two clouds, with versioned migrations, containerized initialization, and its own expert review board.

The App Store: where the agent became the guide and I became the hands

Shipping the backend was an agent-execution story. Shipping the iOS app was the opposite — and the contrast is instructive.

Apple's path to production is famously not straightforward. I read through the Apple documentation and confirmed exactly that. So I did what was now instinct: I asked ios_car_agent to build a plan — and then I worked the plan by asking it questions. How do I do this part? What about that screen? The agent walked me, step by step, through the pieces it could not touch itself: setting up the Apple Developer portal, configuring Xcode, working through the signing and app configuration that live behind Apple's own logins and consoles. The roles reversed completely — the agent supplied the expertise, and I supplied the hands.

Then came the question the whole project had been building toward: how do I get this to my first beta customer? The agent's answer: TestFlight — and here, back inside territory it could reach, it went about configuring everything for it, then built the app and produced the TestFlight release.

That build is the one that landed on my mechanic's phone — the shop I have been driving my cars to for twenty years, now running its front desk on software an agent wrote.

The takeaway: an agent's value does not stop at the boundary of what it can execute. Some walls — Apple's developer portal chief among them — will always require human hands. Behind those walls, the agent shifts from doer to navigator, and a navigator who has read all the documentation and holds your entire project in mind turns a famously painful process into a checklist. Plan → ask → click → repeat.


Where the Time Actually Went

I will be honest that I did not run a stopwatch on every session — the 65 hours accumulated in ten- and fifteen-minute fragments — but the shape of the spend is clear, and the shape is the lesson.

The iOS app took the bulk of the time, and took it up front. No surprise, and no agent will change it: UI/UX takes time. Screens have to feel right, flows have to survive a real thumb in a real garage, and the QA-on-the-phone stage — where I spent more hours than anywhere else — only exists on the frontend. The app was also where the requirements were discovered, which is front-loaded work by nature.

The backend came in around 30% or less. Two reasons, and both are transferable. First, expertise converts to precision, and precision converts to speed: I know how to build a solid backend, so I could give exact instructions — architecture parameters, design parameters, style — and the agent got where we needed to be in quick fashion, without exploratory wandering. Your own strongest domain is where your agents will be fastest, because you prompt it best. Second, the sequencing did quiet work: because the iOS side led, the backend never guessed.

The handoff dividend. For every feature, ios_car_agent iterates first, discovering the requirement the hard way — and by the time the handoff reaches ubuntu_car_agent, the churn has been paid down. The backend agent does not re-iterate; it implements a settled contract. The iOS side's time was not just spent, it was invested, and the backend's 30% is the return. And now that both agents work in parallel — the iOS agent already exploring the next feature while the Ubuntu agent implements the last handoff — the wall-clock math improves again: the pipeline stays full even though each feature still flows frontend-first.

The spend that surprises people: my own hours concentrated at the two ends — product definition before the agents move, and phone QA after they finish. The middle, which used to be the job, is where I now spend the least.

A note on the accounting: the 65 hours is the build — the app, the backend, and getting them to production. The launch surface (naming, brand system, App Store pack, market research) was additional time alongside, done in chat and Cowork sessions rather than the coding workflow. I have kept them separate because they are different kinds of work: the build hours answer "how fast can agents construct a product," while the launch-surface hours answer "how much of the rest of shipping can agents carry." The honest answer to the second question: nearly all of it.


What This Taught Me About Enterprise Guardrails

Part of why I ran this experiment was professional: I design engineering guardrails for a large enterprise, and I needed to understand agentic development from the inside before governing it. Here is what one person, two agents, and one shipped product taught me. Guardrails, remember, are not gates that block — they are checklists that catch. This is my first draft of that checklist for agentic development:

  1. Autonomy is earned per-domain, never granted for life. My agents ran auto mode on application code and still started at "approve every command" the day they touched the production cluster. Climb the ladder fresh in every new domain; the re-climb goes faster each time, but it is never skipped.

  2. Codify the gate, then automate it. Every human review that worked became a skill: PR review standards, deployment command checks, documentation requirements. A rule that lives in one review session dies with it; a rule that lives in a skill is enforced by an advisor on every future occurrence. The human's job migrates from doing the review to authoring what review means.

  3. Advisor and adversary review on everything that matters. Plans get advised. PRs get reviewed through a defined lens. Backends get red-teamed. The second set of eyes that strong human teams get from peer review is available to agents on demand — budget the tokens for it where the stakes justify it.

  4. A prime directive against destruction. Agents like to clean everything and start over, and they are very good at it. No delete, no remove, no recreate-from-scratch — anything destructive requires explicit, itemized human approval. Write it down, put it in the gating skill, and give the advisor authority to say NO-GO.

  5. Least-privilege credentials, always. Scoped access tokens from a secret manager, limited to the one repo or resource, never account passwords, never secrets in prompts or code. The agent gets exactly the access the task requires and nothing more.

  6. Data changes travel as versioned migrations, tested in ephemeral environments. Migrations-only for schema, containerized initialization for production, an ephemeral database harness with maintained golden data for tests. The agent may write every line — the data's lineage stays explainable by the code.

  7. Documents are the system of record. Handoffs, plans, release records, incident reports — committed to repos, not living in chat context. Every settled argument records its rationale. Every incident improves a gate, or it was wasted.

  8. The human holds the two ends. Intent going in — what should exist, in what order. Judgment coming out — QA on the real device, approval at the real gates. Everything between those ends is negotiable; the ends are not.

None of this slowed the project down. That is the finding I would take into any enterprise: process cost approaches zero when agents do the mechanical work, so the old trade-off between speed and governance quietly disappears. You can have both. The organizations that figure this out first will move like I did — 65 hours to a live product — with controls that would pass an audit.


Start Here: Replicating This Setup

If you are starting today, here is the shortest honest path:

  1. Baseline on your own code. One Saturday, your existing codebase, Claude Code. Know which model you are testing. Judge for yourself.
  2. Pick a small, real project with a real user — someone whose problem you already understand deeply. A clean slate, but not a toy.
  3. Start at Rung 1. Claude Code in a terminal. Plan mode. Approve every plan, then every command. Let CLAUDE.md accrete from your corrections. Do not touch auto mode in week one.
  4. Install the floor and the gates on day one. TDD with full coverage as a standing instruction. Gitflow with PR-only promotion. Ask for the ephemeral test-database harness and a golden dataset the moment a database exists.
  5. Work in small features from two-to-three-line prompts. Skeleton first, iterate to mature. QA every feature on the real device before it counts as done.
  6. Grow the agent's memory deliberately: persist to file, then externalize into skills (start from the skills/ folder in this repo), then build a bootstrap so restarts cost nothing.
  7. Earn each rung. Auto mode when the plans have been clean for days. Automated promotions when the gates are skills. Production access last, starting supervised, with a prime directive against destruction and least-privilege tokens.
  8. Keep your hours at the two ends — product thinking and device QA — and let the agents keep the middle.

That is the whole method. It fit in ten-minute fragments of one person's life, and it shipped.


Repository layout

agentic-primer/
├── README.md                    ← this primer
├── skills/                      ← working generic skills, ready to adapt
│   ├── architecture/            ← system-shape rules and design review lens
│   ├── gitflow/                 ← the four-tier branch model and its hard rules
│   ├── documentation/           ← plan, handoff, release, capability, incident templates
│   ├── pr-gate/                 ← advisor-reviewed PR gating (GO / NO-GO)
│   └── deployment-gate/         ← the deployment gauntlet, prime directive included
└── docs/
    └── token-economics-notes.md ← living notes on managing token cost

Drop the skills into your project's .claude/skills/ directory and edit them for your environment. They are generic on purpose — the value is the structure, and the structure is what shipped Curoo.


Curoo is a product of Teeznar Corp. This primer describes my personal workflow and is not affiliated with or endorsed by Anthropic, Apple, GitHub, Atlassian, Microsoft, Oracle, or Slack. Written the same way the app was built: in collaboration with Claude.

About

A practitioner's primer on agentic development: 65 hours, zero hand-written code, one live commercial app. Method, guardrails, and working skills included.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors