Read the story

Architecture

Grades each recorded Zoom consult with Gemini.Runs on Cloud Run for three offices.

A Zoom webhook says a consult's transcript is ready, and one Cloud Run service scores it against the CEO's seven criteria with Gemini. The report goes to the doctor, the TC and the CEO, the chart note goes to the TC, and every consult becomes one row in a master Sheet that feeds the weekly report cards.

2.7 min

median from transcript to sent report in October, 9 in 10 under 3.8

0

score fields the one machine route can return, by allowlist and test

471 consults

scored live since May 19 across Rochester, Buffalo and Syracuse

68 min

from the first commit on May 19 to the first live consult graded that night

New York --:-- simulated

Trace a finished consult
Hybridge Doc Coach A Zoom webhook says a consult's transcript is ready, and one Cloud Run service scores it against the CEO's seven criteria with Gemini. The report goes to the doctor, the TC and the CEO, the chart note goes to the TC, and every consult becomes one row in a master Sheet that feeds the weekly report cards. Firestore run rows, claims Gemini 2.5 Pro Vertex AI, schema checked Zoom 2 accounts, signed hooks Webhook receiver Cloud Run, answers 202 HMAC QA orchestrator filter, who, score, send Gmail report + chart note Doctors, TCs, CEO 3 offices Cloud Scheduler warm 7 AM to 7 PM Drive + Sheets archive, master ledger Report cards Mon 8 AM + monthly DocReview board runs, logs, Analyse ready background report + note inbox row first score + note min instances archive + row scores Mon 8 AM sign in Analyse GCP hybridge-zoom-pipeline, us-central1

Hover a part to trace what it touches. Click it for its notes.

  • Built by me
  • Managed by Google
  • Outside system
  • Main data path
  • On demand
  • Credentials cross

When it breaks

What each failure does, and what it does not do.

  1. Zoom sends it twice

    Delivery is at least once. A Firestore claim on the meeting and file turns repeats into one run, and a crashed claim can be retaken after 15 minutes.

    zoom-transcript-pipeline/app/state.py:1

  2. Gemini runs out of room

    On gemini-2.5-pro the thinking spends the same token budget as the answer. A cut response is never parsed, and the retry doubles the budget instead of repeating the prompt.

    zoom-transcript-pipeline/app/scorer.py:312

  3. A send fails after scoring

    The run turns amber. The sweep repairs only the missing email or Sheet row, without scoring again, up to 3 times, then emails me.

    zoom-transcript-pipeline/app/auto_retry.py:86

What I tuned

Small choices that keep it fast and cheap.

  1. Budget, not retries

    After the September 11 incident the scoring ceiling went from 8,192 to 32,768 tokens. Unused ceiling costs nothing: thinking measured 3,534 tokens at 8,192 and 3,589 at 32,768.

    zoom-transcript-pipeline/config/pipeline.yaml:34

  2. Warm only in office hours

    One instance stays warm 7 AM to 7 PM Eastern instead of all night. CPU stays allocated, because the work runs after the 202 and would starve otherwise.

    zoom-transcript-pipeline/infra/main.tf:256

  3. Resume, do not restart

    Report and chart note run as two branches after scoring. A retry that finds a valid scorecard redoes only the branch that failed.

    zoom-transcript-pipeline/app/resume_policy.py:1

Guards

Rules the code enforces, not rules people remember.

  1. Signed or refused

    Every webhook must match its account's HMAC within 5 minutes of its timestamp, compared in constant time.

    zoom-transcript-pipeline/app/security.py:22

  2. Scores stay in DocReview

    The one route another service can call is an allowlist with no score fields, and it fails closed when its secret is missing.

    zoom-transcript-pipeline/app/api_lookup.py:14

  3. No transcript text in logs

    The JSON logger redacts emails, phones and record numbers. Scoring failures log token counts and the finish reason, never the text.

    zoom-transcript-pipeline/app/logging_config.py:1