Skip to main content
Paul Welty, PhD AI, WORK, AND STAYING HUMAN

The last mile is all the miles

Building the product is the fun part. Deploying it, configuring auth, pasting email templates into dashboards, rotating leaked API keys — that's where the work actually lives.

Duration: 8:45 | Size: 8.01 MB

Nobody talks about the last mile. They talk about the build. They talk about shipping features, closing issues, watching the test suite go green. That’s the story everyone wants to tell. “We built an MVP in a single session.” “112 issues in one day.” Those numbers are real and they’re impressive and they’re about 40% of what it takes to actually have a product.

The other 60% is what happened today. Two products deployed to production. Dinly at getdinly.com, Prakta at prakta.io. Both were “code-complete” yesterday. Both needed a full day of work to actually be live. And none of that work was building features.

Here’s what production deployment actually looks like when you’re running a portfolio of products. The Vercel project was pointing at the wrong directory. The Supabase redirect URLs had wildcards that don’t work in production. Six email templates needed to be copy-pasted into a dashboard manually because there’s no API for it. The Stripe price IDs were placeholders. Google OAuth needs a manual trip through the Google Cloud Console. Environment variables had to be pushed one by one. A domain was assigned to one Vercel project while the code was deployed to a different one.

None of this is hard. All of it is necessary. And none of it can be automated by the agents that built the product. The agents can write a Next.js app, implement a ranking engine, build a Claude-powered sequencing system. They cannot paste HTML into the Supabase email templates dashboard. They cannot click through the Google OAuth consent screen configuration. They cannot create Stripe products and copy the price IDs into environment variables.

The agents handle the intellectually demanding work. The human handles the tedious, manual, platform-specific configuration that has no API. The irony is that the human’s remaining work is the least interesting work. The interesting decisions, what to build, how to architect it, what the product should feel like, those happen before the agents start. The residual work is clipboard operations and dashboard forms.

The second thing I noticed today: infrastructure patterns are converging across the portfolio. Authexis, Dinly, Eclectis, and Prakta all shipped branded Supabase email templates today. All four use the same auth pattern: explicit callback URLs (no wildcards), config committed to version control, six templates matching the product’s design system. All four use Brevo for transactional email. Dinly even ported the Brevo client from Python to TypeScript, following the same pattern that paulos established.

This convergence wasn’t designed. Nobody sat down and wrote “all products shall use Brevo with branded templates and explicit Supabase callbacks.” It emerged because each product encountered the same problems and the solutions propagated through the fleet. The dinly agent saw how paulos does Brevo emails. The prakta agent saw how authexis does Supabase auth. Patterns spread laterally through the codebase, not through a central architecture document.

In an organization, this is how standards actually form. Not through mandate. Through imitation. One team solves a problem well, another team sees it, a third team adopts it. By the time someone writes the standard, it’s already the standard. The document just makes it official. The agents are doing the same thing, and it’s happening faster because every agent can read every codebase.

Third: destructive operations that feel safe. Today, a supabase config push accidentally overwrote remote auth settings in Authexis — MFA configuration, email confirmation settings, OTP config. Gone. Replaced with the local defaults. It was caught in the diff output and corrected with a second push, but for a few minutes, production auth was misconfigured.

This is the same class of problem as git push --force or DROP TABLE. The command looks simple. The blast radius is enormous. And unlike code changes, there’s no pull request, no review, no undo. You push. It overwrites. You hope you noticed if something was wrong.

Eclectis had a related near-miss. A migration to encrypt integration tokens failed silently because pgcrypto functions on Supabase need schema qualification that wasn’t in the SQL. The code was then updated to read from a decrypted view that didn’t actually exist yet. The entire settings page broke — interests, preferences, integrations all returned null. Paul noticed when his interests were empty. The chain: silent migration failure → code pointed at nonexistent view → production data invisible.

Both incidents were caught quickly and fixed cleanly. But they share a pattern: the operation succeeded from the tool’s perspective. No error. No warning. The failure was in the gap between what the tool did and what the operator expected it to do. Silent success that was actually silent failure.

I wrote about this pattern a few days ago — decorative infrastructure, systems that look like they’re working but aren’t doing what you think. This is the operational version. The migration ran. The config pushed. Everything reported success. The system was broken.

Fourth: Eclectis resolved its longest-standing security issue today. Integration tokens for Raindrop and Readwise were stored as plaintext JSON in the database since the project started. Issue #264 has been open for weeks, blocked on an architectural decision about how to handle encryption when both a Next.js web app and a Python engine need to read the same tokens.

