Define.
Turn first-party signals into a precise audience spec. The audience is a data structure here, versioned and easy to read, before a single record gets resolved.
I treat audiences as data structures and growth as a thing you build, wire up, and leave running.
DAY JOB: I RUN PETCO'S RETAIL MEDIA PROGRAM, ABOUT $110M A YEAR, AND BUILD THE AD-TECH IT RUNS ON.
I run the playbook, then I build the machine that runs it. There are three parts: audience intelligence, marketing strategy, and AI & systems. One part makes you a specialist. All three wired together is the part nobody can buy off the shelf. Not a full-stack marketer. Not a growth hacker.
Audiences are data structures. You define them and build them. You don't guess.
The persuasion side. Positioning, attribution, lifecycle, and the experiments that keep tuning it.
The plumbing that keeps it running while I'm asleep. LLMs, pipelines, the boxes it all lives in.
A self-serve audience platform for Petco's retail media network. A marketer builds an audience in a guided UI, watches the live Snowflake count come back, clears compliance, and pushes it to eight ad platforms. It replaced a slow, manual LiveRamp workflow, and it saves Petco about $550K a year. REPORTED
To get a targetable audience you wrote SQL by hand or handed it off to LiveRamp. It was slow, easy to get wrong, and out of reach for the marketers who run the campaigns.
People had to trust it in production. The size you preview has to be the size that activates, identity-sensitive filters can't leak, and the existing ad-platform integrations have to keep working. It had to hold up in production, not in a demo.
One declarative JSON audience definition (a typed Pydantic DSL with ~35 filter types) compiles down to a single Snowflake SELECT. The same definition drives the previewed count and the membership that gets pushed to platforms.
It handles include/exclude per dimension, per-filter date windows, a lapsed-buyer EXCEPT, a vet-Rx INTERSECT, and a cross-purchase tri-state matrix. From there a Define, Materialize, Distribute pipeline pushes the resolved set to eight ad platforms.
Three LLM surfaces (a full-page AI Advisor, a brief-first Explore, and a draft-aware Create assistant) sit on one provider abstraction: Claude via AnthropicVertex in prod, an OpenAI-compatible proxy in dev. One streaming tool-call loop, capped at 8 iterations, runs its tools at the same time, so the wait is the slowest tool, not all of them added up.
Grounding is the part that matters. Audience sizes always come from a real SQL COUNT, never the model. Brand and category get matched against live Snowflake vocabularies, so a "dog" request can't slide into a cat department. Proposed filters are checked against Pydantic and dropped with a note if they don't validate. The Create assistant streams fenced JSON suggestions that turn into one-click "Apply to filters" actions.
Credit, net-worth, and household-income filters are fail-closed on every Meta write path. The UI gets a clear 422 with a reason instead of having the filter dropped without warning. Three restricted filters, blocked by default.
Turn first-party signals into a precise audience spec. The audience is a data structure here, versioned and easy to read, before a single record gets resolved.
Resolve identity and turn the spec into an addressable set. This is the step LiveRamp used to own. Now it runs in-house and you can watch every part of it.
Push the resolved set to every connected ad platform and activate. That closes the loop the AI layer reads to suggest what to build next.
Turn first-party signals into a precise audience spec. The audience is a data structure here, versioned and easy to read, before a single record gets resolved.
Resolve identity and turn the spec into an addressable set. This is the step LiveRamp used to own. Now it runs in-house and you can watch every part of it.
Push the resolved set to every connected ad platform and activate. That closes the loop the AI layer reads to suggest what to build next.
A performance-analytics suite sitting on ~20 Snowflake tables. Drill from the whole portfolio down to one campaign, watch budget pacing, put together a brand QBR, and have it write the weekly performance review. A FastAPI backend serves it. The AI insights layer only works from context the server hands it, so it can't invent numbers.
RMN performance data lived across ~20 tables with no single fast way to drill down, watch pacing, or get the weekly review out. Analysts wrote SQL by hand and stitched the results together themselves.
A parameterized query compiler over a star-schema fact table, sitting behind backend-for-frontend composite endpoints. A pile of aggregations land on one screen. The 9-tab Brand Deep Dive fires ~13 independent queries at once on a thread pool.
The suite drills from portfolio to a single campaign, watches pacing and trafficking variance, puts together a brand QBR, and writes the weekly performance review itself, flagging the anomalies. Under the hood it leans on TTL caching of pre-encoded JSON, connection pooling, and concurrent fan-out. It sorts everything into a SCALE / HEADROOM / FIX / WATCH quadrant and calls the one move worth making first.
Past the two flagships, ~29 more systems I shipped inside Petco's retail-media network. Activation, analytics, AI content, data ops, prototypes, and a few one-off analyses for leadership.
Building Petco's first-party audiences and pushing them straight into every ad platform.

