03

Builds · 2024 to 2026

What I build, and how

"AI-powered" means nothing on its own. Here is the problem behind each build, what I built to fix it, and where I stop trusting the output.

Built
B-01 TypeScript · Next.js · about 40,000 lines · 216 tests

A four plant glass network and the operations platform that runs it

The problem

I spent four years on a glass line where the numbers that ran the plant lived in a dozen places that did not talk to each other: production here, quality there, a shift handover that depended on who was on and what they remembered to say. Nobody had the full picture until it was stitched together days later, by which point the decision that needed it had already been made.

What I built

I built the operations platform I wished we had: four plants, eight furnaces and eighteen forming lines, with more than thirty screens showing control room, quality, planning and cost from one source of truth. Nothing in it is a guess, so the tests check that the numbers reconcile, glass in against glass out, and a plant manager who disagrees with a figure can be shown the assumption behind it and watch it change. The question answering layer on top scored 22 of 22 on questions I wrote and 0 of 12 on the first set someone else wrote. The zero is the number I trust, because nobody tuned it.

B-02 Next.js · Supabase · Claude · 506 unit tests · closed source

Vera, a CSRD reporting platform that became a company

The problem

CSRD makes every large company in Europe report on its sustainability impact, and the step that decides what actually goes in that report, the double materiality assessment, is the one part of the regulation nobody has a method for. The standard states 99 provisions and leaves the hardest of them undefined, so the job lands on whoever is free, with no benchmark and an audit opinion riding on the result.

What I built

Vera takes a company through that assessment properly: scope, thresholds, evidence and a workpaper an assurance provider can actually read. The AI drafts and finds gaps behind guardrails that stop it inventing a disclosure, and every call is metered so the running cost is a tracked line, not a surprise. Writing it up as a congress paper found the one failure the software itself could not catch: a required field for a threshold's reason accepted an empty string, so a placeholder note could ship straight into a client's workpaper. I found it because I went looking. Fixing it was one validation rule, not a research problem.

B-03 React · deterministic solver · Claude engine behind a flag

A timetabling agent that flags what it is unsure of

The problem

A university was building its master's programme timetable by hand in a spreadsheet every term: matching lecturers to classes against language, availability and workload, with no record of why a given match was made and the whole thing redone from scratch the next term.

What I built

I built an agent that assigns what it can and shows the score behind every assignment, so a coordinator can see the reasoning and override it. Where the pool is thin or the constraints genuinely conflict, it labels the assignment for review or as a gap instead of guessing, which is the decision that mattered after scoping with the timetabling staff. The demo runs a free deterministic solver with the same answer on every load. The first version handed the whole problem to Claude at about five cents a run, and is one flag away from switched back on.

Also This site, on Astro with Claude Code, no framework and no external requests. Messaging agents on the Anthropic API and Twilio, a Claude driven paper trading system against Alpaca, a group holiday planner, deadline and reporting automations. About 200,000 lines across twenty repositories since 2024.

The method

I noticed this on group projects during the MSc. Same tools, about the same total time, different results. Classmates asked for deliverables straight away. I spent longer on the background first: what this is, why it exists, what I need out of it, what the constraints are. The work after that was faster and I usually finished first.

Ambiguity in the input turns up in the output, where it is harder to see. Front-loading the context is the same job as scoping a project before anyone builds anything.

Where I stop trusting it

I learned to structure problems, and worked in industry, before any of this existed. So I know how I would do the job by hand, I can tell the model to do it that way, and I can usually tell when an answer is fluent and wrong. The output is confident either way.

The closest call so far was in Vera. A sample report button meant for demo mode was reachable from the live workspace, and it would have written an invented greenhouse gas inventory into a real report: a Scope 1 figure to the tonne, "verified by Bureau Veritas", a materiality table, all formatted, none of it true. Code review caught it and it was gated. That is why nothing a model writes carries a client's name without a person signing it.

It does most of the typing and I am not going to pretend otherwise. What I bring is the framing, the call on which output to trust, and enough domain background to specify the problem properly. Analysis is cheap now. Choosing what to analyse, and owning the answer, is the paid part.