Four years delivering digital products in regulated environments — Tata Consultancy Services and Plusnet, on products serving 800,000+ customers — and a habit of building things end to end on my own time.
I like the unglamorous parts: what happens when the signal drops, what happens when two people press the same button, and what happens when someone pulls your app apart to see what's inside.
|
Enquiries and complaints arrive; Revamp reads them, decides what they are and how urgent, extracts the commercial detail, opens the follow-up task and drafts the reply — then stops and waits for a person. Every decision lands in an audit trail. Runs on a deterministic rules engine, so the public demo costs nothing to host. The same interface drives a local model through Ollama, and the same workflows execute in n8n. |
The bit I'd point at in an interview. I ran a real model against it and caught it rewriting "revenue fell, driven by lead volume" into "driven by a decrease in conversion rate, as the conversion rate increased" — a claim that contradicted the evidence table rendered directly beneath it. So I took the model out of that path entirely, put validation on the rest, and wrote down why. Knowing when not to use the model is most of the work.
|
Fixtures, live match events, player ratings, subs collection. Offline-first, so it works on a pitch with no signal. React Native on iOS and Android, Postgres on Supabase. No sign-up — the demo loads a club with a full season already played. |
What I found while building it. A hole that let any club member make themselves an admin of their club. I fixed it in the database policy, where a modified app can't reach it, then wrote a test that signs in as two real users and proves it's closed. That test found a second bug: it had been reading its config from the wrong directory since the day it was written, so it had never actually run.
|
A Chrome side panel that reads whatever page you have open and pulls out the parts you would otherwise go hunting for.
It then offers to save it, copy it, set a reminder, or make a calendar file. It never sends, submits, posts or pays, and it cannot read a page you have not opened it on. Nothing leaves the device: no host permissions at install, no content scripts, one network call in the whole codebase, and no model anywhere near the reading — which is what lets 477 tests hold the behaviour in place. |
The line I had to delete. It used to say "Ruled out" when an advert asked for a DBS check. That is the product claiming to know something about the reader from evidence that is only about the advert — you might hold one, or get one in a fortnight. It was ruling people out of jobs nobody had ruled them out of. Conditions are now stated as what the advert asks, with a button that says I have this, and the answer is remembered.
|
Picking someone up or dropping them off at Manchester: it works back from the flight — landing, border, bags, the walk out — to the time you should leave home. Live aircraft positions refine the time from your booking; when nothing live is available, it says so instead of guessing. Costs nothing to run or to use. A scheduled GitHub Action publishes the data a browser can't fetch directly, and no credential ever reaches the page. |
What real data taught me. The first live run of the road-closures feed returned 24 disruptions near the airport — every one a routine lane closure for maintenance. Letting those widen the estimate would have put a permanent 6–12% penalty on every recommendation, and a warning that is always on is not a warning. Now only closures actually in force move the number; the rest are reported, not counted.
|
Free, open practice for the aptitude tests used to select trainee air traffic controllers. Every drill explains the format before you start, teaches a method, and reports where you're losing marks. Nothing is uploaded — it all runs in the browser. |
Generated from my CV data on 2026-09-13 — I edit one file and this panel redraws itself.
Previously worked with
.NET · C# · VB.NET · Angular · WordPress · Java · PHP · MongoDB
Still readable, still useful in a code review — just not what I reach for now.
How this page maintains itself: my CV lives in one typed file in the
cv repository. That repository publishes
itself as JSON, and a scheduled workflow here fetches it and redraws the skills
panel above in both light and dark. I update one file; the CV site and this
profile follow. No badge service is involved — every image on this page is
generated in the repository and served from it.
Open to work in technical delivery, development, data or digital transformation. The quickest way to see how I build is the Revamp demo above — it covers the architecture, the guardrails and the reasoning behind both.