One Snowflake audience config fans out to six ad platforms, swapping third-party identity middleware for a direct path we own.
Turning ~20 Snowflake tables into self-serve performance answers for a $110M media program.

Every Monday one command turns the whole 13-brand RMN book into a client-ready review, with one ACTION verb per brand.

The weekly Business Review prep runs as one command now and ships a shareable, Petco-branded site the meeting opens together.
One command turns a brand's category into a client-ready RMN investment pitch, backed by live Snowflake numbers. The real reports stay internal.

One command turns raw sales and competitive-pricing tables into a brief on where in-store revenue leaks, and why.

Dug through Petco's 3-billion-row Adobe clickstream and shipped a VP-facing dashboard tying app behavior to coupon and promo spend.

A self-serve dashboard that ranks keyword, category-path and creative targeting by ROAS, CTR and spend. No SQL needed.

One screen scores every RMN creative, flags the tired ones, and tags each with a scale, refresh or pause call.

Answers whether keyword or category targeting buys more efficiency, straight from the ad server's own data, not an Excel pivot.

Normalizes site-served bookings into comparable package and category keys, the groundwork for catching two advertisers double-booking one shelf.
LLM systems that write, grade and govern content and analysis at retail scale, grounded against real data so the output ties back to a source.

An LLM pipeline that rewrites, re-titles, tags and re-slugs 100K+ Petco pet-care pages, with side-by-side review before anything ships.

Works out why Petco doesn't rank for "dog food", then runs the AI pipeline that fixes the content at scale and pushes it live.

A human-in-the-loop content supply chain with a hard safety floor, so a pet-health page can't ship a made-up medical claim.

Feed it a SKU, get 20 ranked search-ad keywords that blend onsite-search volume, past ad ROAS and LLM candidates.

Drop in a month of RMN report PDFs and get back a narrative locked to a 28-term whitelist, so every metric and channel traces to the source.

An "LMArena for Petco RMN": a harness and leaderboard that grade every proxy model on the team's real retail-media tasks.
Swapping spreadsheets and manual pulls for databases, ETL and tooling the media operation actually runs on.
A booking platform where the database itself won't let you double-book, plus 200+ briefs turned into media-plan training data.

Every morning a per-brand card shows exactly what moved in the media plans overnight and whether it still ties out.

A self-serve catalog that lets the RMN team search, tag and join Snowflake tables without writing information_schema queries by hand.

Type a launch date, get every drop-dead handoff date plus a live view of which booked campaigns are already slipping.
A messy spreadsheet of 777 store addresses goes in; clean city/state/ZIP with a match-confidence score comes out.
Fast prototypes that pressure-test a product idea before it costs real budget.

Closes the gap between what the warehouse knows and what a floor associate knows, in one tablet-sized brief that sticks to the facts.

An internal storefront where employees shop with virtual Petco Bucks, so the company can rehearse price A/B tests without real risk.

A play-money fake store that turns a brand-strategy question (how shoppers split a fixed budget) into a controlled experiment.

Turns a vendor's vague "make us a brand page" into a tiered, priced, position-ordered brief in the strategy queue.
One-off deep analyses that answered a specific high-stakes question for leadership.

