Projects

Things I've built. Most of them run a dental practice every day.

Tools I built on my own at Hybridge, plus the research and class projects that taught me how.

At Hybridge Implants. The seven I'd walk you through first.

7 projects

Patient Dashboard, Hybridge Implants LLC

Live Since Jun 2026

Patient Dashboard

I built the staff side of our patient platform: one row per patient.

  • 1 chart intakes, estimates and consults
  • 100% Right chart chosen in a blind test
Read the write up
Case study Problem, solution, process, result

I built the staff side of our patient platform: one row per patient, every document one click away, and a live read only mirror of the practice management system that the estimator and capacity planner read through.

  • 1 chart intakes, estimates and consults, all on one chart
  • 100% Right chart chosen in a blind test of the record matcher
  • ~4 in 5 Intake surveys that link to their chart on their own
  • 38 Findings from an eight lens adversarial review, run before the matcher could write

Problem

Every system built for the practice named a patient differently: the intake survey by response id, the estimator by its own number, the consult grader by Zoom meeting, the experience survey by email. The Denticon id was optional, typed by hand, and joined nothing. Offices had three spellings, nightly smoke tests sat among real intakes, and the experience report PDF was in storage all along, but the dashboard could not open it.

Solution

Two Cloud Run services from one image. The dashboard, behind Google sign in limited to the company domain, holds no Denticon credentials; a sync service that serves no pages holds them. Webhooks and three scheduled jobs keep a Firestore mirror of offices, providers, patients and appointments current, and a registry API with one secret per caller serves it to the estimator and the capacity planner. Profiles join every record on the Denticon id at read time.

Process

The vendor API has no patient search, so the mirror is the only patient index there is. It also drops unknown query parameters silently and returns the whole table with a 200, so a parameter is allowed only once it is proven to change totalCount. The record matcher went through an adversarial review, ran in shadow mode, and refuses when unsure. A person's decision always wins: each link write is a transaction that decides again on fresh documents, and every link is versioned, audited and undoable. A journey step with no linked chart reads unknown, never no.

Result

Started in June 2026 and rebuilt around the Denticon API in September; production reads were proven on 29 September and v0.24.0 shipped on 5 October. Once the sync ran on a timer the mirror went from six days behind to 2.6 minutes behind on the staging copy, the matcher picked the right chart every time in a blind test, about four in five intakes link to their chart on their own, and the capacity planner reads the registry every minute.

Highlights

  • Two Cloud Run services from one image: the dashboard holds no vendor credentials, and the sync service that holds them serves no pages.
  • Only query parameters proven to change totalCount are allowed, because the vendor drops unknown ones silently and still answers 200.
  • A freshness report that starts from the cursors it expects, so a missing one shows as the worst status instead of vanishing.
  • Record matcher kept in shadow mode after an adversarial review (38 findings that collapsed to 4 critical and 11 high defects), lifted only for rules that were measured.
  • Registry API with one secret per caller, so revoking one consumer never blinds another.
  • 77 vendor API operations transcribed and tested, 18 webhook subscriptions across three offices, and 1,000+ tests.
  • Caught a sweep that reported green while all 18 of its calls failed, and secrets that carried a hidden Windows carriage return.

Built with

  • Next.js 15
  • TypeScript
  • Firestore
  • Cloud Run
  • Cloud Scheduler
  • Cloud Storage
  • Cloud Build
  • GitHub Actions
Doc Coach, Hybridge Implants LLC

Live Since Aug 2025

Doc Coach, Consultation QA Pipeline

I built the tool that grades every implant consult from its Zoom call.

  • +130% Treatment acceptance
  • +43% Revenue
Read the write up
Case study Problem, solution, process, result

I built the tool that grades every implant consult from its Zoom call and sends a color-coded report to the doctor and CEO.

  • +130% Treatment acceptance
  • +43% Revenue
  • -35% Hallucinations
  • HIPAA Eligible, no Workspace DWD

Problem

Implant consultations vary in quality and there was no scalable way to grade them. The CEO had a 7-criterion framework but no system enforced it.

Solution

Cloud Run + FastAPI pipeline. Vertex AI Gemini scores against a versioned `consultation-rubric.md` prompt + JSON Schema 2020-12 contract. Every response must validate (one retry on schema-fail) before it renders a color-coded PDF.

Process

Doctor↔TC identity resolves per meeting via the participants list, transcript alias matching, and an LLM tie-break, with explicit failure modes. Avoided Workspace Domain-Wide Delegation by using a user-OAuth grant on the build owner's account (refresh token in Secret Manager).

Result

-35% hallucinations vs the no-schema baseline is the engineering win; +130% treatment acceptance and +43% revenue followed downstream. A 19-section, 11-acceptance-test PRD with locked column orderings serves as engineering brief and clinical-stakeholder reference.

Highlights

  • -35% hallucinations vs no-schema baseline; +130% acceptance and +43% revenue downstream, under HIPAA controls.
  • Versioned rubric prompt + JSON Schema contract for every Gemini response.
  • 19-section, 11-acceptance-test PRD with locked column orderings.
  • Cloud SQL pgvector + GraphQL for longitudinal scoring analytics.
  • User-OAuth grant bypasses Workspace DWD entirely.

Built with

  • FastAPI
  • Vertex AI Gemini 2.5
  • Cloud Run
  • Cloud SQL pgvector
  • GraphQL
  • Firestore
  • BigQuery
  • Drive/Sheets/Gmail APIs
CBCT Scan Validator, Hybridge Implants LLC

Live Since Mar 2026

CBCT Scan Validator

I built the tool that catches bad dental scans before they ever reach the design team.

  • $98K → <$50/mo Vendor quote vs in-house cost
  • ~5.5s Per scan, CPU-only
