Public case studies

Public projects, shown in full.

Six open-source repositories and one live AI research lab—inspectable evidence of how I approach data engineering, machine learning, delivery and operations.

Open-source repositories

Client work stays private.
This code does not.

Focused libraries drawn from recurring client problems—guarded analytics agents, data quality, experimentation and automotive measurement data—alongside the engine and template behind Retro Speedlab.

Analytics agents

agentic-data-analyst

Chat with your data: Claude writes read-only DuckDB SQL, a second agent reviews it, and deterministic guardrails and cost budgets bound every query — answers, tables and charts in Chainlit.

Python · Claude · DuckDBMIT
Data quality

spark-data-quality

Typed, Spark-native data-quality validation and profiling that combines compatible checks into a single aggregation pass.

Python · PySpark · PydanticMIT
Statistics

experimentation-toolkit

A typed library for A/B experiments covering inference, sample-ratio-mismatch diagnostics, power analysis and multiple-testing correction.

Python · SciPy · PydanticMIT
Automotive data

spark-asammdf

An Apache Spark DataSource V2 connector for distributed analysis of ASAM MDF4 vehicle measurement data, with filter pushdown into the file.

Scala · Apache Spark · PythonMIT
Retro Speedlab · see below ↓

retro-speedlab-core

The engine behind the lab: Go-Explore and tree search over emulator save states, guided by a PPO policy and a route map read from a TAS video, with every run verified frame-exact from power-on.

Python · stable-retro · Stable-Baselines3GPL-3.0

Why it exists

Useful evidence, without breaking trust.

Much of my commercial work sits inside client environments and is protected by non-disclosure agreements. Retro Speedlab offers a modest, transparent alternative: a real system that can be inspected, used and challenged in public.

The lab asks a focused question: how fast can an AI finish Snake Rattle 'n Roll, warpless, from power-on? Answering it combines two disciplines that organisations increasingly need together. The engine searches over emulator save states in parallel emulators, guided by a PPO policy that learns which buttons work and by a route map read from a reference tool-assisted-speedrun video. A new part of the run counts only once it replays frame-exact from power-on, all on a 2017 desktop with an RTX 2070. When the search gets stuck, a scheduled team of Claude Code agents improves the game package, and a second Claude agent keeps the platform itself running.

The playful subject keeps the experiment approachable; the engineering behind it is the same I apply to client systems.

Everything happens in public: the run streams live on Twitch, and every lab report and every record is published on the lab's website.

It is not intended to stand in for the scale or constraints of an enterprise engagement. It simply makes the working habits visible: narrow the problem, build the whole path, automate repeatable operations, measure what is running and keep ownership of code and data.

Two disciplines, one system

A search that learns.
Agents that engineer.

Search and reinforcement learning find the fastest run; agentic engineering keeps improving the system around it. The lab practises both in production, under the constraints clients face: limited hardware, unattended operation and the need to verify every result.

retro-speedlab-core

Search and reinforcement learning

Finding the fastest inputs through a NES game from power-on, on a desktop from 2017.

  • Game model. A small game package reads the emulator RAM and splits the game into states, so the engine knows where each level starts and ends.
  • Exploration search. Go-Explore-style frontier search and a tree search branch from emulator save states in parallel emulators; every level is loaded straight into memory and practised in turns.
  • Learned guidance. A Stable-Baselines3 PPO policy on Gymnasium environments learns on the GPU which buttons work and guides the search.
  • Learning from video. A small CNN reads a reference tool-assisted-speedrun video level by level and turns it into a route map, frames left per map cell, that steers the search and its checkpoints.
  • Verification first. A new part counts only once the movie replays frame-exact from power-on; then every part is trimmed for fewer frames.

For clients: Search, learning and strict verification that optimise a measurable outcome on hardware an organisation already owns, with every experiment tracked in Weights & Biases.

Claude Code · Agent SDK

Agentic engineering

Turning Claude into a dependable, unattended engineering process, with evaluation and observability built in.

  • Multi-agent lab runs. When the search is stuck, a scheduled Claude Code lead agent delegates to subagents that probe the game, research, build and verify, and improves the game package: states, rewards and RAM memory.
  • Hard gates. A change ships only when its tests pass and the current movie still replays from power-on.
  • Observability. Every lab run is traced in Langfuse via OpenTelemetry: a session per run, a trace per round, subagents nested.
  • Evaluation. Each run is scored on whether the search progressed afterwards, and a critic reviews the lab reports and writes lessons for the next run.
  • Autonomous maintenance. A second agent, built with the Claude Agent SDK, runs every six hours: it reads Bugsink errors, lab reports and the live run, fixes the most important problem with a test, merges and deploys or opens a pull request.

For clients: Agents that act on real systems within defined boundaries, measured on outcomes, with a trace and an audit trail for every change they make.

End-to-end system

From game memory
to a proven run.

Each stage is connected, automated and independently inspectable. Flyte workflows run the speedrun and the lab unattended, on portable, open components rather than unnecessary platform dependency.

Retro Speedlab / speedrun loop Operational
  1. 01
    Explorestable-retro · save states · Go-ExploreFrontier grown
  2. 02
    GuidePPO · TAS route map · RTX 2070Search steered
  3. 03
    VerifyFrame-exact replay from power-onRun proven
  4. 04
    ImproveClaude Code · Langfuse · Dokku
    pass → deployfail ↺ reject
  5. 05
    PublishFastAPI · PostgreSQL · TwitchLive in public
Self-hosted on DokkuUnattended around the clockEvery agent run traced

What it demonstrates

Small enough to inspect.
Complete enough to be useful.

The value of this case study is not a polished concept deck. It is the connection between a research question, search and learning, autonomous agents and day-to-day operation.

01

Research framing

One narrow question, answered in public: how fast an AI finishes a NES game from power-on on a 2017 desktop.

02

Measurable outcomes

Every release is tracked in Weights & Biases—levels beaten, frames saved, hours since progress—and every lab run is scored on whether the search moved on.

03

Governed autonomy

Agents work unattended behind explicit gates: tests must pass, the movie must still replay from power-on, and every run leaves a trace and a report.

04

Full-stack delivery

A Vue 3 website and stream overlay on FastAPI and PostgreSQL, Twitch chat commands with “Ask the AI”, and a Discord bot that posts records and lab runs.

05

Operational discipline

Docker and Dokku on a Hetzner server and a home server, self-hosted Bugsink and Umami, and ruff and pyright strict in CI.

06

Pragmatic AI

Claude writes the stream commentary and lab report cards; every input in the run comes from search and a learned policy, proven by replay.

Explore the evidence

See the system,
not just the summary.

The page for engineers lists each component, from the desktop at home to the website, and how well the agents work, measured over every lab run.