The line
Kelvin Le
Software engineer
kelvin.le.swe@gmail.comRising senior at Maryland, May 2027. Summer 2026 on GitHub's Enterprise Primitives team, working on enterprise identity sync and deprovisioning.
Departures
- 01Enterprise identity at scaleGitHub Identity org · Summer 2026
- 02UFC fight outcome predictorPersonal project · Leakage-safe ML
- 03AlgoVizPersonal project · 1.2k users
- 04Swing AnalyzerPersonal project · On-device pose estimation
- •TerminusEnd of the line · More work
Each stop is a problem that looked simple and was not.
Interned on the Enterprise Primitives team, working on the systems that sync and deprovision enterprise identity.
Problem
Enterprise Teams was capped at 5,000 members. Raising it to 15,000 meant a single team could span up to 15 million effective user-organization relationships, and an earlier scale test had to be killswitched before it completed.
What I did
- Fixed a latent data-loss defect in the identity-provider group sync. Team membership removals were computed from truncated API fetches, so a team synced from a group past the fetch cap could silently lose every member beyond it.
- Traced it to two compounding causes and proved each fix independently necessary by reverting them one at a time. The service's existing test suite passed against the live bug.
- Analyzed production telemetry across the deprovisioning path and found a job class issuing 3.5M+ primary database reads and zero writes per run.
The hard decision
Two proposed optimizations would have moved all 3.5M reads onto replicas and off the primary.
I opened both, then closed both myself after correctness analysis showed each would silently corrupt data under replication lag.
Gave up the performance win to avoid a failure mode that would not have raised an error. Shipped instrumentation to measure the real failure rate instead of guessing.
Result
The sync fix removes a silent data-loss path blocking the member-limit increase. The telemetry work produced a remediation decision for every primary-touching action on the path.
- Users protected per team
- up to 10,000
- Primary reads found in one job class
- 3.5M+ per run, zero writes
- Optimizations withdrawn after analysis
- 2
Ruby · Go · TypeScript · MySQL · Kafka · Datadog
Private employer work. No public repository.
A leakage-safe pre-fight ML pipeline whose output feeds a betting decision layer, so calibration matters more than accuracy.
Problem
Most public fight-prediction models leak. They train on statistics generated during the fight they are predicting, which makes the reported accuracy meaningless.
What I did
- Built a strictly pre-fight feature set: 52 features across both corners, every one derived only from bouts that had already happened.
- Implemented an Elo system from scratch with an opponent-average-Elo feature to capture strength of schedule.
- Split chronologically and grouped by event, so a single fight card can never straddle the split, and fit imputation on the training partition only.
The hard decision
Accuracy alone is the wrong metric when the output is used to size a bet.
Evaluated on log loss and Brier score alongside accuracy, then converted calibrated probabilities and American odds into expected value and quarter-Kelly stakes.
A better-calibrated model can score lower on raw accuracy. That is the correct trade when a miscalibrated probability produces the wrong stake size.
Result
Roughly 62% accuracy on a held-out chronological test set, with no leakage path and calibration measured explicitly.
- Pre-fight features
- 52 across both corners
- Split
- grouped chronological events, 70/15/15
- Models compared
- logistic regression, random forest, gradient boosting
Python · scikit-learn · pandas
Live: not deployed
Ten algorithm visualizations driven by one shared engine, with an AI explainer that knows which step you are looking at.
Problem
Algorithm visualizers are usually ten hand-built animations that share nothing, so every new topic costs as much as the first.
What I did
- Designed a generic step-trace engine. One AlgorithmTopic contract drives all ten topics through a shared player, narration system, pseudocode highlighter, and counter framework, with no per-topic engine code.
- Built a comparator-based binary min-heap so Dijkstra is honestly O(E log V) rather than nominally so.
- Added a step-aware explainer that forwards the current step's narration, active pseudocode line, and live counters, resolves topic scope server-side, and caps every forwarded field.
The hard decision
Claiming an operation is O(1) is easy. Demonstrating it is not.
Instrumented a from-scratch linked list to count pointer writes per operation, then asserted equal cost at size 8 and size 800. Pinned all 16 frames of a Dijkstra trace as a golden regression.
More test infrastructure than a visualizer strictly needs, in exchange for complexity claims that are verified rather than asserted.
Result
Ten topics ship on one engine. The explainer returns a typed error rather than a fabricated answer when it cannot answer.
- Topics on one contract
- 10
- Dijkstra frames pinned
- 16
- Explainer failure mode
- typed error, never fabricated
TypeScript · Next.js · Vitest · Playwright
Upload one golf swing, get the two or three flaws that matter, each explained by geometry rather than a model's opinion.
Problem
Pose estimation gives you landmarks in pixel space. Camera distance, zoom, and phone orientation all change those numbers without anything about the swing changing.
What I did
- Wrote five explainable geometric rules over MediaPipe pose landmarks: early extension, loss of posture, head sway, loss of knee flex, and over the top.
- Normalized every displacement by golfer stature so zoom cannot change a result, and converted to pixel space first so portrait and landscape encodings of the same swing agree within 1e-6.
- Inferred a ball-direction sign at address so one implementation serves both left and right handed golfers.
The hard decision
Measuring hip movement directly would flag any swing filmed with a moving camera.
Measured hip displacement relative to the ankles, so a camera pan moves both and cancels out.
A more complex rule in exchange for not firing on footage where nothing is wrong.
Result
A stateless service that discards each video after analysis and fails with explicit contracts rather than hanging.
- Orientation agreement
- portrait vs landscape within 1e-6
- Explainable rules
- 5
- Failure contracts
- 413 over cap, 504 past deadline, controlled 500
Python · FastAPI · MediaPipe · TypeScript · Next.js