Read the write up
Case study Problem, solution, process, result

I built the tool that catches bad dental scans before they ever reach the design team.

  • $98K → <$50/mo Vendor quote vs in-house cost
  • ~5.5s Per scan, CPU-only
  • 0.6309 Honest AUROC (leaky 0.80 caught)
  • 20-scan CICT gate, every push

Problem

Bad CBCT scans (poor field-of-view, motion, missing anatomy) kept reaching the implant-design queue. A vendor wanted $98K up front + $26K/yr to fix it.

Solution

An in-house classifier. Frozen DentalSegmentator nnU-Net v2 encoder + a compact 500K-param head, packaged as a Cloud Run service that scores every scan in seconds.

Process

Bake-off across six architectures, then iterated through Models G, H, J as data taught more. A strict 20-scan CICT holdout caught a leaky AUROC of 0.80 in CI. Shipped the honest 0.6309 rather than game the gate. Tag-based CI/CD lets us hot-swap the head checkpoint via GCS with no OpenVINO IR rebuild.

Result

Under $50/mo running cost. ~5.5s per scan on CPU, scale-to-zero. The 10-year recurring loss from bad scans closes.

Highlights

  • Bake-off across six architectures (A through F), then iterated through Models G, H, J.
  • Model H: frozen DentalSegmentator nnU-Net v2 encoder + multi-scale taps + compact 500K-param head. Cost-tuned threshold (FN cost = 15× FP).
  • 20-scan CICT holdout in GitHub Actions caught a leaky AUROC 0.80.
  • Tag-based CI/CD with hot-swap checkpoint via GCS, no OpenVINO IR rebuild.
  • Found the partner's bidirectional SFTP path (DLCPM has no API license).

Built with

  • PyTorch Lightning
  • MONAI
  • OpenVINO
  • FastAPI
  • Cloud Run
  • Eventarc
  • W&B
  • GitHub Actions
Centralized Diagnostic Filter, Hybridge Implants LLC

Live Since Jun 2026

Centralized Diagnostic Filter

I am turning a founder's diagnostic mental model into a standardized system.

  • Live Intake, PDF, Drive filing
  • 0-200 Future tooth-loss risk score, 4 bands
Read the write up
Case study Problem, solution, process, result

I am turning a founder's diagnostic mental model into a standardized system: every scan, photo, and survey into one report, with the doctor validating every finding.

  • Live Intake, PDF, Drive filing, dashboard in production
  • 0-200 Future tooth-loss risk score, 4 bands
  • v2 Doctor-reviewed ruleset behind the AI read
  • 3 AI generators per clinical report

Problem

The practice's diagnostic intelligence lived in the founder's head and a third-party intake tool. Assessments were screenshotted by hand, filed manually, duplicated across three markets, and the HIPAA posture was unverified. There was no standardized, owned way to turn a complex case into one consistent report.

Solution

The Centralized Diagnostic Filter: a HYBRIDGE-owned system that pulls CBCT, scans, photos, and a risk survey into one standardized report, with a future-tooth-loss risk score and a treatment leaning, never a final diagnosis. The governing rule is AI assists, doctors validate.

Process

Phased to de-risk. Phase 1 replaced the third-party intake with an owned, BAA-covered questionnaire and premium PDF on Google Cloud. I then recorded the founder reading four real cases, turned his narration into a written panorex ruleset with per-rule citations, and implemented it as a Gemini engine on Vertex AI with structured output, where the model observes and the code recomputes every count.

Result

Intake, PDF delivery, and Drive filing are live for all three markets with a nightly end-to-end smoke test. An internal dashboard links cases to Drive folders and generates doctor and consultation reports on demand from three chained AI generators. The founder reviewed the first AI reads and his corrections shipped as ruleset v2; tooth numbering is in a measured eval before more diagnostic scope is added.

Highlights

  • Turns a veteran clinician's diagnostic model into a written, cited panorex ruleset and a running Gemini engine.
  • The validation loop is real: the founder's review of the first AI reads shipped as ruleset v2.
  • A 0-200 future tooth-loss risk score across four bands, preserved from the existing model.
  • Three chained AI generators per report, with one source of truth so pages never contradict.
  • HYBRIDGE-owned on Google Cloud, schema-versioned and auditable from day one.

Built with

  • TypeScript
  • Next.js
  • Google Cloud
  • Terraform
  • Vertex AI Gemini
  • Cloud Run
  • PDF generation
  • HIPAA
NPC Coach, Hybridge Implants LLC

Live Since Aug 2025

NPC Coach

I rebuilt a brittle n8n call grader into a coaching platform.

  • 1,156 Tests on the green gate
  • 40 / 40 / 20 Weighted score + 3 hard gates
Read the write up
Case study Problem, solution, process, result

I rebuilt a brittle n8n call grader into a coaching platform: it finds every new-patient call, grades it with a quoted transcript line behind each score, and tracks each coordinator's trend.

  • 1,156 Tests on the green gate
  • 40 / 40 / 20 Weighted score + 3 hard gates
  • 285 → 40 Calls ingested → scored, day one
  • $50-250/mo Cloud cost at full volume

Problem

An earlier n8n grader proved the idea, scoring each call out of 60 from recordings it pulled off SFTP every hour. But it emitted a brittle semicolon-delimited blob into a single Google Doc, carried no transcript evidence, computed no real score, shared the patient's name and full transcript company-wide, and silently skipped any call when the workflow died mid-run.

Solution

A full rebuild on a HIPAA-scoped Google Cloud footprint. A pipeline ingests recordings from SFTP and CallRail, transcribes with Vertex Gemini, classifies the call, scores relevant new-patient calls on six criteria with a verbatim quote behind each, resolves a stable patient ID, and writes a validated verdict to BigQuery with the report in Cloud Storage.

