I build AI systems that make real decisions in production, then test the failure path myself before I trust them. Looking for Deployment Strategist / Applied AI Engineer work.
Chicago · linkedin.com/in/hughprobertson
Four projects, each verified against something real rather than taken on faith.
An MCP server that only lets an AI client write to Salesforce through a propose-then-confirm step. The server holds the "before" state itself, so a client can't forge or skip the check, and it re-verifies against the live record before every write.
How I know it works: tested against a real Salesforce Developer org, including a genuine concurrent-edit rejection I created by hand in the Salesforce UI mid-flow — not simulated in code.
Chose a two-step propose_update / confirm_update split over a single write_update call
Because a client-supplied "before" state can be forged or wrong, on purpose or by bug. Splitting the write means the server, not the caller, owns the truth about what's about to change.
Chose native fetch and Node's built-ins over jsforce, axios, dotenv, uuid
Because every dependency is a black box between a reviewer and what the code actually does. Node already does most of what those libraries offer natively.
Chose classifying failures by type before retrying over a blanket retry on any failure
Because a 4xx fails the same way on every retry — the request is wrong, not unlucky. Only transient failures (5xx, network) are worth retrying.
Chose deliberately breaking the guard and forcing a real conflict by hand over trusting a green test suite
Because a test that has never failed proves nothing. I broke the stale-check, watched the test fail as it should, reverted it, then forced a genuine conflict by hand-editing the record in Salesforce mid-flow — not in code.
A chat-first AI sales execution platform — the product I'm building as founder. Nothing the product tells a seller about their own accounts may be unverified; that's an architectural rule, enforced structurally, not a style guideline.
How I know it works: the public repo is a build ledger, not a highlight reel — halts, corrections, and costs are all in it.
Chose requiring the grading model to quote the exact words behind its verdict, character for character over trusting a model's stated verdict on its own
Because it forces the quote to be real, even though it doesn't prove the quote is relevant. A narrower, honest guarantee beats a broader one nobody can check.
Chose publishing halts and corrections on purpose over only showing what passed
Because a green wall tells you nothing.
Chose tracking "registered" and "running" as separate fields for every agent over one combined headcount number
Because conflating them is how fleets get oversold.
Chose leaving cost fields null until they can be attributed to a specific run over estimating them
Because an estimated number that looks real is worse than an honest gap.
Python + Google Places API + LLM enrichment, loading every restaurant in Chicagoland into the CRM with account overviews and pain-point angles. Replaced manual entry for the whole sales team.
How I know it works: built and run solo, in production, while carrying a full sales quota as an individual contributor — not a side project done instead of the job.
Chose a read-only connection to the source CRM plus a separate warehouse database over writing transformed data back into the system it read from
Because writing back into the system you read from is the most common way these things go wrong. Here it's prevented by the database connection itself, not by remembering not to.
Chose a deterministic template for enrichment over calling an LLM on every row
Because the model wrote better prose, but the template is free, reproducible, and auditable — every profile stores the exact template id that produced it, so "why did it say that" is a query, not a guess.
Chose flagging and quarantining bad rows over dropping them
Because in a sales CRM a missing field is often the signal itself. An account with no reachable contact is exactly the one a rep needs flagged, so dropping it deletes the finding.
Chose an explicit --as-of argument over reading today's date at run time
Because "future-dated" has to be defined against a fixed point, or the pipeline stops being reproducible the moment the real calendar moves past the dataset.
An offline-first iPad app for a family member's field sales territory — voice-to-CRM capture, on-device OCR, and offline caching for reps working areas with dead signal.
How I know it works: a two-phase provider-matching pass against real territory data hit a 100% match rate; the public version runs on sanitized synthetic data.
Seven years as a police officer in Australia, a year as an armoured vehicle crewman, Division I football at Illinois enrolled at 27, then full-cycle B2B sales — sourcing, selling, onboarding, and supporting accounts myself, start to finish. Each one taught the same thing a different way: don't trust a claim you haven't tested yourself.