Hey there! I’m Edd 👋🏻, a Lead Software Engineer with 15+ years of experience. I build reliable, evolvable systems in TypeScript, PHP, and Python - leaning on DDD, event sourcing, the AWS Serverless stack (Lambda, CDK, Fargate, EventBridge), and Terraform. Currently building end-to-end systems for the UK railway signalling sector - from ESP32 telemetry firmware over cellular GPRS through to…
A few weeks back I wrote up a lunchtime session code-golfing a minimal agentic loop with a single sh tool, which turned out to be surprisingly capable. That post was about the floor of what an agent needs to be. This one is about the ceiling, or at least my approximation of it at this point.
Didn’t get much time to delve into side projects this week - but what I did get to was a re-architecture of My Own Coding Agent around extensions, and pulling VoiceScribe back to a local-only pipeline.
A few bits from this week. A bit of fun code golf seeing how small an agentic loop in PHP can be, and more work on Forge with several improvements to the Git review pane. Also been leaning into computer use and terminal recording tools to get agents to verify and demo their own work.
There has been a lot of discussion recently about agent frameworks - orchestration layers, SDKs, harnesses. Over lunch I found myself curious about how much of that is actually essential. How small could a working agentic loop be, whilst still doing useful work? The result is 821 bytes of PHP, running entirely locally via Ollama with a single shell tool - and it turns out that gets you…
A few bits from this week. More time on Forge - deeper integrations with the coding agent harnesses it supports and the ability to spin up isolated workspace services. Also some thoughts on how much I nitpick agent-produced code, and moving Jeeves over to GPT-5.4.
A few things from the week. Jumped on the bandwagon and built my own native macOS terminal for coding agents, let an agent loose on my Advent of Code solutions, and dealt with Anthropic closing the door on third-party subscription access.
This week I’ve been going deeper on how LLMs actually work - not just using them, but trying to understand what’s happening under the hood. This has led me to build a reading companion app to assist in learning.
A mix of things this week. Pokémon nostalgia, getting properly stuck into Pi as a coding agent, and letting an agent loose on my chess engine in the background.
A bit of everything this week. PWAKit docs, rethinking how agents get isolated workspaces, pruning overstuffed config files, and Jeeves diplomatically telling me I’m not marathon-ready.
I’ve been AFK from the computer the last couple of weeks due to the birth of my new baby. This weeknotes is different - less building at the computer, more living with what was already built.
The big theme this week has been wrapping things up - quite literally, in the case of PWAKit - and expanding what already exists into something more robust.
Week three. It’s been another busy week with work and spending any free time I do have with these LLMs, exploring many different things along the way.
We made it to week two. This one’s been heavy on building - a coding agent harness, a labour contraction timer, a desktop diff reviewer - but also on reflecting on how I’m actually using these tools and what patterns are emerging.
This is something new. I’ve been wanting to start capturing the things I’m working on, thinking about, and learning - more raw than a polished blog post, but something I still wish to document. There’s a lot happening with agents and LLM tooling right now, and I feel like personally this stuff is changing so quickly that to have a reference back to my previous experience could be…
As both a runner and someone curious about MCPs, I wanted to chat about my workouts with an LLM. This led me to build Strava and Garmin Connect MCP servers, exploring the Python/FastMCP stack and discovering patterns for designing effective MCP tools. The result: a system that lets Claude/ChatGPT generate throwaway code to analyse my training data in ways I never anticipated.
An exploration of building a Plex MCP server using Laravel 12 and Laravel MCP. By integrating Plex playback sessions with OpenSubtitles, I created a system that lets AI assistants understand exactly where I am in a film - perfect for catching up on missed plot points or diving deeper into themes while watching.
Exploring how AI agents can implement programming languages from scratch. The santa-lang Workshop provides a structured approach using shared PHPT-style tests, Docker isolation, and stage-gated development to compare how different harnesses and models tackle the same language specification across multiple programming languages.
How I levelled up my F1 Picks game in another 4-hour sprint - leveraging Laravel Boost, LLM-driven guidelines, Tailwind styling, and robust tests with Cursor + GPT-5 - to deliver a F1-inspired upgrade just in time for Dutch GP qualifying.
In this post, I share how I built a lightweight web app that scans LEGO F1 blind box Data Matrix codes to identify the minifigure inside. Using Cursor and the GPT-5 model, I put this together in under an hour - saving my nephews from costly duplicate boxes.
In this post, I share my journey designing and prototyping my first PCB: a scaled-down electronic chessboard using an ESP32-S3, hall sensors, and WS2812 (NeoPixel) LEDs. I cover the motivations, design decisions, schematic and PCB layout challenges, and lessons learned while validating key concepts before scaling up to a full 8x8 board.
In this post, I share my experience using AI-driven tools like Cursor, Claude Sonnet, and OpenAI’s o3 to rapidly prototype an embedded chess UI on the ESP32 microcontroller using LVGL. Letting the AI handle implementation allowed me to stay focused on high-level design, iterate quickly, and stay in flow. Hype aside, it’s a powerful tool for exploring ideas faster.
This post is the story of how I rebuilt my blog from the ground up: no frameworks, no preprocessors - just hand-rolled CSS and semantic HTML. Along the way, I rediscovered the power of modern CSS and gained a new appreciation for the tools we now have. And yes, I did chase the elusive 100% Lighthouse score!
In this post, I share a pattern I’ve been using to bridge native Android functionality with JavaScript running inside a WebView. It covers setting up a lightweight Kotlin/Java-JavaScript bridge to handle asynchronous communication between the two.
In this post, I share a pattern I’ve been using to bridge native iOS functionality with JavaScript running inside a WKWebView. It covers setting up a lightweight Swift/JavaScript bridge to handle asynchronous communication between the two.
Hugo provides a means of including limited amounts of video content (YouTube and Vimeo) within Markdown via the concept of embedded shortcodes . In a recent post, I discussed a shortcode that I had made to embed local and remote video content. However, I also required a means to embed audio content, such as that playable via the audio HTML element. To achieve this, I built a custom shortcode for…
Hugo provides a means of including YouTube and Vimeo content within Markdown via the concept of embedded shortcodes . However, I required a way to embed other forms of local and remote video content, such as those playable via the video HTML element. To achieve this, I built a custom shortcode for Hugo.
Over the past week, I have dedicated some of my free time to a long-overdue blog redesign. During this process, I stumbled upon several glaring spelling mistakes in older posts, which led me down the path of manually reviewing all my previous entries. This felt a lot like yak shaving , prompting me to consider whether leveraging a Large Language Model (LLM) could be an effective solution to this…
A walkthrough of Webhook Spy — a minimal serverless tool for inspecting webhooks and inter-service communication. Built with two Lambdas and DynamoDB, it’s fast to deploy, cheap to run, and groups requests effortlessly by path.
I rebuilt my family’s Formula 1 prediction game using NextJS 14, embracing new features like the App Router, React Server Components, and Server Actions. Deploying to AWS Lambda with the Lambda Web Adaptor was a fun challenge that pushed me to explore serverless architecture in a modern frontend context. While the code is a bit wild, the journey taught me a ton about the evolving NextJS…
My family and I have been playing an Formula 1 prediction game for the 2024 season, sharing our picks via WhatsApp and tallying scores manually. Before the F1 summer break ended, I wanted to see how quickly I could build a platform to streamline this process online.
I’ve recently finished reading Monolith to Microservices by Sam Newman. This post contains my notes from the book, which I wrote while reading to help digest the material. It also serves as a future reference.
This post walks through building a choreographed, event-driven order fulfilment system on AWS using EventBridge, Lambda, and SQS. It covers how events propagate between subdomains, the trade-offs between choreography and orchestration, and how to handle idempotency, observability, and event schema design. Inspired by a real-world example in Monolith to Microservices, the post also includes…
In this post, I explore how to implement the Transactional Outbox pattern using serverless technologies. I compare two practical approaches: one using DynamoDB Streams for event publishing, and the other using a relational database with a polling worker. Each approach has trade-offs, but both ensure atomicity between data changes and event publication.
Another year, another Advent of Code , another excuse to explore new languages. After my recent exploration into PWAs this past year, I wanted a reason to explore Kotlin and Swift, two languages equipped for native mobile (Android and iOS) development. Before delving into the mobile domain, I wanted to see what each language had to offer. In this post, I will document my experience completing the…
Over the past several years , I have taken the opportunity of allocating Secret Santas for members of my family as a means of exploring new technologies. For the past several months, I have been interested in the concept of Progressive Web Applications (thanks in large part to this series ), and getting more hands-on experience with the ever-changing frontend landscape. As such, I decided that…
I have been an avid runner for many years now, but I still get confused by imperial and metric measurements. On top of this, the number of times I seek out a random website to perform some form of pace/distance calculation is too often to count. What I wanted was a desktop and mobile application that could perform pace, distance, and time calculations, along with imperial/metric conversions - a…
Now that the interpreter’s performance concerns had been addressed, it was time to decide how each of the available runtimes would be packaged and distributed. In the final post within the series , I will document how the language and runtimes were built, tested, and distributed using a custom CI/CD pipeline.
Now that we have discussed building the core language and desired runtimes, it is time to highlight one of the biggest reasons why I decided to rewrite the interpreter in a lower-level systems language - performance! In this post, I will document how I went about benchmarking the two implementations (TypeScript/Node and Rust), greatly improving performance and highlighting interesting findings…
With the core language library now written, I could go about building the desired (delivery) runtimes. In this post within the series , I will delve into my experience integrating the core language library with these chosen runtimes, documenting some of the challenges that I faced along the way.
After implementing santa-lang in TypeScript (Node) , I wanted to explore rewriting the tree-walking interpreter in a lower-level systems language for efficiency and performance gains. My goal was to be able to run the entire Advent of Code 2022 calendar quicker than the Node variant. I settled on using Rust due to its blend of high and low-level constructs, its vibrant package registry (Cargo),…
The Parkrun Alphabet is an unofficial challenge that sees runners complete a Parkrun at locations starting with each letter of the English alphabet. I am a big fan of Parkrun and wanted to work out how feasible it would be for me to complete the challenge based on the closest tourist locations to my local weekly run. I also thought this would be a great opportunity to explore pandas and work with…
Large language models (OpenAI/ChatGPT in particular) are all the rage at the moment. Like many developers, I am interested in exploring what is possible with this new technology. This post documents the use of LangChain Agents / Tools to aid in answering questions based on recent NBA events.
Large-language models (OpenAI/ChatGPT in particular) are all the rage at the moment. Like many developers, I am interested in exploring what is possible with this new technology. This post documents my experience exploring how to implement Q&A Retrieval Augmented Generation (RAG) using LangChain and Postgres (using the pgvector extension).
Large-language models (OpenAI/ChatGPT in particular) are all the rage at the moment. Like many developers, I am interested in exploring what is possible with this new technology. This post documents my experience exploring how to implement Q&A Retrieval Augmented Generation (RAG) using LangChain and the Chroma vector database.
December has come and gone, and the dust has settled on completing the Advent of Code 2022 calendar. As highlighted in my previous post , I wanted to complete this year’s puzzles using my own programming language, santa-lang, which I have tailored to help aid in solving such problems. In this post, I want to discuss this experience, how the language aided in solution development, and where…
Over the past several years, I have been slowly working my way through the previous Advent of Code calendars. For each calendar, I opt to solve the puzzles in a new programming language to familiarise myself with other ways of understanding and working. However, there comes a time in each calendar when I grow to dislike some aspect of the language. So I had an idea… why not give this whole…