Process

Ports-and-adapters so the same code runs on in-memory fakes in tests and real cloud in prod, gated by one NPC_BAA_ACCEPTED compliance switch. The scoring math is pure Python, not the model: the 0-100 headline is a 40/40/20 weighted sum, while three hard gates and a patient-urgency override ride alongside as loud flags, never a hidden score cap.

Result

First full day on live calls: ~285 recordings ingested, 40 real new-patient calls scored with quoted evidence, 3 voicemails auto-filtered, 28 flagged for missing a non-negotiable. 1,156 tests green. Live on Cloud Run behind Google sign-in, locked to the practice domain.

Highlights

  • Full rebuild of an n8n prototype: weighted 40/40/20 score, 3 hard gates, a patient-urgency override.
  • A verbatim transcript quote behind every one of six scoring criteria.
  • Ports-and-adapters plus one NPC_BAA_ACCEPTED switch gate all real PHI; 1,156 tests run with no cloud.
  • BigQuery system of record feeding a 26-endpoint React dashboard with per-coordinator trends.
  • Deterministic call IDs so a call is never graded twice or lost; voicemails auto-filtered.
  • Reports view, print, download, and email through a Gmail send identity; recordings transcode to MP3 and play inline.

Built with

  • Python
  • FastAPI
  • Vertex AI Gemini
  • React
  • TypeScript
  • BigQuery
  • Cloud Storage
  • Cloud Run
  • pytest
Capacity Planner, Hybridge Implants LLC

Live Since Sep 2026

Capacity Planner

One forward view of demand, capacity and capability across three offices.

  • Every minute Live schedule sync
  • 48 Tagged releases in the first eight days
Read the write up
Case study Problem, solution, process, result

I replaced the operations lead's staffing workbook with a planner that shows demand, capacity and capability across three offices, reads the live schedule every minute, and never writes back.

  • Every minute Live schedule sync, with no vendor credential in the planner
  • 48 Tagged releases in the first eight days after the first deploy
  • 1,600+ Tests across engine, web, Postgres integration and Playwright
  • 0 Write paths to the source system, enforced by a type test

Problem

Staffing for three offices lived in the operations lead's workbook: seven sheets and twenty pasted week blocks. Fixed ranges undercounted silently when a row landed outside them, typing over a formula deleted it, and time off entered later never changed the plan. Leadership spent its time solving last minute coverage gaps instead of asking who the best person to place was.

Solution

A pnpm monorepo: a pure TypeScript engine package with no I/O, and a Next.js 16 app on Cloud Run with Cloud SQL Postgres, Drizzle and Google sign in. The same engine runs in the minute sync and in the browser for instant what if changes, golden tested against the workbook. Bookings come from Denticon through the patient dashboard's registry, so the planner holds no vendor credential and only reads.

Process

Read only is a type level test: the appointment source may have no member named like write, create, update, delete, cancel or book. A mass cancel guard stops any sync that would cancel an office's bookings in bulk and changes nothing, after a silently dropped office code nearly did exactly that. Sync failures return 200 so the scheduler does not retry storm, and staleness shows on a status pill. Cover suggestions rank five keys (capability, willingness, presence, free day, pairing), and every reason shown comes from the rule that produced it.

Result

Deployed internally on 28 September 2026, reading live Denticon data the next day, and at v0.44.0 by 5 October with a Needs action tab and Bandwidth suggestions. It plans doctors, assistants, treatment coordinators and front desk. Live data caught real modeling bugs early, like one doctor stacked three rows deep because the schedule books the doctor in the assistant's chair.

Highlights

  • Pure engine package with no I/O: the same math in the minute sync and the browser's instant what if, golden tested against the workbook.
  • Postgres over Firestore for person by weekday by location joins; NextAuth over IAP alone so roles and the audit log know who signed in.
  • Its own cloud project, to isolate patient data and stay clear of a sibling app's database connection ceiling.
  • Minute sync behind a version pointer, never a hot swap; failures return 200 and show up as staleness.
  • Excel files parsed in the browser and never stored.
  • A dependency upgrade put SQL parameters into error messages, so the logger now records only the Postgres error code, constraint and table.
  • Cover suggestions ranked on five explainable keys, with ties broken on person id.

Built with

  • Next.js 16
  • TypeScript
  • Cloud SQL Postgres
  • Drizzle
  • NextAuth
  • Cloud Run
  • Cloud Scheduler
  • Playwright

More from Hybridge. From daily tools to ones still in build.

9 projects

Treatment Estimator, Hybridge Implants LLC

Live Since May 2026

Treatment Estimator

I rebuilt a ten year old pricing tool, and every quoted price is now frozen with the estimate.

  • ~1 month Spec → end-to-end (vendor: never)
Read the write up
Case study

I rebuilt a ten year old pricing tool, and every quoted price is now frozen with the estimate, so the six month price promise holds. Since May it has shipped 72 releases, including visit sequences and the day's consult schedule as its front page.

  • ~1 month Spec → end-to-end (vendor: never)
  • 100% Branch coverage on pricing engine
  • 5 Pricing model kinds
  • 72 Tagged releases from May to October 2026

Problem

A 10-year-old single-price tool couldn't handle three clinics with different price books. The 6-month price-lock was a promise on the PDF, not a system property. An earlier vendor attempt never shipped.

Solution

Next.js 16 + Postgres + Drizzle rebuild. Five pricing models (flat, tiered, tiered-zoned, price-range, per-surface). Captured `*_at_capture` columns freeze every saved price, with per-location price book versions.

Process

