Platforms
Products with real users and a roadmap past launch.
Web app, mobile app, and the services behind both — accounts, payments, field workflows, and the admin surface that keeps it all honest.
In practiceBuilderHelp
Construction project management — a Next.js dashboard, an Expo field app, Stripe and ACH, and OCR that reads supplier invoices.
Case studies
Long-form writeups of how the work actually went.
Selected work
- BuilderHelpAI construction project management — invoices, change orders, subcontractor payments, RFIs, scheduling and budgets across a web dashboard, an owner portal, and a field-crew mobile app on one source of truth.Case study →
- Provale CupCommerce and marketing site for an FDA-registered metered drinking cup — Shopify checkout, clinician resource library, and editor-owned content throughout.Case study →
Field notes
- A tools/list cache is not a sessionMCP’s 2026-07-28 core is stateless, and tools/list now carries ttlMs. Caching the catalog is not the same as keeping a connection-scoped capability map — invalidate on list_changed, and put real state in tool arguments.
- A reprint is not a voidWhen a florist ticket is already on the bench, reprint means lost paper. Void means the instructions changed. Mixing them prints a second arrangement from stale truth.
- A signature window is not a retry windowHMAC timestamp skew stops captured replays. Provider retries keep coming for hours or days. Dedup TTL has to outlive the longer clock — not the five-minute one.
- A restock is not an inspectionApproving a return and ticking restock puts units back on the shelf before anyone opens the box. Disposition belongs after a real look — especially on partials.
- Shipping under a flag is not finishing the flagA release flag that stays green forever is still unfinished work. Owner, type, and a removal date belong in the same PR that adds the branch.
- A gift message is not an order noteCheckout can collect a card message in one field. Stuffing it into the freeform order note is how it collides with staff updates, delivery instructions, and the ticket on the bench.
- A green migrate is not a rehearsalApplying a migration to an empty database proves the SQL parses. It does not prove the lock, the backfill, or the rollback will survive production shape.
- A delivery window is not a shipping estimateCarrier ETAs are ranges you hope for. A florist's morning window is a capacity commitment — and it has to survive checkout, the order record, and the ticket on the bench.

