Shipped products, current builds, and personal projects across commerce, AI, banking, and developer experience. Tap any project to see the full story.
Compliance Hub is Swap's system of record for product classification: the tax codes and HS/HTS codes that decide how much duty and tax a cross-border shopper pays at checkout. I led two workstreams that moved classification from manual and partial to automated and destination-specific.
Challenge: shoppers were charged the wrong duty and tax because classification was manual, partial, and blind to what the product actually was. Solution: made Compliance Hub the source of truth, classifying only active products on change with full product context, synced into the fields checkout already reads. Impact: +40% duty/tax accuracy and ~60% less manual SKU review across 13K+ jurisdictions.
The obvious build was our own fine-tuned HS classification model. We tried it. Against the tax engine's classification API fed with full product context, our model trailed by about 15 points on accuracy. In a regulated domain that gap is the difference between a correct customs invoice and an audit liability, so I chose to orchestrate the existing API with better inputs rather than own the model, and put the effort into the data contracts and sync that actually moved accuracy.
The breakthrough on the jewelry disputes was unglamorous: running the classification API with full product depth as input returned the exact HTS codes the merchant said were right. The accuracy problem wasn't the model, it was the inputs we were feeding it. The trade-off I designed around: making Compliance Hub a checkout dependency turned sync freshness into a reliability concern, and per-call costs scale with catalog size, so classifying only active products on change was the lever for both.
We found the problem the worst possible way, through a merchant complaint, because we had no view into accuracy before brands flagged it. If I ran it again, I'd ship the coverage and dispute instrumentation before the classification pipeline, not after. Knowing destination-specific code coverage and HS dispute rate from day one would have surfaced the jewelry misclassifications in-house, instead of in a stalled onboarding.
Results showed up immediately after launching with correct destination-specific duties, across the ~5,000 active SKUs that had been under manual review.
Red Equipment, a UK outdoor brand, rebuilt cross-border fulfillment on Swap, including the transparent duties and territory-specific tax/VAT this work powers, and reported +111% global sales YoY, +65% conversion, and +13% AOV. That's a platform-level outcome with many inputs; accurate, surprise-free duty and tax at checkout is one of them. Read the case study →
Swap earns revenue across cross-border commerce through service fees, duties, and taxes, and billing for it ran by hand. I owned, end to end, the platform that turned it into an automated, auditable system.
Challenge: every cycle, Finance reconciled multiple months of order data by hand, because different fees depend on different events (order placed, fulfilled, returned). It was slow, error-prone, hard to explain to merchants, and it tied up working capital while Swap fronted duties and taxes for weeks. Solution: a rule-based engine that captures each merchant's tax and fee rules once, freezes them in time, does the math, and issues invoices automatically. Impact: ~450 of 800 merchants moved onto automated billing, and invoices now generate in seconds instead of weeks.
The hard part of billing isn't the arithmetic, it's time. Rules change, but past orders must bill on the rule that was true when the event happened. Modelling billing as versioned, point-in-time settings rather than live state is what made it accurate, auditable, and trusted, and it's what let Finance own the rules instead of filing engineering tickets.
Challenge: support split shipments (orders fulfilled from multiple warehouses across countries) where duties and tax calculate by warehouse country of origin, not by order. Solution: shipped tax and duty first, then built the per-line shipping calculator the feature actually needed to be usable. Impact: went from a launch almost nobody could activate to a feature sales now leads with.
"Edge case" is a misleading term in niche or regulated domains. The edge is often what determines whether the feature is usable at all. I traded edge-case coverage for launch speed. The trade was wrong, because the edge wasn't the edge. It was the use case for most of the customer base.
Now I scope down the audience, not the feature. Before a release I ask what's the smallest scope where the whole flow works, not just the headline. When I shipped the LLM customs description generator later, I limited launch to clothing only and kept jewelry, footwear, and medical devices out until we'd evaluated composition accuracy. Same trade-off as split shipments, resolved the right way.
I shaped Swap's U.S. sales tax product and wrote the public guide that explains it. The work turns a problem most founders avoid into something operators can actually act on.
Challenge: U.S. sales tax isn't one tax. It's 12K+ jurisdictions and 50+ states with separate filings, and post-Wayfair economic-nexus rules make a brand liable the moment it crosses a state's sales or order threshold, often without realizing. Solution: nexus tracking across all 50 states, one-click registration, and audit-ready filing, with a public guide that explains the whole thing. Impact: rate handling from 0 to 11.25% automated, and a compliance problem founders avoid turned into a guided workflow.
As Product Manager at OCBC, I owned Connect2OCBC, the bank's open-banking portal where fintech partners discover, test, and integrate against OCBC's 500+ APIs. I ran it across the lifecycle, from requirements to launch.
Challenge: a bank can publish APIs and still see little adoption if partners can't find the right one, try it safely, and go live without a sales conversation for every integration. OCBC's open-banking presence sat in InnoPay Quadrant 3. Solution: a self-serve portal with a clear path: get access, experiment in a sandbox, then go live. Impact: InnoPay ranking moved from Quadrant 3 to Quadrant 4 and targeted API consumption grew 10%.
trade-classify is a small, real system that classifies products to HS codes with an LLM, then refuses to guess when it isn't sure. I built it to make my day-job thinking public: how you ship AI in a regulated domain where a wrong answer is an audit liability, not a bad suggestion.
Challenge: LLMs will happily produce a confident, wrong HS code. In customs, that's a compliance risk, not a UX papercut. Solution: ground the model in the tariff schedule, draw a hard trust boundary between what auto-applies and what routes to a human, and measure it with an eval that reports recall on the risky subset, not just headline accuracy. Impact: 100% precision on auto-applied classifications, 100% recall on the risky subset, and 0% fabrication in the eval set.
pm-ai-skills is a set of Claude Code skills I built for the way I actually work on AI products: turning a PRD into a testable prompt, writing a first-draft eval suite, and red-teaming a feature before it ships. I use them on my own builds, and they're public so other PMs can too.
Challenge: most PM AI tooling stops at "chat with the doc." The repetitive, high-leverage work (writing evals, pressure-testing prompts, finding where a feature breaks) stays manual. Solution: package that work as skills that produce a real first draft you edit, not a blank page. Impact: I dogfooded the eval skill to build trade-classify's eval spec.
A personal build: an agentic "Proactive Delivery Agent" that watches orders in flight, detects delivery exceptions early, and takes or recommends action before they turn into support tickets. It's where I'm sharpening hands-on agentic-system design, the model-native, decision-making layer rather than AI-assisted features.
In active development. More detail and results to come.
No projects in this category yet.