9-decision ADR with tradeoff tables and library citations before any code. 100% branch coverage on the pricing engine. Golden snapshots lock every documented wizard path. A `questions-for-Chelsea` doc with worked numbers lets the clinical SME review without reading code.

Result

Shipped end-to-end in about a month, what a vendor failed to ship in a decade. Runs under $35/mo. Since then, 72 tagged releases through October 2026: a three pane drag and drop workspace with phases and scenarios, an Excel export that matches the coordinator's own file with live formulas, a landing page that is the day's consult schedule, visit sequences built from the estimate, and a full restyle in the Hybridge design in nine releases on one day.

Highlights

  • 9-decision ADR with tradeoff tables before any code.
  • Captured *_at_capture columns freeze every saved price, so the 6-month guarantee holds.
  • Three-affordance wizard so the TC never loses context mid-consult.
  • 100% branch coverage on the pricing engine; golden snapshots per wizard path.
  • 72 tagged releases from May to October 2026, with about 800 test cases in the repo.
  • Visit sequences generated from the estimate and edited in a three pane builder, from the shared Treatment Sequence packages.
  • The landing page is the day's consultation schedule, read from the patient dashboard's registry API.
  • An estimate's arch now comes from its options, so the up front Upper, Lower or Both question is gone.
  • Restyled in the Hybridge design (glass shell, Inter, a new logo, restyled PDFs) in nine releases on one day.

Built with

  • Next.js 16
  • TypeScript
  • Drizzle
  • PostgreSQL
  • Auth.js
  • Cloud Run
  • @react-pdf/renderer
  • Zod
Treatment Sequence, Hybridge Implants LLC

Live Since Aug 2026

Treatment Sequence

I replaced hand built Word visit plans with shared packages.

  • 11 Practice masters transcribed verbatim as data
Read the write up
Case study

I replaced hand built Word visit plans with shared packages that generate the plan from an estimate, let the coordinator edit it in a three pane builder, and export it to Word and PDF.

  • 11 Practice masters transcribed verbatim as data, all validated
  • 84 of 92 Generation attempts matched to a validated master in a dev database audit, 0 errors
  • ~8 hrs Chair time in a full arch case, spread across about nine months
  • 0 tokens Shipped as a committed build snapshot, so no registry credential can expire

Problem

Coordinators wrote each patient's visit plan by hand in Word, copied from master documents in Drive, in two formats: a flat list of chair time units, and a six column table for full arch cases and dentures. Every change meant renumbering the visits and redating everything after it by hand, on a case that can run nine months.

Solution

Two packages. sequence-core holds the domain model, the practice masters stored as data, generation from an estimate, date and wait arithmetic, and the Word and text renderers, with no React. sequence-ui is a three pane React editor: visit list, flowchart and a live document preview. The estimator stores a living plan plus immutable version snapshots, and one shared text module keeps the preview, Word and PDF from drifting apart.

Process

Generation picks a template; it never infers a plan. A procedure with no matching visit prints as a yellow open item, an unsupported combination asks for a manual build, and a free text wait stops date projection instead of guessing. Anything not transcribed from a master carries a DRAFT banner on screen, in the PDF and in Word. The packages reach the estimator as a committed build snapshot stamped with its source commit, and a check fails if core and ui come from different commits.

Result

Live inside the estimator since 27 August 2026, with save, versions and PDF a release later, a read only lookup for the patient dashboard, and a Word export that now embeds Inter instead of opening in Times New Roman. A dev database audit matched 84 of 92 generation attempts to a validated master with 0 errors. The named tradeoff: nothing fails yet when the two repos fall out of step, so automating the refresh is next.

Highlights

  • Every template is a verbatim transcription of one practice master, with its source document recorded.
  • Staging became an explicit mode after a bug sent every full arch case to manual build: no implant teeth had been read as no staging.
  • The both arches master was transcribed instead of composed from two single arch masters, because composing them puts the visits in the wrong order.
  • A unique index on sequence and version number guards concurrent saves; at most one accepted plan per estimate.
  • Export routes take the plan in the request body, so a coordinator can export what is on screen without saving first.
  • No registry and no package token in the Dockerfile: a committed snapshot, after pnpm's file protocol quietly kept serving an old build.

Built with

  • TypeScript
  • React
  • Tailwind CSS
  • dnd-kit
  • docx
  • PostgreSQL
  • Drizzle
  • pnpm
Cowork Dashboard, Hybridge Implants LLC

Live Since Apr 2026

Cowork Dashboard

Weekly Monday.com exports turned into an always in sync leadership dashboard.

  • 5.2 s → ~17 ms Weekly tab over a multi year range
Read the write up
Case study

I rebuilt a flaky dashboard on weekly exports, then rebuilt it again on Cloud Run so a card and its drilldown can never disagree. The Weekly tab went from 5.2 seconds to about 17 ms.

  • 5.2 s → ~17 ms Weekly tab over a multi year range
  • 1 registry Every card number is computed from its own drilldown rows
  • 31% → 5.8% Ambiguous patient to lead links, after first name checks
  • ½ day → 3 min Weekly recon time, still just drop four files

Problem

The April version on Apps Script replaced a live API dashboard that broke constantly, but it claimed more than it delivered. Every metric had three implementations (card, drilldown and trend overlay), so two tabs could disagree. The connect column holds only the surname, so about 31% of patients resolved to an arbitrary lead: the 49% to 99% jump measured coverage, not correctness. A multi year Weekly view took about 5.2 seconds.

Solution

A rebuild on Cloud Run behind IAP. Cloud Scheduler checks Drive every five minutes; a private ingest service parses the four exports with ExcelJS, joins and hashes them, and writes an immutable snapshot to Cloud Storage. The browser loads one pinned snapshot of about 0.4 MB and computes everything locally with the same core package the ingest uses, and each card number is a function of its drilldown rows by construction.

