Selected work & working record

Systems built to take work off the desk

I find the manual, repetitive thing and build the system that removes it — for my own supplement brand, and for clients in gyms, retail and content. Mostly alone, mostly with AI doing the typing. The part worth hiring is not the speed. It's the operational thinking underneath it — knowing what to automate, what to leave alone, and how to build it so it keeps working after I've moved on.

What the tools below actually changed

7 tabs → 1 the morning check on the business: eleven agents run in parallel, a twelfth writes the briefing
6m55s → 1.96s one client pipeline after caching, with the output verified byte-identical
18 shared modules, so a new client engagement is assembled rather than rebuilt
0 AI models in the path that compares the money on a client's monthly debit run

Selected systems

Clients anonymised
For my own business
Financial
reporting

The P&L

Whether the event actually made money, computed where the data lives

The reporting layer behind my events business. One screen answers what most event organisers work out afterwards in a spreadsheet, if at all: revenue against supplier costs and sponsor income, how many of the people in the room had been before, and for each marketing campaign, what it cost set against what it actually brought in.

It was originally written the obvious way — pull every paid registration into the application and add it up in code, on every single request. That works until it doesn't, and it gets slower precisely as the business gets busier. So the arithmetic moved into the database, where the data already is, and the application receives finished totals rather than raw rows.

The judgement call inside it

The honest question in any campaign report is what you're allowed to attribute. Originally the only evidence a campaign had worked was how many times its discount code was used — which quietly breaks for any campaign without a code, and for any code that gets shared outside the campaign it belongs to. So attribution is now recorded on the registration itself, at the moment of purchase. Knowing which number you can put in front of someone and which is only directional is most of the work.

Operations

The Warehouse Case

Built it, costed it, and then argued against switching it on

An inventory and fulfilment app — products, variants, stock levels, orders, picking, and the reporting over it — built against a proper relational schema rather than a spreadsheet pretending to be one.

Then I costed running it in-house against paying an outsourced fulfilment partner, and the outsourced option won at our launch volume. So we use theirs. The analysis produced a specific number for when that flips — sustained monthly order volume roughly double our launch projection — which is written down as the trigger to revisit, rather than left as a vague someday.

Why this one is on the page

It's the piece I'd most want to be judged on. Building something and then arguing against deploying it, on the numbers, is harder than building it — and the version of me that skipped the costing would have quietly spent months running a warehouse app to justify having written one.

Payments

The Stack

Recurring billing in a country the platform doesn’t support

No subscription app on our store platform supports a single South African payment gateway. Rather than change either, I built the bridge: it holds the customer's authorised card with the local provider, charges it on its own schedule, and then creates a genuine paid order back in the store.

That last step is the whole design. Because the store sees a real order rather than a note about one, everything downstream — stock, fulfilment, the email platform — fires normally and knows nothing about the bridge. No parallel universe of subscription orders to reconcile later.

The details that decide whether it's safe

Money is handled only in whole cents, never decimals. Incoming payment notifications are signature-checked and de-duplicated, because a provider is allowed to send the same one twice and charging twice is not a recoverable mistake. And it refuses to try at all on payment methods that legally can't recur — bank transfers return a non-reusable authorisation, and the system treats that as a permanent no rather than retrying forever.

Evaluation
& accuracy

The Label Audit

Checking whether the machine actually read the tub correctly

Anything that reads product labels automatically depends on a model reading small print off a curved, glare-lit tub photographed in a shop aisle. Trusting that it works is not the same as checking.

So I photographed 25 real products in-store, then separately tracked down each manufacturer's own published nutrition panel — an independent source that knew nothing about my photos — and compared the two, value by value.

What it found

21 of 24 products matched exactly, several with six to nine separate values checked at once. The four misses were all single-digit slips — a 2 read as a 5. No wrong ingredient names, no wrong units, nothing invented. The pass and fail thresholds were written down before the test ran, not chosen afterwards to suit the result.

What it doesn't establish: 23 of the 25 products were curved tubs. Sachets and fine print are barely represented, so this says nothing about that failure mode. That limitation is written into the findings themselves, not left for a reader to notice.

Executive
tooling

Friday

Twelve agents, one morning briefing

A single screen that answers "what is happening in my business today". Eleven agents go and find out, all at the same time; a twelfth reads everything they came back with and writes the actual briefing in plain language.

