Build log

Thirty years shipping product.
Ten weeks shipping code.

One operating model, run at two scales. At BS&A I designed an AI-native software development lifecycle in partnership with my CTO and took AI tool adoption across seven engineering teams from 19% to 58% in three months — a 49% velocity gain on a large, aging brownfield codebase. This page is the same model at the other scale: one person, end to end, alone — to find out whether it holds when there’s no organization behind it.

I’ve spent thirty years in B2B enterprise SaaS building products and shipping features — hundreds of products, thousands of features, always in partnership with engineering, and always bounded by engineering capacity, velocity, and priorities. The constraint was never judgment. It was capacity — and that has been true of every product leader alive.

That constraint is gone. I can find a market problem, design the solution, build it, put it in front of real users, and iterate — in days. The numbers below come from my actual Jira, Confluence, GitHub and Vercel accounts, updated automatically.

I have never been more excited about this work.

An AI-native SDLC, run by one person.

Spec
Confluence. Problem, data model, reversible decision.
Human gate
Prototype
Claude Design. High-fidelity, cheap, in front of users before code.
Human gate
Backlog
Jira epic and linked stories, written by both of us.
Shared
Build / Test
Claude Code. Stories in parallel; tests written and run with every branch.
Automated
Review
Pull request. Nothing merges without my read.
Human gate
Production
Merge triggers the build; Vercel deploys.
Automated

I didn’t abandon the discipline when the constraint lifted. I applied it.

Every feature starts as a spec in Confluence — the problem, the data model, the architecture decision and why it’s reversible. The spec becomes a high-fidelity Claude Design prototype — quick and cheap enough to put in front of real users and validate before any code is written — then an epic and linked stories in Jira. Claude Code works stories in parallel, each on its own branch. Merges trigger builds and deploy to production through Vercel, continuously.

I review the pull request.

Same stack an enterprise product org runs. Same gates. 69 specs, 491 backlog items, 200 pull requests — every one of them reviewed by me.

What’s new is that Claude writes to Jira and Confluence directly. The backlog isn’t documentation I keep up after the fact; it’s the live system of record my AI collaborator and I both operate from. Ideation, research and architecture happen in conversation. Design prototypes come out of Claude Design. Code lands as a branch and a pull request. Nothing skips the spec, and nothing merges without review.

Those are product decisions. They’re the same ones I’ve been making for thirty years. What changed is that I no longer wait in line to see them built.

Products I’m building.

TopHand — the farm’s most knowledgeable hand.

tophand.ag · in active development · first customer: GoatLife Farm, Michigan

Farm management software has a crowded middle: everyone sells record-keeping, and record-keeping is a chore farmers resent paying for. TopHand sells something no competitor pairs — a condition-gated timing engine that tells a farmer when to act, bridged to a coordination board that handles who does it.

The wedge is money, not time. Cutting hay in the right window is worth $70–100 per ton in grade spread; every day of delay past peak costs roughly $9 per acre in quality loss. A tool that saves one cutting pays for itself for years. That’s a different sales conversation than “keep better records.”

When I found that my data model had quietly assumed hay was the only crop a farm grows, that became a Confluence spec, a nine-story epic, and a shipped migration — seven days from problem to production, with the whole thread traceable from the decision to the commit.

My family runs a working dairy-goat farm in Michigan. It’s the first tenant, the demo environment, and the reason I know which problems are real.

TopHand exists to prove the operating model, not to raise capital. It’s a live product with real users because that’s the only honest way to test whether the method works.

Visit tophand.ag
  • Installable PWA Next.js, React, TypeScript and Tailwind, with a Serwist service worker so it keeps working in a field with no signal.
  • Multi-tenant from the ground up Account → farm scoping on every query, Postgres row-level security behind it as defence in depth, and a registry that fails the build if a new table doesn’t declare its tenancy.
  • Plans, add-ons and feature gating A capability-key registry resolving entitlements per account.
  • Satellite field mapping Mapbox GL with draw tools, Turf for automatic acreage, and field boundaries parsed straight from deed text by AI.
  • AI enrichment the farmer confirms Anthropic’s Claude API fills in researchable values as editable suggestions — never auto-committed, because a wrong estimate silently accepted is worse than a blank field.
  • Condition-gated timing engine Weather and crop state reconciled into a cutting-window recommendation — the difference between recording the past and acting on the present.
  • Notifications that land somewhere Twilio SMS (consent-gated, toll-free verified) and Resend transactional email, each deep-linked to the record that triggered it.
  • Hands-free in the field ElevenLabs text-to-speech reads recommendations aloud for a farmer whose hands are full.
  • Serverless Postgres on Neon With photo storage on Vercel Blob.
  • 1,078 tests Across 89 files, run on every branch.