Process

Business rules were ported verbatim and held to a parity gate that runs the original Apps Script code in a Node VM. When parity could not catch a one day date shift (both sides used the same reader), a golden test pinned figures read off the old production dashboard. A sorted date index means a one week query touches about 60 rows instead of scanning every lead, and a request sequence guard stops stale results from landing.

Result

Live on Cloud Run since 2 September 2026. The Weekly tab dropped from about 5.2 seconds to about 17 ms, ambiguous links fell from 31% to 5.8% with link quality recorded on every row, a Cash Flow tab shipped on 15 September, and on 30 September it took on the Hybridge design while staying dark. The weekly routine did not change: drop four files.

Highlights

  • Linkage 49% → 99% via the Monday connect column, then made correct in September: first name checks cut ambiguous links from 31% to 5.8%.
  • Weekly recon: half a day → 3 minutes, and the routine is still drop four files.
  • One metric registry: every card is computed from its own drilldown rows, so the two cannot disagree.
  • Weekly tab from about 5.2 s to about 17 ms with a sorted date index.
  • Cash Flow tab: what is booked to begin, windowed on treatment start date, with weekly totals built from the daily numbers.
  • Surfaced ~$460k of orphan patient value the old dashboard was silently dropping.

Built with

  • TypeScript
  • Node.js
  • ExcelJS
  • Cloud Run
  • Cloud Storage
  • Cloud Scheduler
  • Cloud IAP
  • Chart.js
Reconciliation, Hybridge Implants LLC

Live Since Jun 2026

Reconciliation

I replaced 70 hours a week of manual cross checking with an engine.

  • 70 hrs/week Manual cross checking returned
Read the write up
Case study

I replaced 70 hours a week of manual cross checking with an engine that reads three exports and shows the insurance team only the flagged patients.

  • 70 hrs/week Manual cross checking returned to a three person team
  • 2 systems, 1 engine Eaglesoft + Denticon through one core
  • 200+ tests All on synthetic fixtures, no PHI in git
  • 8 of 120 Typical flags per day, everyone else clears automatically

Problem

A three person insurance team spent about 70 hours a week cross checking the schedule, the production ledger, and the clinical notes by hand to confirm every patient seen got documented and billed under the right doctor. It was slow and it failed exactly where mistakes cost the most: care documented but never billed, billed with no note behind it, or billed under the wrong provider.

Solution

A pure, deterministic reconciliation engine wrapped in a thin FastAPI app. Two source adapters (Eaglesoft CSV, Denticon xlsx) normalize hostile exports into the same typed models, the matcher keys everything on patient_id, and a stack of checks (money vs note, billing provider vs the doctor named in the note, note-claimed codes vs the ledger, perio charting proof, office policy rules) separates verified patients from the handful that need a human.

Process

The engine has no network, no database, and no clock, and it takes the timestamp as a parameter, so identical inputs give byte-identical output and every count traces to a source row. Columns map by name and a missing one fails loud; the app also checks the dates inside every file and warns when an export covers the wrong day. 200+ tests run on synthetic fixtures that mirror every real quirk, plus an opt-in golden test against a real day, so no PHI ever enters the repo. Every false flag the team reported got traced, fixed, tested, and redeployed the same day.

Result

Shipped and live on Cloud Run, in daily use. About 70 hours a week of manual cross checking became an exception review of roughly a dozen flags out of ~120 patients a day, over 3,600 hours a year returned. A Gemini clinical matcher is built and waiting behind a preview-mode rollout.

Highlights

  • Pure deterministic engine split from the app shell: same inputs, byte-identical, auditable output.
  • Two practice-management systems normalized into one set of typed models via a source-adapter registry.
  • Matching keyed on patient_id with a fuzzy-name fallback that flags low-confidence rather than guessing.
  • Reads free-text notes despite human habits: nicknames, typos, and template lines that look like exams but are not.
  • 200+ tests on synthetic fixtures plus an opt-in golden test; no patient data in git, ever.
  • Gemini clinical matcher (tooth, surface, procedure code) built but gated behind a preview rollout.

Built with

  • Python
  • FastAPI
  • Vertex AI Gemini
  • Firestore
  • Cloud Run
  • Google OAuth
  • pytest
Daily Sales Report, Hybridge Implants LLC

Live Since Sep 2026

Daily Sales Report

I turned the VP of Finance's morning Excel forecast into an automated pipeline.

  • 4.2% → 1.5% Current month revenue error
Read the write up
Case study

I turned the VP of Finance's morning Excel forecast into an automated pipeline that projects lab revenue and new arch starts three months out, with honest error bands and commentary that cannot invent a number.

  • 4.2% → 1.5% Current month revenue error, early in the month to late
  • 15 + 6 Acceptance values and edge cases pinned on every commit
  • 108 Model constants ported exactly from the original
  • ~290 Tests, up from 31 at the start

Problem

The VP of Finance had built a sound forecast in Excel and handed it over with a spec, but it needed a manual paste, recalculate and send every morning, fed by two daily export emails from the dental lab's case system.

Solution

A pure Python engine package with no I/O, and a pipeline package with parsers, a dedupe ledger and a BigQuery loader, with Terraform for the infrastructure. A daily Cloud Run job runs the model, and a Cloud Run web app behind IAP shows the dashboard, history and a Projections tab. An Apps Script bridge runs inside the VP's own Google account and copies the report attachments to a landing bucket, so the project never holds a credential that can read his mailbox. Gemini writes the commentary over finished numbers only.

Process

