Projects
The larger personal builds. Each one exists because I wanted to learn a specific shape of system end-to-end; the write-ups focus on decisions and trade-offs rather than feature lists.
FPL Pulse, weekly enrichment pipeline
AWS Lambda, Step Functions, S3, Anthropic Haiku and Sonnet, Langfuse.
A weekly LLM enrichment pipeline for Fantasy Premier League. Five collectors fan out across the FPL API, Understat, and news sources into a four-stage S3 lake; a Step Function drives enrichment over roughly 700 players per gameweek through Anthropic Haiku and Sonnet, cost-engineered to sit inside the AWS free tier with the Claude API as the only meaningful spend. Live dashboard · writeup →
Scout Agent, agentic recommendations
LangGraph, pgvector, Lambda Function URL, SSE streaming.
The interactive plane on top of the FPL pipeline. A four-node LangGraph state machine (planner, tool_executor, reflector, recommender, looped up to three times) runs over a Neon pgvector store and streams transfer recommendations to the dashboard over Server-Sent Events through a Lambda Function URL. Shipped April 2026 after the OAC-on-POST landmine cost me an evening and an ADR. Read →
Knowledge vault and personal plugin
Plain markdown, Claude Code plugin, no embeddings, no MCP, no daemon.
A curated personal knowledge base read directly by Claude Code via Read, Grep, and Glob. Started as a hybrid FTS5 plus LanceDB MCP server with an Ollama embedding pipeline, then deleted entirely once the vault was small enough to fit in context. The deletion is the point. Read →
Tube Race, a daily navigation game
React, TypeScript, Dijkstra, a Python + TfL Open Data pipeline, static on AWS.
A change of shape from the rest: a daily fog-of-war puzzle on the London Underground, where you navigate a fogged map to a target and get scored against the Dijkstra-optimal route. A greedy solver measures how hard each day is, and every station comes with its opening year, traffic, and a fact worth knowing. No backend, no LLM, no per-play cost. Play it · writeup →