RevenueSales and order counts for today, the week and the month
InventoryWhat is running low, and how close to out
InboxUnread mail scored for urgency rather than listed
SuppliersSupplier correspondence pulled out of everything else
CalendarToday, plus what is coming in the next seven days
SocialOrganic and paid performance across the ad accounts
CompetitorsReads six local rivals and returns a strategic read, not a link list
EventsSweeps 29 sources for competitor events, so I can plan around them rather than after them
WholesalePipeline and account status from the stockist sheet
TargetsMonthly goals against actuals, and whether the pace clears them
ContentBriefs for what to post, aware of who each segment is
The briefingReads all eleven and writes the morning summary
The decisions that make it usable

Each source fails on its own: a supplier system being down costs you the supplier section, not the page. Expensive work is cached with deliberately different lifetimes — a competitor sweep is worth keeping for a day, a revenue figure is worth minutes. And the agent that writes email replies starts with a draft — I read it, edit it if it needs it, and send it straight from the dashboard.

AI
infrastructure

Loop

An agent runner built around the assumption it will misbehave

A system that puts AI agents to work across my codebases, written directly against the model's API rather than on top of a framework, so the controls stay mine. It splits into two halves that never touch: a build side that plans, writes, criticises and tests a change — then stops, and hands a human a patch to approve — and a monitoring side that watches live payment and stock signals and reports what it finds.

The monitoring side can recommend a fix but is structurally forbidden from running one. Different jobs get different models by cost and by how much judgement they need: the strongest model plans and criticises, a mid-tier model writes and tests, the cheapest one does the frequent, shallow watching.

The controls, specifically

A hard spend ceiling per run and per day that kills the process rather than warning about it. A cap on how many times an agent may loop before it is stopped for making no progress. A timeout on every individual agent. Prompt caching at the conversation level so a long run doesn't re-pay for its own history. And every run writes a trace of what each agent did and what it cost, so an expensive or looping run can be read back afterwards rather than guessed at.

Shared
foundation

The Foundation

A starter kit where a missing key switches a feature off instead of breaking the app

Every new app I build starts from the same foundation: sign-in, error reporting, background jobs, payment webhooks, forms, file uploads, money handling. The governing rule is that every piece works with no third-party accounts connected at all — a missing key means that capability is switched off with a clear message, never a crash. The automated checks enforce exactly that on every change.

How I know it works

Payment webhooks are tested against deliberately tampered, duplicated and malformed deliveries, not just valid ones. Form validation is tested by bypassing the browser checks entirely and confirming the server still refuses bad input. Uploads inspect the file's actual bytes rather than trusting what the browser claims it is, and strip GPS location out of photos. Money is handled in whole cents and refuses ambiguous input rather than guessing at it.

Events

The Door

Tickets, check-in, and the admin side behind them

The platform the reporting above sits on: public event pages, tiered ticket pricing, registration and payment, a QR code that gets scanned at the door, and the admin side behind it — attendees, sponsors and suppliers.

Payment confirmation arrives by webhook rather than by trusting the browser to come back, because the customer closing the tab after paying is normal behaviour and must not cost them their ticket. Access to data is enforced at the database itself, not only in the application, so a mistake in a page can't expose another event's attendee list.

Infrastructure

Oracle

An old desktop turned into always-on infrastructure that reports its own death

An unused PC rebuilt as the machine everything else runs on: reachable from my laptop and phone anywhere in the world over a private network rather than anything exposed to the public internet, with terminal access, full remote desktop, a continuously synced notes vault, and push alerts to my phone when something needs attention.

The part I'd point at

Every alert in the system originates from that machine — so if the machine itself dies, the alerts simply stop, and silence looks exactly like everything being fine. So it now checks in with an external service every 15 minutes, and that service emails me when the check-ins stop. A monitor has to live outside the thing it's monitoring, or it isn't monitoring it. It's also deliberately independent of the agent system's own scheduler, so it still works when that's switched off.

Customer
acquisition

The Card Engine

A quiz that ends in something the customer actually keeps

A customer answers a short quiz and gets back a personalised image generated on the spot — something they'd actually save or share, rather than a discount code. Behind it: scoring, abandonment tracking, rate limiting, content moderation on anything a user types, short links, and the plumbing to pass what was learned into the email platform.

How I know it works

Carries its own test suite across scoring, moderation, rate limiting, attribution and the email sync — the parts where a quiet failure would either leak bad content to a customer or lose the lead entirely.

Context
engineering

Master Context

A company knowledge base written to be read by a model, not a person

One repository holds the business itself — what we sell and why, pricing, operations, brand voice, marketing, the strategic decisions and the dates they were taken. Every other project points at it as the single source of truth, so a fact lives in exactly one place and the projects hold only what's specific to them.