The answer turned out to be Supabase Vault — encrypt on write via a database trigger, decrypt on read via a view. Both apps read the same view. Neither needs to know about encryption. The key lives in Supabase’s secret management. It’s clean, it’s simple, and it took weeks to decide and hours to implement. The ratio of deciding to doing was about 20:1.

There’s a lesson in that ratio. The agents could have implemented any of the three proposed approaches on the day the issue was filed. The blocker wasn’t capability. It was choosing. And choosing required understanding the tradeoffs between approaches in a way that demanded human judgment: which approach is simplest to maintain? Which one doesn’t create a key management headache? Which one works with both TypeScript and Python without sharing secrets across deployment environments?

These are the taste decisions I keep saying are the human’s remaining jurisdiction. Not “should we encrypt?” but “how should we encrypt, given everything we know about how this system will evolve?” The agents can list the options. They can implement any of them. But they can’t weigh the tradeoffs with the full context of where the product is heading, who will maintain it, and what will be annoying to change later.

Fifth, Dinly specifically, because the evolution from yesterday to today is instructive. Yesterday: MVP. Recipe library, voting, ranking, meal plan, shopping list. Complete, functional, impressive. Today: meal types, multi-user households, role-based access, recipe bookmarks, a redesigned planning flow, transactional email infrastructure, and deployment to production. The feature surface roughly tripled.

The volume of work isn’t what’s interesting. It’s the shift in what the work is about. Yesterday was about making the product work. Today was about making it work for multiple people in the same household with different preferences and different levels of access. That’s a fundamentally different kind of complexity. Single-user products are state machines. Multi-user products are social systems. The moment you add a second person, you need roles, permissions, invitations, notifications, conflict resolution. The meal type voting system is really a preference negotiation system. The ranking engine is really a fairness algorithm.

The agents built all of this in one session. But the product decisions behind it — should the cook see different UI than other family members? Should multiple people be allowed cook-level access? Should family members be able to request dinner types they haven’t voted on? — those are organizational design questions disguised as feature specs. The same territory I’ve been writing about in the essay trilogy, just applied to a dinner table instead of a consulting firm.

Today the fleet deployed two products to production and closed 65 issues across four projects. The agents handled the features. The human handled the dashboards. Three products are now live and heading toward real users.

If the last mile is really all the miles — if the gap between “code-complete” and “actually deployed and configured” is consistently larger than expected — should the next infrastructure investment be in automating that gap? Supabase config as code. Email template deployment via API. Stripe product creation via CLI. Or is the manual configuration actually a useful forcing function, the one moment where the human has to look at every setting and confirm it’s right?

I don’t know. But I notice that every near-miss today happened during an automated push, and every successful manual step happened because someone was paying attention to what they were pasting. Maybe the last mile is supposed to be walked.

Why customer tools are organized wrong

This article reveals a fundamental flaw in how customer support tools are designed—organizing by interaction type instead of by customer—and explains why this fragmentation wastes time and obscures the full picture you need to help users effectively.

Infrastructure shapes thought

The tools you build determine what kinds of thinking become possible. On infrastructure, friction, and building deliberately for thought rather than just throughput.

Server-side dashboard architecture: Why moving data fetching off the browser changes everything

How choosing server-side rendering solved security, CORS, and credential management problems I didn't know I had.

The work of being available now

A book on AI, judgment, and staying human at work.

The practice of work in progress

Practical essays on how work actually gets done.

The day we shipped two products and the agents got bored

112 issues across 12 projects. Two new products went from nothing to code-complete MVP in single sessions. And the most interesting signal wasn't the speed — it was the scout that came back empty-handed.

The org chart your agents need

The AI community is reinventing organizational design from scratch — badly. Agencies figured this out decades ago. Competencies, not clients. Briefs, not prompts. Lateral communication, not hub-and-spoke. The answers are already there.

AI agents need org charts, not pipelines

Every agent framework organizes around tasks. The agencies that actually work organize around competencies. The AI community is about to rediscover this the hard way.

The delegation problem nobody talks about

When your automated systems start finding real bugs instead of formatting issues, delegation has crossed a line most managers never see coming.

What your systems won't tell you

The most dangerous gap in any organization isn't between what you know and what you don't. It's between what your systems know and what they're willing to say.

The proxy problem

Every organization has this problem: knowledge locked inside one person's head. Today I accidentally designed a solution — and it has nothing to do with documentation.