Some scenarios. A game ships. Someone digs through the credits, finds an AI tool listed, and the review-bombing begins. A few weeks later a different game ships, the same tool sat in the pipeline, but nobody notices. That game does fine. The difference between the two outcomes is disclosure, not use. The same pattern shows up in film. A studio quietly uses a generative tool to clean up a…
Every week I read another post arguing that LLM coding agents are fundamentally untrustworthy. The code is buggy. The output needs reviewing. The agent doesn’t fully understand the domain. It hallucinates progress. It tests only the happy path. All valid criticisms. I’ve been managing software engineers for years, and this list sounds awfully familiar. Consider engineers, real ones…
When did you last care which chip was in your laptop? Not which laptop, or which operating system, but which actual silicon processor was doing the work. Unless you’re a gamer or someone running heavy compute workloads, the answer is probably never. You bought the machine because of what it could do, not because of what was inside it. Intel and AMD are invisible. I’ve been thinking…
I was talking with a group recently about LLM-assisted engineering. I was asked how to cross the capability gap: how to feel in control with LLMs rather than dependent on them. My reply was the predictable: develop “good taste” in engineering. Which is the standard advice now, but what does that actually mean in practice? It’s one of those things that’s obviously real; some…
LLM-assisted coding feels slow at first. Painfully slow. You’re constantly second-guessing the output, reading every line, checking for hallucinated imports and invented APIs. This is where the fear creeps in – the worry that you’re losing your craft, becoming a glorified prompt engineer who can’t actually write code anymore. Every suggestion feels like it needs to be verified,…
I’ve been playing with GitHub’s spec-kit this week. It’s pitched as a workflow tool for local LLM agents – think Claude Code, Cursor, Windsurf. The idea is structured development: specify requirements first, then plan, then implement. It works. The /speckit.constitution command establishes project principles, /speckit.clarify resolves ambiguity, /speckit.analyze validates…
I’ve been using Claude Code a lot recently, and I’ve settled on a workflow that’s been producing really good results. The short version is: use two separate Claude instances to challenge each other. The first step, especially when working in an existing codebase, is context gathering. With Claude Code in “plan mode,” I’ll give it a detailed overview of the…
I was a big Notion user. For a while, it was my go-to for everything: project management, note-taking, knowledge bases, and a lightweight CRM. It’s a useful way to quickly build databases and organize data in a slightly more robust way than a spreadsheet, and the WYSIWYG editor is a bonus. But there’s a catch: data is effectively held hostage. Notion’s export formats are, to put…
I’ve been using Bluesky more and more recently. It’s a pleasant enough place to post, though I’m still not entirely convinced by the AT Protocol, but that’s a topic for another day). As I’ve been spending more time on Bluesky, I realised I wanted to bring over my old posts from Mastodon. Manually copying and pasting everything seemed tedious, especially with image…
LLMs are changing how we write software. In the face of this unheaval, it’s tempting to think these tools somehow absolve us from following good engineering practice. We have fifty or so years of layered wisdom, and sticking close to this knowledge not only makes your codebase more robust, it enhances the LLM capabilities and developer experience. One of the most important practices, now…
I’ve tried three of the newer agentic code assistants this week: OpenAI Codex , Google Jules , and Claude Code . I asked each of them to operate in the same codebase, which is a personal app which I built to track my finances. It’s a pretty straightforward Django CRUD application, which tracks account balances over time, does some lightweight reporting, and can produce charts of the…
Working in technology means riding wave after wave of hype. Some waves reshape the landscape; others crash on the shore, leaving behind damp sand and confused investors. I’ve been around long enough to have lived through many hype cycles, inflated with breathless promise, often to be deflated just as quickly. I’ve been thinking about the recent past, and the bubbles built more on…
Like many engineers right now, I’m exploring how LLMs can accelerate workflows. The potential is undeniable: generating code snippets, drafting content, summarizing complex information, powering chatbots. We are on the cusp of a significant shift in how we build software and create digital experiences. The temptation is strong to integrate these powerful tools directly into our production…
The Model Context Protocol (MCP) ecosystem is changing quickly. While experimentation is interesting, I’ve found myself settling on a core set of MCP servers that I use day-to-day to when writing software with AI. These are the ones that have stuck: Github MCP server I primarily use the Github MCP server because it’s the canonical implementation from Github itself. While you can run it…
This is keeping me up at night. The model we built is dying. It’s time to build the next one. Let’s start with a sketch of an agency project. A standard mid-sized website project costs maybe £80,000. That covers the costs of the sales process, a strategist, a project manager coordinating everything, a couple of designers iterating on UX and visuals, a few software engineers building the…
I’ve been using files-to-prompt recently to help query large codebases with LLMs, but I realised this would work just as well for documentation sets. Here’s how to generate a complete documentation set for Django; I’ve been uploading this to a ChatGPT Project as a supporting document, and getting really good results. $ git clone git@github.com:django/django $ files-to-prompt…
I wanted to install a Matrix service for my family. While matrix-synapse is packaged in Fedora, there’s scant documentation regarding what to do next after installing the package. First, you need to generate a configuration file: $ generate_config --server-name your.domain.here --config-dir=/etc/synapse/ --report-stats=no > /tmp/homeserver.yaml $ sudo mv /tmp/homeserver.yaml /etc/synapse…
From time-to-time, I’m asked to evaluate a large codebase. This is usually from a client who has a project in distress, or who needs to quickly move their infrastructure provider and re-host the application elsewhere. I lot of the time this relies on the intuition of a good engineer who is familiar with the technology being used. There’s a lot of code browsing, writing quick notes, and…
I’ve found myself writing a lot of Claude artifact prompts recently. I don’t remember if I started writing these little personal software widgets before of after I read Simon Willison’s post on the same topic , but they are a very fast and straightforward way to feather the personal software nest. I have about ten artifacts which I’m regularly using now, and I’m…
I’ve previously used fingerprint authentication on Thinkpads in the very distant past. There have been a lot of changes to the software stack since then, so I had to rediscover how to make the fingerprint reader work. I’m using Fedora 40. I don’t actually think any of these instructions are Z13 or Thinkpad specific, but YMMV. First, install the fprintd package and start the…
Python 3.13 was released today , and it would be easy to overlook this: “dbm.sqlite3: An SQLite backend for dbm. (Contributed by Raymond Hettinger and Erlend E. Aasland in gh-100414.)” I don’t think that many Python engineers know about the dbm module, which is a shame because it is a sharp tool. It’s a tool for reading and writing to string databases, which has been around…
At work recently, I’ve been working on some code to measure the bandwidth required to display webpages, and from there calculate the approximate energy usage and carbon output. Here are the links from my notes: Greening Digital with Django , a talk by Chris Adams , whose blog is also full of interesting ideas. Faster, leaner, greener: 10x lower website carbon emissions , a talk by Thibaud…
Ruff’s VSCode extension is nice, and can handle the jobs previously done by black and isort . To turn on everything, and to run this on every file save (this is probably what you want, given it only takes a few milliseconds), use this configuration in .vscode/settings.json : { '[python]': { 'editor.codeActionsOnSave': { 'source.organizeImports': 'explicit', 'source.fixAll': 'explicit', },…
I like that iPython can be configured to automatically reload modules. It’s useful to be able to keep REPL context through development, without needing to constantly tear down and setup your context: >>> %load_ext autoreload >>> %autoreload 2 However, turning on the autoreload extension is also annoying to set each time you spawn a REPL, but thankfully this can also be automated: Create a…
I wanted to put together a single-file Django application, which could still do ‘useful’ work; that is, define models, operate on them, and setup URL routing. I ended up with two files. The first, application.py : import os from django.db import models from django.http import HttpResponse from django.urls import path, re_path from django.core.wsgi import get_wsgi_application from…
Similar to my previous post (more than a year ago!) about using Git hooks to enforce conventional commits , I wanted to start logging all of my commits. This is part of a larger project to keep a better work diary, but I wanted to start with something simple and unobtrustive, and this seemed like a simple place to start. We need to create a global hooks folder, and enable it. $ mkdir…
I was looking for a way to enforce the Conventional Commits pattern for my own commit messages. A lot of the solutions I found were wildly overcomplicated; I don’t need to install a commit linting framework with a hundred JS dependencies, I just want to apply a regex to a commit message. This was fairly straightforward. First, create a global hooks folder, and enable it. $ mkdir…
It appears that everyone on the internet completely hates 1-2-1 meetings. I don’t particularly want to add fuel to that viewpoint; I’m sure there are a huge mount of people who completely hate 1-2-1 meetings with their manager . I understand that. However, done correctly, the 1-2-1 meeting is one of the greatest tools we have in the workplace; building lines of communication up, down,…
Some of these are older links I found languishing, misfiled in my Safari favourites. The collapse of complex software Right now, the software industry has been in a nearly two-decade economic boom (with some fits and starts), but the one sure thing in economics is that booms eventually turn to busts. During the boom, software companies can keep hiring new headcount to manage their existing…
Back after a vacation with the ChatGPT special edition. I suspect the theme of the next 5 years will be ChatGPT. Chat GPT is the birth of the real Web 3.0, and it’s not going to be fun. As the ouroboros continues to devour itself into ever-tightening recursion (A “recursive descent”! HA!), we approach the info-bullshit singularity. I believe the web as a way to access information…
We are being levelled-down The government has allocated £9.7 billion of levelling up funding since 2019. But between 2010 and 2020, annual funding from the national government to local councils in England fell from £41 billion to £26 billion adjusted for inflation — and the government’s critics say pots of levelling up funding since are scant compensation. “That’s why we’re in the mess we’re…
It’s a time of year when a lot of businesses are hiring, and layoffs mean there are more candidates in the marketplace. That also means the volume of online commentary concerning ‘bad practices’ is growing; and the amount of bad practice is staggering. Otherwise rational engineering organisations seem very susceptible to copying their hiring process from whatever nonsense the…
Amazon is discontinuing its AmazonSmile charity program next month “Amazon emailed participants of the free program about the news on Wednesday. The email said that AmazonSmile, which launched in 2013, ‘has not grown to create the impact that we had originally hoped.’” It’s despicable that the Smile programme only managed to have ~$45m/year impact, during a time when…
Microservices are a Big Ball of Mud It’s incredible that we still have microservice defenders in 2023. It’s a prime example of the immaturity of software enigneering; the cargo-cult is truly rampant. The article makes the point that this is ‘over-engineering’, which I take issue with. Over-engineering usually implies a baroque, but working solution, when microservices…
A few years ago I used to write these short articles with links to interesting things I found on the internet. I stopped doing that because I didn’t have the time to write them. Now I have the time, so I’m going to start doing it again. Surviving Disillusionment The software engineering discipline is deeply immature. As we seem unable to rectify this, it’s unsurprising that a lot…
This week didn’t have much consistency. I did a lot of work on this game last Sunday, and then I was busy most of the week, and I barely touched the game. I finished it yesterday. I think this shows in the final product; last week I wrote about being glad of having a refactoring pass on the code, something which I didn’t manage to have this time. I did make some progress though, I…
I captured the momentum of last week, and began this game on Sunday evening. There was certainly more time spent on this game, but I spread it out over several evenings. I’ve also shared the first week’s post with a few people, and I’ve had some interesting conversations. I’ve started to develop a rough project list in my head, building complexity. This list is very likely…
Introduction Like a huge amount of software people, when I was young I learned how to write code because I wanted to make games. Now fast-forward 30 years, and I’m a full-time software engineer, I lead software teams, working on big, complex projects, but I’ve still never finished a single game. Looking back, the reason that I never finsihed a game was due to the scale of my vision.…
This will list all registered Django URLs in a project, with their arguments. from django.conf import settings from django.urls import URLPattern, URLResolver urlconf = __import__(settings.ROOT_URLCONF, {}, {}, ['']) def urls(ls, acc=None): if acc is None: acc = [] if not ls: return l = ls[0] if isinstance(l, URLPattern): yield acc + [str(l.pattern)] elif isinstance(l, URLResolver): yield from…
rsync will run in sequential mode by default. This can cause transfers to take a long time, and it’s unlikely to make full use of your bandwidth if you’re copying many small files (for example, when syncing a home folder). This situation can be slightly improved by using xargs to run many parallel rsync operations: ls /home/yourname | xargs -n1 -P8 -I% rsync -Pa %…
I always forget how to setup new Dokku apps; I do it infrequently enough that it never sticks. Create the app: $ ssh host $ dokku apps:create myapp Create the database and link it to the app: $ dokku mysql:create myapp $ dokku mysql:link myapp myapp Set some variables. DEBUG and SECRET_KEY are Django-specific, and the other is for SSL provisioning: $ dokku config:set --no-restart myapp…
I’ve been thinking recently about Github Marketplace; where it may lead. I’m responsible for technical purchasing at Giant . That means that I’m ultimately responsible for the purchasing we make; but I’m also required to justify those purchases. We’re an SME, and the expenses cannot easily flex beyond their budget, and there are other people in the business who will…
In the neverending quest for the ‘right’ development setup, I’ve been thinking about the concept of how to organise and make available my tools. This is partly motivated by some ’new’ (to me at least) tools and options which are becoming more popular; remote development (as included in VSCode ), both in the sense of a remote server, but also a remote environment, like…
After hacking yesterday through a few issues with my AWS account (transferred a domain name from one AWS account to another, but didn’t remove the NS records from the original account led to some DNS confusion and AWS couldn’t then verify certificates in Certificate Manager), I’ve managed to come to a good place with serverless . I now have a Flask application, with multiple…
I’m on holiday this week, and I wanted to use the time to really get to grips with serverless models of deployment. My background is in Python development (which I want to stick with; this week isn’t to learn a new language), and mainly around doing full-stack deployments with Django, and all that entails; a persistant relational database, the MVC pattern, and server-side rendering. I…
This is possibly specific to my own super-minimal postfix setup on Void, but to add a new email user: $ sudo adduser someone $ sudo passwd someone Amend /etc/postfix/virtual , as follows: someone@domain.com someone Regenerate the virtual alias table: $ sudo /usr/sbin/postmap /etc/postfix/virtual And finally restart postfix : $ sudo sv restart postfix
Void Linux uses the very miminalsit service management tool runit . The runsvdir program monitors a folder for service definitions, and then supervises the processes described within. There is a system-wide instance of runsvdir for system services by default on Void, which is responsible for your tty s, sshd , maybe a logger, depending on your configuration. There will be times when you want to…
I recently replaced the keyboard in my Thinkpad X230 with the keyboard from and X220. There are a few reasons for this; while the chiclet keyboard on the X230 is decent (I’ve used it for about a year without any real complaints), the keyboard from the X220 is a much more typist-friendly layout, with a huge Return key, a more sensible layout for Home/End/PgUp/PgDown, and a huge Escape key…
It’s reasonably simple to bring up a new KVM system on Arch, assuming your hardware supports VT-x or AMD-V (and almost everything does). First, check that you have the capabilities needed. The first command checks that the CPU supports virtualisation, and thr second whether your kernel has the appropriate modules available: $ lscpu | grep "Virtualization" $ zgrep CONFIG_KVM /proc/config.gz…
I’m a big fan of TabNine , a machine-learning powered omni-completer for pretty much any language. It’s a hassle to run with FreeBSD, though. These instructions cover running TabNine with Neovim, but you can ignore the Vim-specific parts if you just want to run the TabNine binary on FreeBSD. First, install the plugin in your Neovim configuration file: Plug 'zxqfl/tabnine-vim' Save your…