Writing

Notes from two decades of platforms and teams.

Engineering leadership, integrations at scale, and what a fractional CTO actually does. New posts roughly twice a month — also in RSS.

September 1, 2026

Remote MCP on Rails: everything that broke

A real remote MCP server on Rails needs OAuth 2.1, three RFCs, and a healthy distrust of defaults. The failures were in Doorkeeper's silent defaults, the MCP gem's transport, and a generated fix that was stricter than the spec it implemented.

August 18, 2026

The Assistant That Couldn't Say Hello: Building a Grounded RAG Menu Chat for Spree Commerce

spree_menu_chat is a read-only RAG assistant grounded in a Spree store's real, synced menu and policies — Gemini, Voyage embeddings, and pgvector, with the read-only guardrail enforced structurally, not just prompted. A \r\n-vs-\n parsing bug silently broke every streamed answer behind a fully green spec suite, and even after that was fixed, the assistant still couldn't handle a plain "hi."

August 17, 2026

The Subscriber That Was Never Subscribed: Adding DoorDash Delivery to a Spree Commerce Platform

spree_doordash adds live-quoted, auto-dispatched DoorDash Drive delivery to the Spree + Square restaurant platform. Two real bugs — a phone number format DoorDash silently rejects, and an event subscriber that was never actually wired up — only surfaced once a real storefront checkout was driven through, not the 87-example spec suite that kept passing regardless.

August 14, 2026

Why I Open-Sourced a Square Integration for Spree Commerce

spree_square started as one restaurant's Square integration. Here's why it made sense to release it as open source, what it actually took to ship it responsibly — a full commit-history security review, closing test-coverage gaps first — and the bug the first real release caught within days.

August 13, 2026

The Cash Register Is the Database: Building a Restaurant Ordering Platform on Spree + Square

Why Square — not a second admin UI — is the source of truth for the menu in a Spree Commerce restaurant platform: the architecture that fell out of that call, a payment trick that never touches Square's card APIs, and two webhook quirks that only showed up against a live sandbox.

August 12, 2026

Shipping WhatsApp's Native Catalog + Cart: A Field Guide to the Undocumented Gotchas

What it actually takes to get a Rails app talking to WhatsApp's Cloud API with real Catalog and Cart support — eight undocumented walls, in the order I hit them, and the checklist that would have saved me a day.

August 10, 2026

I'm Learning MCP by Building a Server Claude Can Actually Log Into

A hands-on log of building an MCP server against a real Spree Commerce store seeded with 100,000 real historical orders — a silent data-loss bug from a fast insert path, a join fan-out that made my own analytics lie by 42x, and standing up full spec-compliant OAuth 2.1 instead of skipping auth for a quick test.

August 7, 2026

I'm Learning Voice AI by Building an AI Receptionist for a Restaurant

A hands-on log of building a voice AI phone agent for restaurant ordering with no prior voice-AI background — the architecture bet that paid off, a toolchain bug with zero AI glamour, and the moment a confidently wrong AI got caught by a boring safeguard.

August 3, 2026

The API Design Checklist I Wish I Had at Integration #1

10 lessons on idempotency, webhooks, auth, and observability from 200+ production API integrations — and the checklist that came out of learning them the hard way.

July 18, 2026

Now taking fractional CTO and advisory engagements

After two decades building platforms and teams — WeWork's hyper-growth years, then eight years scaling a restaurant-integrations organization to 20,000+ live locations — I'm opening a small fractional CTO and advisory practice.