TopHand’s cut recommendation: three gates, a quality target and the reasoning behind the call
TopHand — the call on a demo field. Three gates, a quality target in RFV, and the reasoning out loud: cut Thursday, or lose roughly four RFV points a day waiting.

Register · TopHand

Live from Jira, Confluence, GitHub and Vercel · updated 12:42 AM ET

github.com/productdetroit
Days building
71Since 25 June 2026, day one for TopHand.
Work items delivered
118Stories and tasks closed Done in Jira, in production.
Median idea → live
11hoursMedian created → resolved, all issue types.
Spec → shipped
6daysMedian epic lifetime: Confluence spec to production.
Specs written
23Problem, data model, architecture decision — before code.
Epics complete
9/26Done of created. The rest are sequenced, not stalled.
Pull requests merged
141
Production deploys
168
Lines of code
79,022
Reviewed by me
100%
Last shipped
Repo setup preflight yesterday

MotorAdvisor — the question becomes a repair order.

motoradvisor.app · in active development · independent repair shops

A service writer standing at a counter has one question — what’s wrong with this car, what will it cost, and should we even do the work?— and answering it today means crossing four systems and a phone call. MotorAdvisor turns that question into a priced, bookable, payable repair order, in the conversation where it was asked.

The bet isn’t that shops want another database. It’s that the repair decision is a single continuous act— diagnose, price, decide, approve, pay — and that every product in this market breaks it into pieces and hands the seams to the shop.

The part nobody does: it gates the repair against the car. A vehicle valuation sits alongside the estimate, so a $3,400 repair on a car worth $2,900 is a conversation the system starts rather than one the writer has to remember to have. That verdict is advisor-facing by default — telling a customer their car isn’t worth fixing is the shop’s call to make, in the shop’s voice.

Same operating model as TopHand, at a different scale: specs first, epics and stories, one story per pull request, every merge reviewed. Where it differs is the shape of the risk — two licensed upstream data providers that must stay strictly separate in the code, enforced as build rules with negative controls rather than as conventions anyone has to remember.

Visit motoradvisor.app
  • Responsive web app Next.js, React and TypeScript end to end — no second language anywhere in the stack.
  • Conversational AI layer Anthropic’s Claude API running an agentic tool loop over task-shaped tools, so the model asks a question rather than walking a catalogue.
  • AI model gateway Model choice is deterministic app code — a tested router sends mechanical turns to a cheaper model — then the Vercel AI Gateway picks the best-cost provider serving that model, with automatic failover. The app decides what; the gateway decides who.
  • Custom remote MCP server Stateless streamable HTTP with OAuth 2.1, PKCE and dynamic client registration — an external agent gets the same tools the app uses.
  • Developer docs that stay current motoradvisor.app/dev rebuilds automatically as the platform changes, so a builder wiring up the MCP server is always reading live documentation, not a stale wiki.
  • Two licensed data-as-a-service integrations Repair data and vehicle valuation, HMAC-signed, and deliberately blind to each other in code so one vendor’s failure modes never reach the other.
  • Multi-tenant by shop Each shop carries its own labor, tax and supplies rates, its own branding, and its own connected payment account.
  • Integrated payments Stripe Connect: the shop is merchant of record, a platform fee rides each invoice, and the customer pays on a shop-branded page via Stripe Elements.
  • Editorial Studio A third deployed surface that extracts PDFs into structured records with per-field provenance.
  • Documents that leave the building Printable and emailable PDF quotes, and QR-coded pay links.
  • Architecture enforced by the build Six framework-free packages whose module boundaries are policed by dependency-cruiser with negative controls — a rule that isn’t proven to fail when violated isn’t a rule.
  • 916 tests, offline fixture replay The whole suite runs with no network at all.
A MotorAdvisor work order: the conversation on the right, priced diagnostics and a repair-or-replace verdict on the left
MotorAdvisor — one work order in the demo shop. The question is asked on the right and lands as priced, approved diagnostics on the left — then the repair is weighed against what the car is actually worth.

Register · MotorAdvisor

Live from Jira, Confluence, GitHub and Vercel · updated 12:42 AM ET

github.com/productdetroit
Days building
26Since 9 August 2026, day one for MotorAdvisor.
Work items delivered
147Stories and tasks closed Done in Jira, in production.
Median idea → live
5daysMedian created → resolved, all issue types.
Spec → shipped
7daysMedian epic lifetime: Confluence spec to production.
Specs written
46Problem, data model, architecture decision — before code.
Epics complete
10/23Done of created. The rest are sequenced, not stalled.