Parity first: every acceptance value and edge case from the spec is pinned on every commit. Every number in the Gemini commentary must appear in the report payload, a list of banned phrases blocks advice the model has no business giving, and if the guard fails the report falls back to a deterministic template. No auto tuning: the best in sample parameter grid scored 2.59% but was 0.62 points worse out of sample. A better lag model sits behind a switch because its 0.28 point gain did not clear the noise floor.

Result

In production since 25 September 2026. Current month revenue error falls from 4.2% early in the month to 1.5% late, and the report never depends on the LLM. The one hand typed figure now lives in BigQuery as rows that supersede instead of overwrite, after a scale to zero quietly lost it while the form still said Saved.

Highlights

  • Bands calibrated to cover about 68% of outcomes, for this month and the next two.
  • The mail bridge runs in the VP's own account, so the project never holds a mailbox credential.
  • A number guard on the LLM: any figure not in the payload fails the check and the template takes over.
  • No auto tuning: an in sample win that lost 0.62 points out of sample stayed out.
  • Fixed reflected XSS and path traversal through untrusted filenames, including escaping the model's own output.
  • A hand typed figure that lived in container memory now persists in BigQuery as superseding rows.

Built with

  • Python
  • BigQuery
  • Cloud Run Jobs
  • Cloud Run
  • Cloud IAP
  • Gemini
  • Apps Script
  • Terraform
Marketing Data Warehouse, Hybridge Implants LLC

Live Since Aug 2026

Marketing Data Warehouse

I built a BigQuery warehouse that joins ad spend, calls and leads to booked patients.

  • 98.5% Patients linked to their lead
Read the write up
Case study

I built a BigQuery warehouse that joins ad spend, calls and leads to booked patients and treatment value every day, documented so both people and LLMs can query it.

  • 98.5% Patients linked to their lead
  • 99.5% Join agreement with the weekly exports
  • 22 Golden questions in the weekly Gemini eval
  • ~2 days From spec to a running pipeline

Problem

Marketing numbers lived in five separate logins, and no off the shelf connector could join ad spend all the way through to treatment value, so a connector product was ruled out.

Solution

Google Ads lands through the BigQuery Data Transfer Service; Microsoft Ads, Meta, CallRail, Monday CRM and TapClicks come in through Python connectors running as Cloud Run jobs on Cloud Scheduler. Data moves from raw to staging to marts, every column carries a description, and a data guide tells an LLM what to read first. People query it through Looker Studio, Gemini and an MCP connection.

Process

A daily ops job checks freshness and runs a drift check that alerts on a z score above 3 against a 28 day baseline, and a weekly eval harness asks Gemini 22 golden questions. The lead to patient join moved from fuzzy phone, click id and email matching to the CRM's own board relation link, with the match method recorded on every row. View types that carry the identities of callers, reviewers or leads are blocked in code, whatever the config asks for.

Result

Live since early August 2026, with the TapClicks connector added on 25 September. 98.5% of patients link to their lead, and the join agrees with the weekly exports 99.5% of the time. It is not perfect: the first eval run passed 77% against an 80% gate, and on 23 September pipeline health stood at 32 of 36 checks with the CallRail sync failing two nights running.

Highlights

  • A CallRail backfill looked like the account had no history; the API silently ignores created_after, and start_date brought calls back to June 2025.
  • Lead to patient join on the CRM's own relation link, with match_method on every row.
  • Every column described and a data guide written for LLMs, so a model reads the map first.
  • Drift alerts at a z score above 3 against a 28 day baseline.
  • Identity carrying view types blocked in code: callers, reviewers, commenters and leads.
  • A demo rule of thumb: a funnel conversion near 96 percent means a bad join.

Built with

  • Python
  • BigQuery
  • BigQuery Data Transfer
  • Cloud Run Jobs
  • Cloud Scheduler
  • Gemini
  • Looker Studio
  • MCP
Enterprise Data Project, Hybridge Implants LLC

Live Since Aug 2025

Enterprise Data Project

I moved every team's automations onto one self-hosted AI platform on AWS.

  • -20% Automation cost
Case study

I moved every team's automations onto one self-hosted AI platform on AWS, and cut the bill doing it.

  • -20% Automation cost
  • 500+ hrs/yr Recovered on exec analytics
  • Self-hosted n8n on AWS via Docker
  • Org-wide Standard data flows

Problem

Per-seat SaaS automations were expensive and getting more so. C-suite analytics relied on manual exports each week.

Solution

Self-hosted n8n on AWS via Docker. One platform for every team automation, with data flows standardized across the org.

Process

Migrated existing automations into n8n. Built executive analytics pipelines that publish on a schedule instead of on-demand.

Result

20% lower automation cost. 500+ hours/year recovered on executive analytics. AI initiatives ship on a shared substrate.

Highlights

  • Self-hosted n8n on AWS via Docker, cutting costs 20%.
  • Automated C-suite analytics pipelines recovering 500+ hours/year.
  • Standardized data flows for AI initiatives across the org.

Built with

  • AWS
  • Docker
  • n8n
  • Data Pipelines
  • Automation
Case Intake, Hybridge Implants LLC

Prototype Since Sep 2026

Case Intake

I built a morning list of lab cases that duplicate an earlier scan case.

  • 06:00 ET Daily run on Cloud Scheduler
Case study

I built a morning list of lab cases that duplicate an earlier scan case, so customer service can merge them. It runs as a demo on sample data while the vendor API license is pending.

  • 06:00 ET Daily run on Cloud Scheduler
  • 1 letter The most a name can be mistyped and still match
  • 67 Tests
  • Demo Deployed 30 Sep 2026 on sample data; live mode waits on a license

Problem

Doctors write the prescription in the lab vendor's customer portal, which cannot edit an existing case, so every prescription arrives as a second case that duplicates the scan case already in the system, and customer service has to catch each pair to merge it.

Solution

