Native apps
Shipped iOS work — SwiftUI, widgets, watchOS, StoreKit.
Not a React Native shell. Pencil input, offline databases, App Store review, and the boring release machinery that keeps an app alive after launch day.
Handwriting that becomes text and live sessions that become notes; AI answers grounded in the Rules of Golf, with an offline database when the signal drops.
Case studies
Long-form writeups of how the work actually went.
2026–Endeo
Handwriting on an iPad, turned into searchable text — and a sermon, transcribed while you take notes on it.
2026–RuleCaddie
A golf rules assistant that cites the rule it's answering from, and still answers when the course has no signal.
2026–Veto
Everyone secretly vetoes what they won't tolerate — and the database, not the app, is what keeps those vetoes secret.
2026–Private Reserve
A palate log that has to survive a dark, loud bar — and private club rooms where the verdicts get argued out.
Selected work
- EndeoiPad-first Bible study app. Handwrite notes on any passage with Apple Pencil and have them turned into text; record a teaching session and get it transcribed, linked to your notes, and summarized.Case study →
- RuleCaddieGolf rules answered on the course — AI chat grounded in the official R&A/USGA Rules of Golf, with an offline rules database when there's no signal, plus a watch app and widget.Case study →
- VetoGroup decisions, settled. Everyone secretly vetoes what they won't tolerate and the app reveals what survived — vetoes stay private by design, with the winner computed server-side.Case study →
- Private ReserveA palate log for spirits, with private club rooms where a group logs the pours going around and argues the verdicts.Case study →
Field notes
- Thirty seconds is not a sync budgetApp Intents get about thirty seconds in the background. A real sync, export, or on-device pass often needs more — and LongRunningIntent only keeps running if you keep reporting progress.
- Write the kill criteria before the first commitA prototype without a written kill signal becomes a product by inertia. We decide what would end the idea before the repo exists, and we treat a keep as a rewrite.
- The simulator is not a PencilEndeo's handwriting loop can look fine in Xcode and still fail on glass. We treat simulators as structure checks and keep Pencil, Vision, and session timing on a real iPad gate.
- The engineering time that starts after the feature is finishedReview queues, a platform permission model that changed under us, and OAuth production verification. None of it is in the estimate, all of it is on the calendar.
- Airplane mode is the easy caseTotal disconnection is simple to detect and simple to test. The failures that reach users come from one bar of signal and a request that neither succeeds nor fails.
- Making a golf rules assistant cite rule numbers instead of inventing themA plausible wrong answer about a penalty costs a stroke. RuleCaddie is built so answers are traceable to the actual Rules of Golf, and so it can decline.
- Veto keeps individual vetoes secret in the database, not in the appIf the client has to receive a secret in order to hide it, it isn't secret. Row-level security plus a server-side reveal function is what makes the game actually work.
- We stopped committing the .xcodeproj and the merge conflicts stoppedThe Xcode project file is generated from a manifest and never committed. It costs a build step and a few weeks of learning what Xcode writes behind your back.