Selected work
All of these run in production for my own business. The numbers come from my own logs and test runs, not third-party audits.
01One-person AI operations platform
Problem. Four business lines and one person: a content site, a paid membership community, a travel advisory practice and a lead-generation site.
- 60+ Claude Code skills, each encoding one repeatable job: drafting articles, researching prices, handling inquiries, renewing members, reporting.
- 100+ scheduled workflows run those jobs unattended. Slack is the operations console for results, diffs, failures and items waiting for approval.
- Each job goes to the cheapest model that can do it: Claude Opus for heavy reasoning, Sonnet for standard execution, OpenAI Codex for read-only research, and plain scripts where no model is needed.
Research, drafting, monitoring, reporting and routine data refreshes run without me. I spend my time on judgment calls and on clients.
Claude CodePythonPowerShellTask SchedulerMCPSlack
02Securing a membership RAG assistant with retrieval-level access control
An on-site AI assistant answers member questions from 4,300+ articles (14,000+ vector chunks) and five community chat archives. Answers are scoped to each member's tier.
The gap I found. Paid articles were protected only where the web page is displayed. The assistant searched the vector index directly, and the index did not know which articles were paid. Non-paying accounts could therefore get paid content by asking the assistant.
The fix.
- Every chunk now carries a permission tag, and the assistant filters by permission before any text reaches the model.
- Tags are re-applied after every content refresh, and ingestion fails closed: if an article cannot be fetched, it is never defaulted to public.
- Role-based regression tests replay the same questions as different member tiers.
Post-fix audit: 0 unprotected chunks across 84 gated articles. Average response time cut 22% (14.3s to 11.1s), then streaming added.
FastAPIQdrantOpenAI embeddingsClaudeWordPress pluginHMAC sessionsCloudflare Tunnel
03Live pricing intelligence
Problem. Travel prices sit behind authenticated trade portals and change daily. Looking them up by hand did not scale, and published price pages went stale.
- Browser-automation pipelines run inside my own authorized accounts, at low request rates. Where possible they call the portal's own endpoints from inside the page instead of clicking through the UI.
- They feed price lists that refresh automatically: 600+ cruise sailings, 20 flight routes, all-inclusive packages and resort deals. The oldest entries refresh first, so the pipelines stay within rate limits.
- A bookability check follows each search result through to the payment page, so prices that show in search but cannot be booked get caught.
One portal rewrite cut a 20-hotel search from over a minute to about 26 seconds. Every booking flow stops at the payment page for a human to approve.
Chrome DevTools ProtocolPlaywrightPythonStatic site generation
04Change-detection sentinels
- Offer monitor: checks 20 credit-card issuer pages every day, compares them with the published articles, drafts updates and posts the diff to Slack. If a page cannot be read reliably, it goes to a human instead of being guessed.
- News monitor: scans 7 industry RSS feeds every 3 hours for promotions that affect existing articles.
- Award-seat report: a daily report on a third-party API capped at 1,000 calls a day. Queries are batched, and new features reuse data already fetched, so they add zero extra calls.
PythonRSSREST APIsSlack
05Membership and community automation
- Renewals: a spreadsheet is the source of truth. Reminders go out once per member, sorted by tier, through an email API with SMTP fallback. Status is written back to the sheet and summarized in Slack.
- Community mining: every day an LLM screens five member chat groups (a 316K-message archive) and surfaces content candidates. A human decides what gets published.
- Knowledge archive: 722 member-reported data points consolidated into a searchable archive, updated with new entries every two weeks.
Google Sheets APIResendLLM classification
06Other experiments
- cpptool.ca: a CPP retirement calculator in 6 languages. Static site, zero backend cost.
- A Manifest V3 Chrome extension prototype, and a text-to-image-to-video prototype (FLUX, Kling).