Recently at work, someone asked me why my team wasn’t creating detailed logical data models as part of their solution design. It seems quite simple to me – they don’t do it because nobody reads it. Most solution architecture documentation is out of date before it even gets logged in the architecture repository. Why do we even write documentation? I think we create documentation for one of two reasons: So really, design documentation is about ensuring that everyone’s on the same page, both now and in the future. Some designs are ephemeral – just to help us get our heads… Continue reading →
This is more notes to myself so i don’t forget. Goals: Benefits of 1Password: Initial set up 1. Install 1Password, 1password-cli, direnv. 1Password must be the direct download or Homebrew cask version, not the Mac App Store version as App Store enforces sandboxing. 2. Configure 1Password desktop app 3. Configure shell Add to ~/.zshrc. This causes direnv to evaluate a .env.tpl file each time you navigate in to a folder, and clear when you navigate out of a folder. Open a new terminal shell (or type it in the existing one). Adding secrets to a project 1. Add the secret… Continue reading →
If you’re running Claude Code against your own API key or through a proxy instead of Anthropic’s native backend, you’ve probably noticed that the built-in WebSearch tool just doesn’t return results because it relies on a server-side API that only exists at Anthropic. Without web search, the agent cant research, so we built a self-hosted replacement using MCP. What we built The brilliant DDGS is an open source metasearch server that aggregates results from DuckDuckGo, Bing, Google, Brave, and Yahoo. It has a built in MCP server which exposes five tools: search_text, search_news, search_images, search_videos, and search_books. We deployed it… Continue reading →
Claude Code can do a lot of things. But can it keep a plant alive? The Plant: Act I — Fifty-Eight Days October 22 – December 19, 2025 On October 22, 2025, the moisture sensor read 1829, the first of 5,568 check-ins over fifty-eight days. The scale runs from wet at roughly 1100 to dry at 3400, putting that reading in the middle. The sensor is in the pot of a Tradescantia zebrina. There’s also a 5l jug of water with a pump, a grow light and a camera. Claude’s job is to keep the plant alive – basically, keep… Continue reading →
I have a personal GitHub account and a corporate one, and I found it annoying to have to select the correct SSH key for work repos, so I configured git and SSH to pick the correct key for me. After initial setup, there are three config files to modify: After the initial setup, there are three config files involved: How does it work? well I clone a work repo now and everything is already correct. Generating the keys SSH key first: Give it a passphrase, then add the public key (~/.ssh/work_id_ed25519.pub) to your work GitHub account under Settings > SSH… Continue reading →
By default, Kafka attempts to send records as soon as possible, sending up to max.in.flight.requests.per.connection messages per connection. If you attempt to send more than this, the producer will start batching messages, but ultimately if you saturate the connection so there are unacknowledged message batches pending, the producer enters blocking mode. We can optimise the way the producer batches messages to achieve higher throughput through two settings, batch.size and linger.ms. linger.ms is the number of milliseconds that the producer waits for more messages before sending a batch. By default, this value is 0, meaning that the producer attempts to send… Continue reading →
Claude Code is pretty amazing. It’s let me build prototypes and improve apps faster than I ever thought possible. But I was wondering – what else can it do? I’ve been using Emby for years, but recently I started to wonder what happened to Jellyfin, the project that forked Emby years ago. So i decided to ask Claude Code to help me by setting up a debate and mediating the answer. Setting up the debate Here’s the prompt i used: pretty basic stuff. It got to work, setting up a task list: The folder structure was quite basic: debate.md has… Continue reading →
Although builds were succeeding locally, during CI builds were failing on Linux with the error Error: Cannot find module @rollup/rollup-linux-x64-gnu. npm has a bug related to optional dependencies. The log suggested removing package-lock.json – but this obviously breaks deterministic builds. The root cause is a missing dependency – specifically, when Rollup needs native binaries for performance optimisation. Mac-generated lockfiles won’t include Linux-specific optional dependencies. First noted in npm bug 4828, it was fixed in npm 11.3.0+, but adding an explicit optional dependency prevents edge cases. The fix is: This allows builds to work reliably across platforms. Continue reading →
I was recently asked to design a method to meet ITAC (IT Application Controls) standards for critical data flows in our organisation. ITAC are application-level controls looking mainly at how we ensure the completeness, accuracy and validity of transactions – for example, invoices or trades. Our control set is based on the ICFR principles, of which ITAC is one part. The specific control objective I was asked to look at relates to the risk of loss of integrity of financial data transfers. The focus on the integrity of the data, not authenticity or non-repudiation is really important as it means… Continue reading →
In a previous post, I explained how to configure Azurite to use a self-signed certificate to enable OAuth authentication. One challenge with this method is that the Azure Python SDK will refuse to connect to azurite, reporting errors such as: This is because the the Azure SDK uses the Requests library, which in turn uses Certifi as its source of root certificates. Certifi provides a regularly updated bundle of the Mozilla root trust store, and our self-signed custom certificate obviously isn’t in Mozilla’s trust list! Making Requests trust our self-signed certificate You can get around this by setting the REQUESTS_CA_BUNDLE… Continue reading →
I’m rob. I spend my time exploring the world, playing board games with my family, solving complex technical problems, and learning new things. At work, I lead a team of solution architects designing and building complex realtime trading systems. Sometimes i write about things here, or code them on GitHub. I believe a few things that guide what I do and how I do it: