

You're not hiring a process. You're hiring the judgment that runs it. Here's how an engagement actually goes.
The stated problem and the real problem are often different. "We need microservices" is usually "our deploys are scary and our team stepped on each other twice last month." I spend the first conversations pulling the real constraint into the open — because the whole engagement is only as good as the problem it's aimed at.
Then I tell you the smallest thing that solves it. Sometimes that's a distributed, event-driven platform. Often it's one well-layered API and a boring database. I'll make the case for whichever it is, and I'll name what I'm choosing not to build and why. Everything I decline to build is declined on purpose.
I don't hand over a two-thousand-line diff and hope you can review it. Work ships in small, ordered layers — contracts, then data, then the rules that are the product, then the wiring. Each layer is small enough to actually review. Errors stay local. Naming gets fixed cheaply, at the start, instead of expensively, at the end.
The cheapest place to catch a mistake is a paragraph, before any code exists. So we argue with the plan first — in prose. It feels slow for about a day. Then it's dramatically faster, because nobody's spelunking through a giant generated diff looking for the line that's lying to them.
When AI-assisted work is involved, the prompts are committed alongside the code — a versioned record of why the system looks the way it does. Six months from now, when someone asks why a query pointedly ignores a filter, the answer is in a file with a commit history, not in my head. When I roll off, the reasoning stays.
Weekly cadence, your approval at every step, no surprises — that part's table stakes, and yes, I do it. The part that's worth paying for is the four decisions above.
Two engagements, two very different shapes — a production reliability rescue and a right-sized proof of concept. Pick one.
Reliability hardening for a 21-function, event-driven Azure platform — without the rewrite nobody needed. Here's the same judgment above, applied to a real engagement.
A choreographed, event-driven backend — 21 Azure Functions reacting to Service Bus messages — had grown one handler at a time. Three different ways of acknowledging a message meant the profile-creation path could silently drop a new registration.
A reverse-engineered architecture baseline, one standardized message-settlement pattern rolled across every function, an at-least-once redesign of the create path, poison-message dead-lettering by default, and consistency observability for the CQRS read models.
Dropped registrations closed at the source, uniform settlement across all 21 functions, a bounded and observable read-model divergence window, and a versioned architecture baseline the team actually owns — with no new Azure spend.
A new member signed up. The platform said "got it" to the message broker — and then the call that was supposed to actually create the profile failed. Because the message had already been marked complete, nobody retried it. Nobody dead-lettered it. Nobody knew. The signup didn't throw an error. It didn't fire an alert. It simply never happened.
That's the kind of bug that never shows up in a demo. It compiles. It passes tests. It works every single time you watch it. It only fails when you aren't looking — which, for a registration path, is most of the time.
When you acknowledge a message is not a coding detail. It's an architectural decision about delivery guarantees, and it has to be made once, on purpose, for the whole system — not twenty-one times, by accident, one function at a time.
One write to the canonical profile document projects into five denormalized read models — username lookup, geo/filter search, birthday lists, newest members, tag search — each partitioned for its own query. A textbook CQRS fan-out.
The create path acknowledges the message before the downstream call succeeds. A failure after that point drops a signup, silently, with no retry and no alert.
Three completion strategies across 21 functions means delivery guarantees you can't reason about, because they're different everywhere you look.
The five projections run independently. A partial failure leaves search and member lists temporarily disagreeing with the source of truth — with no visibility into when, or for how long.
One function dead-letters correctly. The rest either abandon-loop or drop. A poison message is therefore either an infinite retry or a silent loss — never an alert.
This is the point where a certain kind of consultant sells you a rewrite: event sourcing, an orchestration layer, a service mesh to "manage" the functions. The architecture was already right. What the system needed wasn't a new architecture — it needed the one it already had, applied consistently. The most valuable slide in the whole engagement was the one that said don't rewrite this.
At the end of the day, the client got an architectural plan, remediation, and hardened, production-ready code.
Want the whole story? Review the entire case study and the discovery delivery the client actually received.
RecipeForge — an AI content engine for food bloggers, built as a proof of concept to answer a business question cheaply: is one guided flow, seed to scheduled, worth building for real? A $2,100 answer to a five-figure decision.
Prove that a solo food blogger — or a small brand running six content channels — can go from "it's Taco Tuesday on the Grill Master channel" to a photorealistic photo, platform-specific copy for seven networks, and a scheduled post, from a single screen, with a human keeping exactly two decisions.
A working PoC on .NET Aspire and Angular: a guided Content Pipeline that chains a content seed, a photorealistic image (Venice.ai), and social copy (Azure OpenAI), then files the result into a DAM library and a Kanban content board — end to end, in one flow. Right-sized on purpose.
The ~750-line pipeline component wasn't vibe-coded. It was built from a committed, layered SCRUB prompt library — Context → Plan → Execute (seven layers) → Verify — that ships in the repo as an open, reusable artifact. The prompts are the plan, and the plan is public.
A food blogger's actual job, most days, isn't cooking — it's the treadmill after it. One dish becomes a shoot, the shoot becomes a photo, the photo becomes seven captions, and then it has to be filed, tracked, and scheduled. Every day, across every channel. Most tools solve one slice and hand you back to the treadmill for the rest. The cost isn't any single step — it's the seams between them.
The question wasn't "can AI write a caption." It was a business question: is a single guided flow that owns the whole chain — seed to scheduled, no copy-paste, no lost files — worth funding as a real product? That's exactly the question a proof of concept exists to answer. Build the smallest thing that makes the opportunity decidable, before anyone commits a production budget to it.
So I built the boring version on purpose: a guided flow with two places a human has to look, and a prompt library anyone can read. The flashy version — an agent that "just builds your whole content calendar" — demos better and fails in the dark. The boring version is the one a real brand could trust, and the one whose build you can audit line by line, because the plan is committed next to the code.
Two human checkpoints, by design — the seed and the photo prompt. Everywhere else, the machine moves on its own. One dotnet run brings up the API, the Angular app, and an Aspire dashboard. No microservices, no bus, no orchestration layer the workload doesn't have the problem for yet.
Make the model summarize the patterns it must preserve — signals, firstValueFrom bridging, the real response shapes — before it writes a line.
Propose the nine-step state machine, which signals are derived, and where the two checkpoints sit — and confirm it before any TypeScript exists.
Types and signals, then the template in vertical slices, then orchestration, then helpers and styles. Each layer constrains the next until the plausible output and the correct output are nearly the same thing.
Does any transition skip a checkpoint? Do all seven platforms render? Any *ngIf that should be @if, any localStorage, any .subscribe() where orchestration should await? The step that catches you the day you review a diff too fast.
The code shows you what was built. The prompts show you how to build it again — deliberately, reviewably, without the Plausibility Trap. Restrictions are tiered CRITICAL / IMPORTANT / PREFERRED, and every critical one carries its reason, because the reason is what tells the model why the plausible default is wrong for this domain. A prompt is a specification, and specifications deserve engineering.
A proof of concept that names its own next steps — and its own cost — is a proof of concept you can actually make a business decision about.
The path to production is written down, not hand-waved. Production hardening is a separate, scoped decision — one you can now make with a working loop in front of you instead of a slide deck.
The whole point of a proof of concept is to buy down risk cheaply. Twenty-eight architect hours turned an expensive, ambiguous "should we build this?" into a working loop you can click through — before a single production dollar is committed.
| Phase | Allocation | Notes |
|---|---|---|
| Context + Plan | 4h @ $75/h | Load references, summarize patterns, agree the flow |
| Execute · 7 layers | 8h @ $75/h | Types → template → methods → styles, layer by layer |
| Integrate AI + DAM + board | 8h @ $75/h | Wire OpenAI, Venice, DAM library, Kanban board |
| Verify + polish | 8h @ $75/h | PASS/FAIL checklist, styles, Aspire wiring |
| Total | 28h · $2,100 | A $2,100 answer to a five-figure build decision |
Plus consumption: Azure OpenAI + Venice.ai per-generation, Azure SQL + Blob (dev tier). Illustrative rates; production hardening (auth, resilience, CI/CD) is a separate scope.
Push on the concept, the architecture, and the prompt library — the whole build is public. Here's the full case study and the proof-of-concept deck.