Things I've built
Each diagram shows where the AI model sits and where ordinary code takes over. The model suggests, code checks and decides, and a person does or approves anything that touches the real world.
Data in or outA model proposesCode checks and decidesA person acts or approves
An AI mechanic that picks the next test, inside limits it can't change
An agent reads my car's engine data over OBD-II and decides what to test next. Code checks every request twice, on the server and the tablet, before it reaches the car.
- InThe complaint, trouble codes and live engine readings
- ModelNames competing causes, proposes the test that splits them
- CodeServer guard checks rpm caps and read-only commands
- CodeTablet checks the command again against its whitelist
- PersonDriver holds the rpm the tablet asks for
- OutDiagnosis, the evidence, and the cheapest next step
On a simulated car with six hidden faults, the first evaluation diagnosed five. Four of the six show identical trouble codes.
A worker agent whose code changes wait for tests and my "ship it"
Wick answers in my assistant's chat and can read my whole server. Its code changes land on a branch, get tested, and merge only when my own message says ship it.
- InA message in my assistant's chat
- ModelWick reads the server and drafts a change
- CodeWrite guard puts it on a branch, away from live code
- CodeThe project's own tests run on that branch
- PersonI try a preview copy and type "ship it"
- CodeChecks my words, the commit and the tests, then merges
- OutLive app health-checked, reverted if it stops answering
Of the first 16 ship approvals, 13 went live, 2 merged but waited on a restart permission, and 1 was refused.
De-identifying clinical notes: the model points, code removes
Strips patient identifiers from clinical text on my own server. Rules go first, a model only points at what they missed, and code makes every removal.
- InA clinical note and the identifiers already on file
- CodeRules replace every known identifier with a tag
- CodeOutbound gate blocks anything identifier-shaped
- ModelLists leftover spans, from 7 allowed categories
- CodeDrops bad spans, redacts the rest locally
- CodeStricter release gate refuses if any remain
- OutA redacted note, or a refusal
On 1,473 synthetic patient records (June 2026): k-anonymity of 94, re-identification risk 0.053%, none suppressed.
A week of Toronto Bike Share, playing on a phone with no server
A map of 7.3 million Toronto Bike Share trips folded into one typical week. All the work happens once, ahead of time, so the phone only looks things up.
- In7.3 million 2025 trip records, City of Toronto open data
- CodeBatch job folds the year into an hourly typical week
- CodeWrites 1.9 MB of fixed binary files, no database
- PersonI check what the map shows against the numbers
- OutThe phone's GPU draws every station, no server
7,316,957 trips from 2025 reduced to 1.9 MB of precomputed binary files.
Search by meaning across 18 years of my own records
An index over 763,186 dated records from 53 sources, searched by meaning with a local model. A new embedder has to reproduce the stored vectors before I trust it.
- InDated records from 53 sources, left where they are
- CodeIndex stores each record with a link to its original
- ModelLocal embedding model turns passages into vectors
- CodeA new embedder must reproduce stored vectors first
- InA question typed in plain words
- OutRanked passages, each pointing to its source
763,186 dated records from 53 sources, 2008 to 2026, indexed without moving any originals.
Smaller things
Sun: a light planner for photographers. Pick a building and a spot to stand, and it finds the next minute the sun or moon lines up behind it.
A glass UI kit: the controls on this site and in my apps, including a WebGL shader that refracts the map behind a pane instead of blurring it.
A job-sourcing pipeline: collects postings from job boards and 22 company career sites, scores them against my background with an LLM, and puts a ranked shortlist in front of me each day.
How I build
I design the system and write the specification. AI coding agents write the code. I review it and test it before anything depends on it, and I can explain and defend every decision in these projects. I'm not a career programmer, and I don't pretend to be one.
Where a model is involved, it proposes and code decides. The limit on what a model may do is a program it can't talk its way past, not a sentence in its instructions. Every number on this site comes from a source file and a check that re-derives it.
How this site is built is itself an example.
Experience
Jul 2023 – present
Senior Program Manager, Operations & Partnerships
The PsychoEd Clinic, Toronto
- Grew the practice from one location to six. I found the sites, negotiated the leases, hired the staff, and turned each opening into a standard process for the next one.
- Brought Monarch House, one of Canada's largest autism service providers, into a partnership that put one of our assessment clinics inside their flagship Mississauga site. I met their executives in person until they asked for it, then delivered it: psychologists placed, referral rules written, their staff briefed, the room furnished. Projected revenue was $100,000 to $200,000 a year.
Feb 2016 – Aug 2020
Founder, Partnerships & Marketing
ZaPrisco, Toronto
- Found our customers through r/skookum, a machining community I started and moderated alone, which grew to about 80,000 members.
Mar 2014 – Oct 2015
Clinical Research Assistant
Inflamax Research Inc., Mississauga
- Supported Phase I–IV clinical trials at a contract research organization: protocol adherence, participant coordination, data collection and management. GCP-trained.
2018
B.Sc., Human Biology and Cognitive Science
University of Toronto