A Next.js app in the Hybridge design on Cloud Run behind IAP. A Cloud Scheduler job runs at 06:00 ET and lists the likely duplicates. The data sits behind a case source and store interface: sample data today, the vendor's API and Firestore once the license lands.

Process

The name matcher forgives case, spacing, a middle initial, swapped first and last names, and a single mistyped letter. Anything more is a different person.

Result

Demo deployed on 30 September 2026 on sample data, with 67 tests. Live mode is blocked on a vendor API license, and a second phase doctor portal is parked.

Highlights

  • Forgiving but bounded name matching: case, spacing, middle initial, swapped names, one typo.
  • Case source and store interfaces: sample data now, the vendor API and Firestore later.
  • Runs every morning at 06:00 ET on Cloud Scheduler, on Cloud Run behind IAP.
  • Built in the Hybridge design system.

Built with

  • Next.js
  • TypeScript
  • Cloud Run
  • Cloud Scheduler
  • Cloud IAP
Hybridge Forms, Hybridge Implants LLC

In build Since Sep 2026

Hybridge Forms

I am building our own forms platform to replace a Tally, Zapier and Monday chain.

  • 32 of 32 Live Tally forms the importer handles
Case study

I am building our own forms platform to replace a Tally, Zapier and Monday chain on four company websites, around one rule: no submission is ever lost.

  • 32 of 32 Live Tally forms the importer handles
  • 1,300+ Tests across core, admin, renderer and forms
  • 11 of 18 Build tasks done as of October 2026
  • 4 sites Company websites it will serve

Problem

Website forms on four company sites ran through a chain of three vendors: Tally to collect, Zapier to move, Monday to land.

Solution

One owned platform: a public forms app with an embed script, an admin dashboard with a form builder behind IAP, a read API for downstream tools, and nightly checks.

Process

Built around one rule: no submission is ever lost. If Firestore fails, the answers go to a private Cloud Storage bucket and the visitor still sees success. If both fail, the server answers 503 and the browser retries four times over about 15 seconds with the same id, then keeps the answers on the device. An importer brings over all 32 live Tally forms.

Result

In build: about 11 of 18 build tasks done as of October 2026, with over 1,300 tests across the core, admin, renderer and forms packages. Not deployed yet.

Highlights

  • Firestore first, a private Cloud Storage bucket as the fallback, and the visitor still gets a success.
  • The browser retries four times over about 15 seconds with the same id, then keeps the answers locally.
  • The Tally importer works on all 32 live forms.
  • Admin dashboard and form builder behind IAP, plus a read API for downstream tools.

Built with

  • TypeScript
  • Firestore
  • Cloud Storage
  • Cloud IAP
  • Vitest

From the NYU days. The work that taught me how.

5 projects

LLM persuasion research

Research May 2024 to Sep 2025

Teaching Llama to Argue Better

I trained Llama to write more convincing counter-arguments.

Read the write up
Details

I trained Llama to write more convincing counter-arguments, using a reward model and RLHF (GRPO and PPO), with real people judging the results.

A research project on persuasion: I trained Llama to argue better, comparing two training methods (GRPO and PPO) against a learned reward model.

Highlights

  • SFT + RLHF pipeline with QLoRA/LoRA and TRL, trained against a reward model.
  • Compared GRPO and PPO-style optimization for persuasive response quality.
  • Evaluated with BLEU/ROUGE plus human scoring to validate improvements.

Built with

  • Llama 3.1
  • GRPO
  • PPO
  • RLHF
  • TRL
  • QLoRA
  • LoRA
  • PyTorch
Loan Radar

Academic Jan to May 2025

Loan Radar

I built the whole pipeline for loan-default scoring.

Read the write up
Details

I built the whole pipeline for loan-default scoring: training and serving in containers, full model history, and quality gates before anything ships.

Loan Radar is a production-grade loan default scoring platform with containerized services, observability, and resilient retraining and deployment workflows.

Highlights

  • Built ML CI/CD with Docker plus FastAPI services, MLflow artifact lineage (MinIO + PostgreSQL), and automated unit/integration quality gates.
  • Developed low-latency microservices with FastAPI, Flask, and Uvicorn, delivering 0.79ms median and 0.87ms p95 inference at 33k+ samples/sec throughput.
  • Operationalized retraining via Airflow and Terraform-provisioned multi-node infra, packaging Ray head/worker, API, and MLflow services for Kubernetes scaling, rolling updates, and rollback-safe deployments.

Built with

  • FastAPI
  • Flask
  • Uvicorn
  • Docker
  • Kubernetes
  • MLflow
  • Airflow
  • Terraform
  • Ray
Fake News and Sentiment Analysis

Academic Feb to May 2024

Fake News and Sentiment Analysis

I built two models for the 2020 election.

  • 76% Llama 3 8B accuracy on LIAR
Read the write up
Case study

I built two models for the 2020 election: one to flag fake news (76% on the LIAR benchmark), one to read how 1.8M tweets felt.

  • 76% Llama 3 8B accuracy on LIAR
  • 1.8M+ tweets through the sentiment pipeline
  • 2 models misinformation + sentiment, shared ETL
  • 1 GPU whole fine-tune in 4-bit

Problem

"Detect fake news" hides two problems: labeling whether a claim is checkably false, and reading how a crowd of 1.8M tweets feels about it. They need different models and different data.

Solution

Llama 3 8B fine-tuned with QLoRA on the LIAR benchmark for misinformation, RoBERTa fine-tuned for sentiment over the tweet firehose, and LDA for topic clusters, all hanging off one shared cleaning module.

Process

Watched per-class precision/recall instead of trusting raw accuracy on imbalanced LIAR. Unified the tweet and LIAR cleaners to kill train/serve skew. Tuned LDA by coherence after stopword/hashtag handling.