On the medians: Backlog reconciled 17 Aug 2026; these medians measure that cleanup, not cycle time. Honest from work completed after that date.

Pull requests merged
59
Production deploys
324
Lines of code
145,682
Reviewed by me
100%
Last shipped
chore: remove temporary Jira credential diagnostic 7 days ago

Across the portfolio

2products, one operating model. Totals only — cycle times live on each product’s register, where they describe a single thing.

Specs written
69
Work items delivered
265
Pull requests merged
200
Production deploys
492
Epics complete
19/49

What the build is teaching me.

Written by me, dated, and occasionally a correction of something I got wrong first.

What a donated VIC-20 in 1981 taught me about AI in 2026

Almost nobody is fluent in this yet — that's not a gap to be embarrassed about, it's just what the front edge of a technology feels like, and it doesn't last long.

I grew up less than a mile from the Boys & Girls Club in Royal Oak, Michigan. I started going at six and spent most of my childhood there. The club shaped me. The coaches, the programs, the structure, the simple fact of somewhere to be. I owe a lot of who I am to that incredible organization and the adults in it.

A couple of years after I started, a Commodore VIC-20 showed up. I never knew where it came from. I’ve always assumed it was a board member who bought it out of pocket and donated it, hoping a machine like that might do something good for the kids who came through the door. It ran about $300 at the time, close to a thousand dollars now. The staff set it up in the game room, left it turned on, and let anyone who was curious sit down at it.

Almost no one in the country was computer literate then. Not the staff, not our parents, not our teachers. There was no one to teach us because there was barely anyone who knew. What the club had was the instinct to put the machine where kids could reach it, and the patience to let us make a mess of it.

So a handful of us taught ourselves, entirely by trial and error, which at that age is indistinguishable from play. Ten lines of BASIC to make your name scroll down the screen forever. Then we got ambitious and built a choose-your-own-adventure game. Pure text, if/then logic, maybe forty lines. I remember it feeling impossibly sophisticated. It felt like magic, and more than that, it felt like something I had made. I was eight years old and I had just become a builder.

I think about that room constantly right now.

I’ve spent thirty years in product. I was a political science major. I have no computer science background and never wrote production code in my career. And for the last stretch I’ve been building real software with Claude Code, in English, at a speed that would have been a fantasy two years ago.

A lot of what comes back at me is still a foreign language. I don’t always know what I’m looking at. But I’m learning exactly the way I learned on that VIC-20. Try it, break it, read the error, try it again. I have not enjoyed work this much in a very long time.

Almost nobody is fluent in this yet. That’s not a gap to be embarrassed about, it’s just what the front edge of a technology feels like, and it doesn’t last long.

I don’t know who bought that VIC-20. They couldn’t have known what it would turn into, and they almost certainly never found out. They just thought it might be good for some kids in Royal Oak.

If you’re waiting until you understand it before you start, you have it backwards. I never understood any of it at first. I just kept typing.

What one AI conversation actually costs, and what it took to cut it 76%

An unmeasured transaction cost $0.715. It ships today at $0.168, with every hard quality gate green — and the optimization I expected to save the most saved nothing.

Every AI feature carries a marginal cost on every single interaction. It scales with conversation shape rather than user count, it is dominated by what you send rather than what the model says back, and it is invisible until you instrument it. I deferred measuring MotorAdvisor’s until the product had enough shape to be worth optimizing. This is what I found.

The unit. One complete demo transaction, four user turns: symptom, book a leak inspection ($90), add an HVAC diagnosis ($180total), quote a compressor. Every figure below is the API’s own usage accounting, captured in the production agent loop against live data, 18–19 August 2026. Pricing at list.

Baseline: $0.715, and no caching at all

TurnModel callsInput tokensOutput tokensCost
1 — symptom to diagnostic menu217,068496$0.098
2 — book leak inspection331,194520$0.169
3 — book HVAC diagnosis332,150720$0.179
4 — compressor quote449,524885$0.270
Total12129,9362,621$0.715

Four user questions became twelve model calls, because an agentic loop re-sends its growing context on every internal step. Input was 98% of tokens and 91% of cost; all output together came to $0.066. Roughly 6,900 tokens of identical tool schemas and system prompt were re-billed at full price twelve times, about 83k of the 130k input tokens. cache_read_input_tokens was zero on every call.

Optimization 1 — prompt caching: $0.270, −62%