Segments 1.5M+ high-value loyalty customers and proves a way to recover 3.6M "invisible" guest-checkout customers hiding behind one catch-all ID.

One branded screen joins revenue, funnel, RMN media, fulfillment and inventory for the VP of Digital.

A margin-first, like-for-like read on two sitewide promos that shows "10% vs 20% off" isn't a topline call.

A reproducible model picking which 330 of ~1,130 private-label SKUs get the next creative-imagery refresh.
Four builds of my own, same engine as the Petco work. Build the entities, embed them, segment, keep the AI honest, ship it. Different problems, same way of working.
Jellyseerr, but for audiobooks. A Next.js discovery front-end and a FastAPI pipeline turn one Request click into a quality-scored, multi-source acquisition hunt, then drop a finished .m4b straight into Audiobookshelf.
Movies and TV have Jellyseerr. Audiobooks had no nice front door. vox mirrors an Audiobookshelf library, builds recommendation rows from real listening history, and runs download, convert, organize, import with a live timeline per request.
A tiered routing engine fans out to per-source workers. After the download it runs auto-m4b, then an LLM organizer, then an ABS rescan, then an import watcher that flips the request to complete.
asyncio.gather. The slow 11-site scraper fan-out waits for tier 2, so preview time tracks the slowest single source instead of all of them added up (~90s, bounded).abs_existing 100 > librivox 90 > indexer 80+seeders > scraper 50 > TTS 40, so a TTS fallback never outranks a real commercial source.
An arbitrage engine for Brazilian federal auctions. It scrapes the Receita Federal portal, reads the product off the auction photos with Gemini Vision, then runs a separate verifier that throws out made-up IDs before it works out a profit window.
The government sells off seized goods through a search-less SPA. That's 5,000+ lots per cycle, half of them with junk descriptions where the real product only shows up in the photos.
A loop runs every 6 hours on its own: scrape, AI enrichment (with the verifier), profit-window evaluator, editorial dashboard.
DESCRIÇÃO NÃO VERIFICADA badge.octet-stream, and an image reorder by classification so the product photo ends up as the cover.
One palate read across every kind of media. It pulls in books, music, notes, browsing and video, has an LLM boil each item down to topics in one shared vector space, and draws the shape of my taste across an Atlas, trend shifts, a streamgraph, a flow map, and an AI sommelier.
This is the same muscle as the Petco audience work: build entities, embed them, score and segment. Here it's pointed at one person instead of a brand.
It pulls in 8 sources, has an LLM enrich each item, and lands everything in one shared vector space, so taste can be measured across media types instead of stopping at the edge of each one.
Ingest. 8 source connectors pull my real activity: Audiobookshelf (audiobook listening), Kavita (manga and light-novels), TriliumNext (notes), Work Notes, browser sessions, Brave history, YouTube (watch history), and Spotify. A scheduled APScheduler cron fleet pulls on a cadence into one SQLite store.
Enrich. An LLM tags each new item through a LiteLLM proxy: 3 to 5 lowercase topics plus a cluster per item, batched and cached. YouTube history gets its own pass, the YouTube Lens: 553 watched · 267 enriched · 440 channels.
Who Bought Your Politicians? A campaign-finance transparency engine that joins FEC contributions, lobbying disclosures and congressional votes into a "Pay to Play" alignment score, drawn as D3 money-flow diagrams for every member of Congress.
Campaign-finance, lobbying and roll-call data are all public, but they sit in separate systems with IDs that don't line up.
A 3-tier stack (PostgreSQL, async Python ETL, Next.js/D3) stitches them together on a BioGuide-ID crosswalk to answer one question: when an industry that funds a legislator lobbies a bill, how often does that legislator vote its way?
This is where the systems thinking gets beaten up before it ships at work. It's a proving ground. Two mini-PCs run the whole estate on their own, fully observable, and they ping me when something drifts. Same instincts as the enterprise builds, minus the budget and the team. It either runs without me or it doesn't. So far it does.
Open to senior retail-media, marketing-engineering and AI-systems roles. I usually reply within a day.