Multi-platform product · Claude throughout
Vega — an AI fitness platform
A fitness platform built for friends and family: React web app, native SwiftUI iOS app, Android client, Apple Watch workout scheduling, and home-screen widgets — all thin fronts over one PHP API and MySQL database. Claude is integrated across roughly nineteen surfaces: a streaming coach that queries Apple Health through client-executed tool use, post-session debriefs, multi-week training plan generation, and vision-based schedule import.
- 4 clients · 1 backend
- Swift · Kotlin · React · PHP
- ~19 AI surfaces
- SSE streaming proxy
- HealthKit + WorkoutKit
- TestFlight via Xcode Cloud
One backend, four clients, and the mirror rule
Four clients in three languages can't share a library, but some logic has to live on every client — readiness scoring constants, run-split labelling, the debrief instructions. The answer is a documented mirror rule: every deliberately ported piece of code names its twin on the other platform, and touching one side means finding and changing the other. Convention as architecture — the cheapest consistency mechanism that survives a solo maintainer, chosen over codegen or a shared spec because the mirrored surface is small and the docs live next to the code.
Tiered model routing
Every call defaults to Haiku. Plan generation — thousands of tokens of structured output — routes to Sonnet; screenshot import uses vision-capable Sonnet; chat exposes explicit Haiku/Sonnet/Opus escalation that resets after every message, with live token and cost readouts under each reply, so spending more is always a visible choice. Routing decisions are corrected by evidence: when Haiku kept confusing similar product model names in one feature, that single surface moved up a tier — and same-input calls were deduplicated so the sampled answer stays consistent.
Centrally governed prompts
Every AI surface registers in one prompt registry: a default instruction, a per-user override, and data toggles controlling exactly which context blocks get injected — goals, schedule, training history, plan progress. The settings UI renders governance cards automatically from the registry, and a preview button shows the exact assembled prompt the model will see. Domain knowledge ships as token-efficient JSON specs — running, strength, and cycling methodology — rather than prose, so one knowledge base serves every generator.
Prompt caching, and its limitation
Chat resends its large system block every turn, so it's marked for ephemeral prompt caching. Per-message cost accounting made the limitation visible: the system prompt is assembled from live user data, so any change to the injected context invalidates the cached prefix, and infrequent surfaces fall outside the cache window entirely. The wins are real inside an active conversation and near zero elsewhere — the restructure, a stable cacheable core with volatile context trailing it, is queued behind measurement in the eval platform.
Consumer web + native iOS · AI with guardrails
Lyra — a language platform that teaches
A language-learning platform that actually teaches — grammar, conjugation, and vocabulary in pedagogical order with real spaced repetition — rather than testing random words. Six languages are live (French, Spanish, Italian, Portuguese, Welsh, Czech) on a React web app and a native SwiftUI iOS companion sharing one API. The course is drawn as a galaxy: CEFR level = galaxy, unit = star, lesson = planet.
- 6 languages live
- 90+ units · ~3,000 vocab items
- FSRS-4.5 scheduler
- 20 exercise formats
- Azure + Whisper speech
- Web + native iOS
Scheduling is the product
FSRS-4.5 spaced repetition runs server-side only: clients submit graded results, never schedules. Ratings come from grading, not self-report — wrong, almost, correct, and too-easy map to scheduler ratings — and grammar and conjugation concepts are first-class schedulable items alongside vocabulary. Deterministic grading runs client-side for instant feedback and is mirrored server-side as the authority; AI grading is a capped fallback for open answers only, never for choice formats.
Content is a build pipeline
Courses are authored as unit JSON through a validated pipeline: generated authoring briefs, machine-checked invariants (vocabulary introduced before it's used, cross-unit dedupe, per-format payload schemas), and idempotent publishing that regenerates only changed rows by content hash — a full-language publish fell from twenty minutes to under thirty seconds on shared hosting. AI-generated exercises fill demand into a shared, hash-deduped cache, validated before serving and constrained to vocabulary already taught; in-app flag reports feed a triage loop back into the source content.
AI with guardrails
Prompts are composed server-side and every provider call passes one instrumented choke point logging tokens, cost, latency, and errors. The floating tutor receives the learner's screen context as a server-resolved sentence — never client free text — closing an obvious injection surface. Speech uses two providers with defined degrade paths: Azure pronunciation assessment scores read-aloud drills, Whisper transcribes free speech for debriefs; audio is consent-gated, usage-capped, and discarded after scoring.
Two clients, one contract
The iOS app is a genuine second client, not a wrapper: ported components carry named Swift twins, and every API-contract change on the web side requires a parity-log entry before it lands. The mirror rule from the fitness platform, formalised into process.
Developer tooling · LLM-as-judge, validated
Eval platform — closing the loop
Two products and roughly twenty AI features meant every prompt change was a guess: most outputs were one-shot streams, invisible after the fact. The eval platform closes that loop, following the Hamel Husain / Shreya Shankar methodology — capture real traces, find the failure modes by hand, then make LLM judges prove they agree with a human before trusting them to score at scale.
- Next.js App Router + TypeScript
- Neon Postgres + Drizzle
- Vercel
- One trace schema, 3 apps
- Full prompt + completion capture
- Cohen's κ judge validation
Capture without touching the product
Apps push traces by fire-and-forget HTTP, flushed after the user already has their response. App-generated IDs make ingestion idempotent, malformed payloads are quarantined for inspection rather than dropped, and images are replaced by content hashes before leaving the app. The shared-hosting backend can't be reached from outside, so data flows strictly one way — and when the host turned out to lack the PHP primitive for post-response work, the fallback was a bounded flush with an accepted, measured ~1% loss rather than a redesign.
The eval loop
A keyboard-driven inbox for reviewing real traces; free-text open coding; axial coding into a small failure taxonomy — AI-suggested, human-created; then one LLM judge per failure mode. Judges are versioned append-only, return structured verdicts, and are validated against human labels with a confusion matrix, true-positive and true-negative rates, and Cohen's κ, disagreements listed first. A judge that doesn't agree with the human doesn't get to score.
Operating under real constraints
Scheduled scoring batches under the serverless 60-second ceiling and resumes where it stopped; an explicit error verdict keeps failed calls from re-queueing a run forever; every run carries its own cost accounting, with model prices verified against the live price list rather than memory.
Status, plainly
Ingestion and the trace viewer are live in production, with every fitness-platform AI surface instrumented across web, iOS, and Android. Annotation, the taxonomy tooling, and the judge stack are built and green and deploying now — the first validated judge runs over production traces are the current milestone.
ServiceNow internal tooling · described, not shown
Accelerator dashboard
Built after spotting the team's engagement admin eating delivery time: a zero-dependency web app (HTML and JavaScript, Python build tooling) managing the full engagement lifecycle — scheduling and deadline logic, templated customer communications, and calendar matching integrated with ServiceNow, Zoom, and OneDrive. Adopted across the team, saving an estimated three hours per consultant per week, and maintained against a requirements spec for a future platform version.
It's internal tooling, so there's no demo or code here — but I'm happy to talk through the architecture.