Commercial Counsel · Payments · AI · San Francisco
Dual-qualified U.S. and Australian attorney. In-house commercial counsel at Block — negotiating enterprise payments and agentic AI partnerships across Square, Cash App, and Afterpay.
Lead commercial counsel for Block's enterprise merchants and agentic AI partnerships across Square, Cash App, and Afterpay — billions in annual GPV contracted; also built the team's legal ops automation stack.
Managed merchant contracting for Cash App and Afterpay across North America; promoted from Contracts Associate within first year.
Managed BNPL merchant contracts through hypergrowth; served as in-house sell-side associate on Block's $30B acquisition of Afterpay, then acqui-hired to San Francisco.
Financial services regulation and M&A litigation across the Australian financial services sector. Fixed-term engagement.
Negotiated partnership agreements for the Office of External Relations with major telecoms, Big Tech, national health systems, and venture-backed startups.
| University of Sydney | LLB · BA (Media & Comms; Government & International Relations) |
| UC Berkeley | Commercial Contract Fundamentals, Executive Education |
| London School of Economics | Global Communications, Summer School |
| Peking University | Mandarin, Winter School |
Street parking in SF is its own sport. My street has a 2-hour limit the city enforces unpredictably, and I got tired of circling the block hoping my spot was free. So I built a tool to answer one question: is there parking in front of my apartment right now?
A CCTV camera watches the spot 24/7 from my window. A local vision-language model checks the feed every 5 minutes and returns a simple verdict. A web dashboard — and an iPhone lock screen widget — surfaces the answer wherever I am. Everything runs on a Mac Mini I already owned, with no cloud APIs and no ongoing cost.
Capture → A cron job fires every 5 minutes, running a Python script that uses ffmpeg to grab a single frame from the camera's RTSP stream, then resizes it to 960px wide to reduce inference payload.
Local LLM inference → The frame is base64-encoded and sent to LM Studio running locally, which serves Gemma 4 (a vision-language model) via an OpenAI-compatible API. The prompt is engineered around a physical landmark in the frame — a street pole — giving the model an unambiguous spatial boundary to reason about. Temperature is set to 0 for fully deterministic output. The model replies with exactly ANSWER: FREE or ANSWER: OCCUPIED.
Server → A pure-Python HTTP server (no frameworks) runs continuously on port 8181. It serves the dashboard and a set of JSON API endpoints for status, the live camera image, snapshot history, and occupancy stats. Results are written to SQLite; the latest frame is stored for the live dashboard image.
Dashboard → A self-contained HTML app shows a live status badge, the latest camera snapshot, occupancy stats (today / this week / all time), a bar chart of historical occupancy, and a scrollable snapshot grid with colour-coded thumbnails. Password-protected with PBKDF2-hashed credentials.