It's structured for retrieval rather than for reading: each repository opens with a table saying which document to load for which question, so an AI session pulls two relevant files instead of thirty irrelevant ones. Decisions are dated and kept even when superseded — including the ones that were reversed, and why — so a later session can't unknowingly re-argue something already settled.

Why it matters more than it sounds

Most of the output on this page comes from one person working with AI. That only scales if the machine arrives already knowing the business. This is the part that makes the rest possible, and it's the piece I'd rebuild first anywhere else.

For clients
Gym
group

The Debit Check

Two lists built independently, compared line by line, with no AI in the path

The list of members to be debited each month was assembled twice, in two systems, by two processes. Any divergence is money — either taken from someone who shouldn't have been charged, or not taken from someone who should.

No AI anywhere in the path that compares the money. A model is the wrong instrument for arithmetic that has to be right every time and has to be explainable to a member who disputes it. Same for the related tool that works out what each cancellation actually costs under the gym's own contract rules.

Fitness
creator

The Corpus

Explaining why a video worked, with a citation behind every claim

A creator wanted to stop guessing at what makes short-form video land. The system pulls a video apart — sampling frames, transcribing the audio on the machine rather than shipping it to a third party, reading on-screen captions locally — and tags it against a library of 21 named storytelling techniques. Every tag must cite a timestamp or a direct quote, so any claim can be checked. Built for many separate accounts from the first line, because it's meant to be sold on.

How I know it works

Caching took a four-video pass from 6m55s to 1.96s with byte-identical output. Account separation was tested with a second account present, confirming one client's settings can't leak into another's.

Own
tooling

The Rails

Approval, shadow mode, redaction and cost limits — built before the client work

An approval queue, so nothing reaches a customer without a person saying yes — and once something is sent it can never be sent twice. A shadow mode that runs the system against real data while writing nothing, so its decisions can be compared against what the human actually did before anyone trusts it. Automatic stripping of personal identifiers. A cost ledger whose price list expires on purpose, so it can't quietly go stale and start reporting fiction.

None of these were built in response to something going wrong. That's the point.

What they are built from

18 modules, one spec each

The client work above is assembled from these rather than written fresh each time. Each one is built to its own written specification, carries its own tests, and does a single job — which is what makes a new client a matter of composition rather than a rewrite.

schemasThe canonical record shapes every other module agrees on
extractPulling structured facts out of unstructured text, schema-checked
eval-harnessScoring that extraction against known-correct answers
gateHuman approval queue — nothing reaches a client unapproved
shadowRun against live data, write nothing, compare to the human
redactStrips names and national identifiers, and refuses when unsure
connectPolling and webhook harness that reconciles its own two paths
ingestClient file imports, quarantined with a reason instead of dropped
reconcileTwo independent exports compared line by line, no AI in the path
cancellationsWhat each cancellation actually costs under the contract terms
digestA window of activity turned into a short, cited brief
measurementThe before-and-after instrument that produces the number
observeSingle-keystroke event logging while watching someone work
content-corpusThe video analysis system described above
cost-logPer-call cost tracking on a price list that expires deliberately
credentialsOne interface, two typed failures, and nothing more
accessRegister of who can reach what, and when it was granted
loggerShared diagnostics, chosen by evaluation rather than habit

Also built

Shorter form
Storefront
The shop front for the supplement brand — a custom theme, not a template with the colours changed.
Wholesale CRM
Pipeline tracking for gym and retail prospects. Deliberately a spreadsheet, for the same reason as the client system above.
Creator attribution service
Designed in full — link-based attribution rather than discount codes alone, commission rules, a payout ledger, and a creator portal with a second authentication step on anything that moves money.
Paid advertising system
Specified: a library of creative formats and a decision loop over ad performance, intended to replace an agency retainer.
Platform app evaluations
Written assessments of which commerce apps to build versus buy, with the reasoning kept so the decision can be re-examined rather than re-argued.

How I work

Three habits
The ledger

Every claim about a system I build is recorded as verified, assumed, or disproven — with the date and the evidence behind it. It's updated in the same commit as the work it describes, because a record that lags is worse than none: it still gets trusted at a glance.

Plan expensive,
build cheap

The hard thinking gets the strongest model available; the typing gets a cheaper one, working from a specification detailed enough that it isn't making design decisions it isn't positioned to make. You don't have the architect lay the bricks.

Attack the plan
before building it

Before anything gets built, the specification is tested against reality — usually by running its own numbers against real data to see whether it does what it claims. This is where the cheapest fixes are.