Two cache_controlbreakpoints per request: one on the system block, which caches tools plus system prompt, and one on the final message’s last content block, so each loop iteration and each following turn reads the conversation from cache. About 30 lines behind a pure request-builder, plus six tests.

Full-price input tokens fell from 129,936 to 20. Normalizing for path variance between runs, the like-for-like reduction is 52%. Responses ran roughly 27% faster as a side effect. No quality trade of any kind.

Optimization 2 — AI Gateway: $0.265, flat

Routing the same calls through an AI Gateway saved nothing, and it should not have. Cost-based provider routing ranks providers serving the same model, and Anthropic-family providers price Claude within a rounding error of each other. Cross-provider price arbitrage is real for open-weight models and close to nil for frontier proprietary ones.

What the gateway does buy is a failover surface, per-app spend tracing, and an answer to what happens during a provider outage. It runs with the app’s own provider key on each request, so inference bills the existing account at zero markup. Prompt caching passed through byte-identically. One sample showed a latency premium; a single sample is an anecdote, not a finding.

I am documenting a flat result because the alternative is crediting infrastructure with savings it did not produce.

Optimization 3 — model-tier routing, quality-gated: $0.168 shipped

Switching to a cheaper model is the most common cost lever and the least examined one. “It scores 95% of the frontier model on a public benchmark” is a hope, not a decision. So the gate came first.

Hard gates, binary, on structured tool traffic, any failure disqualifying: turn 1 yields the two-inspection menu with no total; turn 2 maps the booking phrase to exactly one application id and returns $90.00; turn 3 carries two ids and returns $180.00; turn 4 re-calls in quote stage and surfaces compressor candidates. The model never computes money — the upstream data service does — so accuracy for a model swap means does the cheaper model drive the tools identically.

Soft gates covered style. Latency was measured as medians and ranges across five runs per arm, with time-to-first-token tracked separately from wall time.

A: all Opus 5B: hybridC: all Sonnet 5
Hard gates (5 checks × 5 runs)25/2525/2525/25
Cost per transaction, median$0.299$0.170$0.146
Range$0.222–0.303$0.164–0.238$0.133–0.150
Wall time, median72.9s61.2s61.5s
Style: question-form endings5/51/50/5

Time to first token was statistically identical: Opus 2,274ms median (n=32) against Sonnet 2,262ms (n=37). Wall time improved about 16%. Every money-critical behavior held in every arm, including the hybrid’s $90 and $180 bookings, which were Sonnet turns.

The gate caught exactly one real deviation, and it was style: Sonnet ended booking turns with an invitation rather than the specified next-step question. One added prompt line fixed it. Re-gating through the shipped code across three runs: hard gates 3/3, router placement exact in every run, question-form endings recovered to 8 of 9 booking-adjacent turns from 2 of 10 before the fix. One residual slip in nine, reported rather than rounded away. Median cost $0.168.

What shipped: a deterministic modelForTurn() router in application code. Three mechanical booking-message forms route to Sonnet 5, everything else to Opus 5. Unit-tested, environment-overridable, one model per turn, because a mid-turn switch would thrash the model-scoped cache.

What did not ship:all-Sonnet routing, worth another 20%, until the gate covers ambiguous vehicles, tool-error recovery, and off-script questions — where the more capable model is likeliest to earn its premium. The savings envelope is known. The license to take it is not yet earned.

Where the model decision actually lives

The most useful thing I learned has nothing to do with cost. Nothing in the stack picks your model for you. The API runs whatever you name. The gateway selects a provider for the model you already named and can substitute a pre-authorized fallback, but only on failure — never because a turn looked easy or expensive. Per-turn model choice is product logic. It belongs in application code where it is deterministic, testable, and visible in a trace.

Cumulative

$0.715 $0.168 median, a 76% reduction, with zero measured quality given up because every step was gated. Against a $180diagnostic ticket that is under 0.1% of ticket value. Each loop — instrument, measure, change one variable, re-measure, document — took an afternoon or less.

What this buys a hiring company.

For a PE-backed SaaS company, this experiment is diligence you can hire:

I can assess vendor and internal AI delivery claims against a model I’ve run myself, at both scales — I know what the demos leave out and what the pilot numbers actually mean.

When I propose an AI operating model to an engineering organization, it isn’t theory. I’ve driven adoption across seven teams with a CTO partner and run the whole lifecycle alone — credibility with engineering that a mandate can’t buy.

And I know where it breaks: which gates have to stay human, where a thin spec turns into rework, and what review has to catch that automation never will.

Open to senior product roles in B2B enterprise SaaS.

Thirty years of judgment, now with no queue in front of it.

joe@productdetroit.com