Result

76% on LIAR (honest, given short politically-loaded claims), cheap RoBERTa inference across 1.8M rows, and defensible topic clusters. Route the cheap model over everything, spend the 8B only on flagged claims.

Highlights

  • 76% on the LIAR misinformation benchmark with a 4-bit Llama 3 8B + LoRA adapters.
  • RoBERTa, not an LLM, for the 1.8M-tweet stream, because throughput beats the last point of accuracy.
  • One shared cleaning module across both models to prevent train/serve skew.
  • LDA topic clusters tuned by coherence, not eyeballed.

Built with

  • LLaMA 3
  • QLoRA
  • RoBERTa
  • LDA
  • Python
ResNet CIFAR-10 class competition

Academic 2024

ResNet Under 5M Parameters

A class competition: 55 teams, 2 weeks, CIFAR-10, under 5M params.

  • #1 / 55 on the professor's unseen test set
Read the write up
Case study

A class competition: 55 teams, 2 weeks, CIFAR-10, under 5M params. I went from 42nd to 1st on the unseen test set by adding data, not a bigger model.

  • #1 / 55 on the professor's unseen test set
  • 97.12% CIFAR-10 accuracy, up from ~92%
  • < 5M param cap, ResNet-only
  • 0 params added by augmentation

Problem

A deep-learning class competition: 55 teams, two weeks, best CIFAR-10 classifier. Hard rules: stay a ResNet, stay under 5M parameters. We cleared the 85% bar and then sat at a frustrating 42nd.

Solution

The rules said no bigger model, so I added data instead. Augmentation, rotating, cropping, and flipping the CIFAR-10 images, gave the model far more to learn from without adding a single parameter.

Process

I tried different ResNet variants and swept hyperparameters to a solid setup (~92%, 16th in class), but tuning hit a wall under the cap. I read papers and open-source repos to see how the best were doing it, then reframed the problem from 'better model' to 'more data.'

Result

97.12% accuracy, 2nd of 55 teams (0.17% behind 1st). On the professor's secret unseen test set, our model generalized best and finished 1st in the whole class. Earned a bonus grade point.

Highlights

  • Went from 42nd to 1st on the unseen test set by adding data, not parameters.
  • Augmentation (rotate/crop/flip) multiplied the training data at zero parameter cost.
  • Hyperparameter tuning alone stalled at ~92% under the 5M cap.
  • 2nd of 55 on CIFAR-10 test (0.17% off 1st); 1st on the professor's unseen set.

Built with

  • ResNet
  • PyTorch
  • Data Augmentation
  • CIFAR-10
Customer Segmentation and Recommendation System

Academic Feb to May 2024

Customer Segmentation and Recommendation System

I built a recommender for 22M+ records: a fast step to shortlist, a smart step to rank.

  • 22M+ records processed on Spark / Hadoop
Read the write up
Case study

I built a recommender for 22M+ records: a fast step to shortlist, a smart step to rank. 20% better than just showing what's popular.

  • 22M+ records processed on Spark / Hadoop
  • +20% Precision@K over a popularity baseline
  • 2-stage candidate generation → ranking
  • 100s candidates ranked per user, not millions

Problem

At 22M+ records on HDFS, scoring every user against every item is intractable. The question stops being "which model" and becomes "how do I not compute the things I don't need to."

Solution

A two-stage pipeline: MinHash LSH buckets similar entities for cheap, recall-oriented candidate generation, then ALS matrix factorization ranks only the few hundred survivors per user.

Process

Salted hot keys and repartitioned to fix Spark data skew. Tuned LSH bands/rows against candidate recall as an explicit knob. Fell back to the popularity baseline for cold-start users.

Result

+20% Precision@K over the popularity baseline (the honest thing to beat) at 22M+ records. Swap LSH for ANN and ALS for a learned ranker and it's the literal production blueprint.

Highlights

  • MinHash LSH for candidate generation, ALS matrix factorization for ranking.
  • Processed 22M+ records with distributed Spark jobs on HDFS-backed storage.
  • Beat the popularity baseline (not random) on Precision@K by ~20%.
  • Fixed Spark data skew by salting hot keys before the join.

Built with

  • Spark
  • Hadoop
  • MinHash LSH
  • ALS
  • Python

Built in the open. The one I build for myself.

1 project

JobPilot open-source job-hunt autopilot

Open source Since 2026

JobPilot

My open-source job-hunt autopilot.

Read the write up
Details

My open-source job-hunt autopilot. It watches 160+ company boards directly, scores each role against my profile, and tailors a resume and cover letter per match, with a calibrated AI judge keeping the rewrites honest.

An open-source job-hunt platform: direct board watching across eleven sources, schema-locked LLM scoring, a calibrated resume judge with a truth-locked rewrite loop, recruiter outreach drafted but never auto-sent, and a multi-page Next.js console behind IAP. The one project that spans all four disciplines.

Highlights

  • 160+ company boards watched directly, not scraped through a job aggregator.
  • Schema-locked LLM scoring per role, plus a per-job chat copilot grounded in the live description.
  • A calibrated resume judge with a truth-locked rewrite loop, so a tailored resume never invents experience.
  • A company watchlist that auto-detects each board's ATS; recruiter and cold outreach drafted into Gmail (never auto-sent), and replies flagged the moment they land.
  • Open-sourced under MIT with a fork guide written to hand to an AI coding agent.

Built with

  • Python
  • Next.js
  • Vertex AI Gemini
  • LaTeX
  • Google Sheets
  • Cloud Run
  • Cloud IAP
  • GitHub Actions

Let's build something. Tell me what you're working on.

Hiring for applied AI, or for the last mile where software meets the people who use it? I'd love to hear about it.