July 2025
Pupdate
The boys had some fantastic long walks on our trip to the Lakes (more on that in a moment).
I did a separate post about Milo’s extended remission, but it’s great that he’s been able to enjoy the summer without vet visits for chemo.
Lake District
We returned to Graythwaite’s Dove Cottage and this time around $daughter0 joined us for most of the stay.
West Windermere Way
We used a little section of the West Windermere Way last year, and this year we walked all the way to Lakeside and back; a 15km round trip.
I was a little sceptical about the walking route veering off to a dogleg through Finsthwaite, which adds a little distance and elevation. But it was absolutely beautiful, and we really enjoyed that section of the route. Particularly when we were able to stop for a bite to eat at a park bench just as we entered some of the forestry land between Finsthwaite and Lakeside.
Blencathra
On our climbs of Helvellyn via Striding Edge and Scafell Pike $daughter0 really enjoyed the scrambles. That led to the ‘Best Grade 1 Scrambles in the Lake District‘ listicle, and Blencathra via Sharp Edge seemed the obvious choice for our next climb.
The climb was a lot of fun, and the views from the summit were outstanding.
We descended via Halls Fell Ridge, which is billed as another scramble but wasn’t anything like Sharp Edge. Though greater challenges lay ahead on a surprisingly tricky crevasse on the otherwise very pedestrian path running parallel to the A66.
CoMaps
I’ve used the Ordinance Survey Maps app for the last few years, but it seems to keep getting worse. This year I switched to CoMaps, which is based on OpenStreetMap, and it was excellent :) Easy to read, works offline, simple to get distance to a point, and lots more. Given that it’s free, and strong on privacy it gets a big thumbs up from me :)
LARQ bottle
GitHub kindly gave me a LARQ PureVis Bottle a few years ago and I really wish I’d had it with me on the Scafell climb as I ended up needing to top up from a stream. The ‘adventure mode’ UV purification would have given me extra confidence to drink that water.
This time around I didn’t need to get any stream water. But it was nice to know that I could make it safe(r) if I needed to; and in every other respect the LARQ bottle was excellent in terms of form factor (fits in the car cup holders and the pockets on my rucksack) and capacity (740ml is more than my other bottles).
RNEC Reunion
The parts of my Navy training that I most fondly remember happened at the Royal Navy Engineering College (RNEC) at Manadon just outside of Plymouth. Sadly it was shut down 30y ago, but that was an excuse for getting folk back together. It was great to see some old shipmates, and hopefully it’s going to become a regular thing going forward.
Doppelganger
At a local Humanists meeting about conspiracy theories I asked “who’s writing good stuff about this (apart from Renee DiResta and Cory Doctorow)” and Prof Tarik Kochi suggested Naomi Klein’s ‘Doppelganger‘. I listened to the audiobook, and it’s a really good exploration of the current (mis)information landscape, and touched a lot on what I call ‘Filter Failure at the Outrage Factory‘.
Urs Hölzle
I’ve know of Urs and his work for many years so I leapt at the chance to join him when I was invited to an ‘exclusive Developer Breakfast & Fireside Chat’. Of course ‘exclusive’ isn’t the same as ‘intimate’ so I didn’t actually get to meet or chat with Urs, but at least I had a spot near to him.
It was really refreshing to hear his pragmatism around AI adoption, and I loved his advice along the lines of “if you’re overwhelmed trying to keep track of stuff day to day then give it three weeks and see what’s still around”.
Solar Diary
Another sunnier July than the year before :)

I don’t know what happened on the 15th, as I was up in the Lakes, but something weird as the data logger seemed to only record up to 0900.
Filed under: monthly_update | 1 Comment
Tags: Blencathra, CoMaps, dachshund, Doppelganger, ffof, Lake District, LARQ, Manadon, pupdate, reunion, RNEC, scramble, Sharp Edge, solar, Urs Hölzle, West Windermere Way
Last week my former colleague Doug Todd asked a question about recording decisions on BlueSky:
Of course I replied suggesting Architecture Decision Records (ADRs), with a pointer to the at_protocol GitHub repo where we use them.
A few days back Doug demoed how he’s using ADRs with his coding assistant (Claude and Claude Code), and I feel like this is going to transform the uptake of the approach. It’s such an obviously good way to provide context to a coding assistant – enough structure to ensure key points are addressed, but in natural language, which is perfect for things based on Large Language Models (LLMs).
ADRs right now might be an ‘elite’ team thing (in DORA speak), but I can see them becoming part of a boilerplate approach to working with AI coding assistants. That probably becomes more important as we shift to agent swarm approaches[1], where you’re effectively managing a team, which (back in the human world) is exactly the sort of environment that ADRs were created for.
Note
[1] It feels like my LinkedIn feed these days is 10% stuff from rUv where friends are commenting on his adventures with agent swarms using ‘claude-flow‘. I’ve been intruiged by Adrian Cockcroft’s comments that working with swarms is more like managing a team (than being an individual contributor), and that the code produced might be as important as the bytecode or machine language that we get compilers (e.g. something that we approximately never actually need to look at).
Filed under: architecture, code, software, technology | 1 Comment
Tags: ADR, ADRs, AI, architecture, Claude, coding assistant, decision, LLM
Milo was back at North Downs Specialist Referrals today for his second scan since finishing his third (modified) ‘CHOP’ chemotherapy protocol. Amazingly he’s still looking clear, which means this is now the longest period of remission since he started treatment :)
Our fingers will be crossed for the next scan in a couple of months time, but meanwhile he gets to enjoy the summer without any vet visits.
Past parts:
Filed under: MiloCancerDiary | 2 Comments
Tags: chemo, chemotherapy, CHOP, lymphoma, remission, scan
June 2025
Pupdate
There’s been a bumper crop of raspberries this year, which has kept the boys entertained..
Berlin
Google’s I/O Connect event was in Berlin once again, which provided a good chance to catch up with various communities and some of the product folk.
I also took the chance to grab dinner with some local ex-pat friends. The food, drink, weather and company were all great :)
Computer sheds
The retro meetup group returned to Jim Austin’s Computer Sheds, this time for an extended visit, as Jim let us start at 11am. Even with the extra hours it still felt like we barely scratched the surface of the place.
I was very happy to find some T9000 Transputers.
Beacon Down
We ended up with something of a wine lake after hosting a party at a local restaurant, all picked by co-owner Alicia Sandeman. Every bottle has been great, but my favourite was Beacon Down‘s Blanc de Blancs 2017. So I planned on visiting the vineyard once tours were running again.
That time came around on midsummer’s day, and it was perfect day for seeing the vines (and beautiful surrounding countryside).
Co-owner Paul put on an amazing tour. Whenever I do these things it’s always great to meet people who are passionate and expert about their product. Paul takes it to another level. I don’t think I’ve met a geekier wine geek, and it also made clear why their wine tastes so good. The preparation and attention to detail come through in the glass.
The picnic was also excellent, and all the better for a glass of Riesling to wash it down.
BLE caberQU
When I first heard about the BLE caberQU USB-C cable tester I was gutted I’d missed the original Kickstarter campaign, but glad I was able to order one. I’ve accumulated a bunch of USB-C cables, and it’s hard to keep track of which is supposed to be able to do what.
Unfortunately when the tester arrived it was telling me that almost every cable I had was USB2 data and 15W for charging. Even the cables I regularly use for laptop charging, and others from reputable brands that claim to be 60W.
No E-Markers
It turned out that all except for two ‘fancy’ cables I have don’t have E-Markers, so the rest represent the minimal configuration of USB2 data (480Mbps) and 3A power delivery (60W). The caberQU can’t reliably measure the difference between (say) a 20W cable and a 60W cable, so the device errs on caution by stating 15W.
I reached out to the support email and creator Peter Traunmüller got back to me saying:
The 15W (5V@3A) rating means that there is no eMarker in the cable, but the cable has a good resistance and the necessary pins are connected. The standard calls for 60W (20V@3A), but there is no proper way to verify this without the eMarker confirming this and we’re airing on the side of safety.
After trying a debug firmware on my unit Peter also kindly sent me another tester.
Treedix tester
Meanwhile I read Terence Eden’s review of the Treedix USB Cable tester, and got one of those too. It has a wider selection of ports than the caberQU, but is otherwise less impressive. Anyway… it gave me the same results as before, for both the regular cables and my couple of fancy ones.
FlexiFone
I’m constantly frustrated by poor cell coverage. When walking to the station, or in town. On train rides to London, but also in many parts of London. Over the years I’ve tried all the networks (or at least MVNOs running on them); but what about all the networks at once? That’s what FlexiFone does.
It’s positioned as a backup solution, but I don’t use huge amounts of data, so I’ve been running their eSIM as my primary data plan with their 5GB for £8/mo tier.
It’s definitely a bit better on the train to London, but everywhere else it shows that the problem is terrible coverage from all the operators, and not just any one that I might be signed up to :(
There’s also the issue that their egress IPs don’t geolocate correctly, which can make some apps think you’re in foreign parts (and refuse to let you confirm an order – looking at you KFC :( ).
After a month I think I’m prepared to call this experiment a failure. But I’ll see how I get on in the Lake District next month, where data for mapping apps can be super important.
Solar diary
It’s been warm and generally dry, but not always sunny, so not the best June for Solar.

Filed under: monthly_update | Leave a Comment
Tags: Beacon Down, Berlin, BLE caberQU, caberQU, dachshund, E-Marker, eSIM, FlexiFone, pupdate, retro, solar, tester, transputer, Treedix, USB-C, vineyard, wine
Dart binaries in Python packages
TL;DR
PyPI provides a neat way of distributing binaries from other languages, and Python venvs make it easy to run different versions side by side. This post takes a look at how to do that with Dart, and the next steps necessary to do a proper job of it.
Background
A few days ago I wrote about Using a Python venv to run different versions of CMake, which works because the CMake binaries are poured into a Python package that’s hosted on the Python Package Index (PyPI)[1].
CMake isn’t the only thing that’s distributed that way. Zizmor is a Rust tool for analysing GitHub Actions that offers PyPI as an installation option (perhaps because its author William Woodruff had a big hand in creating the trusted publisher mechanism for PyPI). Pull the thread on Zizmor, and it leads to Maturin, a tool specifically for putting Rust stuff into Python packages, with a whole bunch of projects using it.
CMake can also be used to build Python packages with py-build-cmake.
There’s more… Simon Willison wrote “Bundling binary tools in Python wheels” when he discovered he could get Zig from PyPI.
Why?
- The Dart (and Flutter) package manager pub.dev is source code only, and doesn’t deal with binaries[3].
- Python venvs provide a nice way to run different versions of the same binaries side by side.
- I’m hopeful that Python packaging provides a stepping stone to apt packages on Kali (and maybe Ubuntu, Debian etc.) as there’s a mature process and tooling for Python stuff, but I’ve not yet fully unpicked whether binaries are (re)created from source or downloaded from PyPI.
Example repo
After some experimentation I threw together a test repo: cpswan/dart_echo_py. The key pieces are:
build.sh
A simple script that compiles the Dart source in the src directory and creates binaries in bin. Then runs python -m build to create packages in the dist directory.
pyproject.toml
This provides all the project metadata that’s used by python -m build to construct a package.
Most importantly the [project.scripts] section provides the entry points to the binaries so that they’re presented on the path for whatever (virtual) environment the package is installed into.
__init.py__
This provides a wrapper around the binaries so that command line arguments are passed into the correct binary in the place where it’s been installed.
Todo
So far I’ve got the bare bones working, but there are a few more things I need to get straightened out before I start putting packages onto proper PyPI rather than TestPyPI:
Multi-arch
The simple build script creates binaries on whatever platform it runs on (Linux x64 in my case) and packages them up into a wheel named dart_echo_py-0.1.5-py3-none-any.whl. That py3-none-any suffix is incorrect, as the binary is very definitely not platform independent. The correct suffix is (something like) manylinux_2_12_x86_64.manylinux2010_x86_64, but I should probably also be building binaries for the other Dart AOT platforms. Arm64 is now easy given that Dart 3.8 does cross compilation, but armv7 and riscv64 are also in reach (if I do builds in Docker).
It should also be possible to target musl based environments (like Alpine) using dart-musl.
Source without binary pollution
When I look at the source tarball created by python -m build it also includes the binaries :(
Automation
A simple build script works for a single architecture build, but to support multi architectures it’s going to make sense to use some automation, which naturally takes me to GitHub actions.
And once the build process is automated that opens the door to build attestations for SLSA etc. so that the resulting packages have some provenance.
It should also be possible to ditch Twine in favour of trusted publishing to PyPI.
Notes
[1] Pronounced ‘pie pee eye’ by those in the know. PyPy ‘pie pie’ is another Python thing altogether.
[2] I could have used that with Dart, but I didn’t want to add to the complexity and confusion by bringing in another tool.
[3] This makes perfect sense in the context of Dart mostly being used for Flutter, and Flutter apps mostly ending up in the Apple App Store and Google Play.
Filed under: Dart | Leave a Comment
Tags: binary, Dart, musl, package, PyPI, python, wheel
Dealing with Policy Debt
TL;DR
Start writing down why decisions are made. Future you may thank you. Future other person who’s wondering what you were thinking may also thank you.
Then keep a dependency graph of the things impacted by the decision. It will help unravel what gets woven around it.
Background
I was at an excellent AFCEA event last night where former GCHQ CTO Gaven Smith CB gave a presentation “There’s nothing artificial about intelligence and security”[1].
Gaven allowed plenty of time for Q&A, and as we got towards the end of that the questions converged on a common challenge:
How do we innovate within the confines of existing governance structures?
This immediately got me thinking about policy debt, something I’ve written about here before, and a common topic for discussion on the Tech Debt Burndown podcast that I do with Nick Selby[2]
What can be done?
My previous post was frankly weak on this question, and I’ve had a few more years to think about it.
What were they thinking?
Sometimes it’s obvious why a piece of policy is there. A law was passed. A regulatory framework came into effect. There’s a good trail of breadcrumbs in the references.
Other times… not so much.
Which is why it’s important to write down why. So when the shifting sands that we built things on have changed we can come back and figure out if the original premise is still valid.
To misquote a common saying about trees:
The best time to start recording decisions was 20 years ago. The second best time is now.
Who did we tell?
Once a policy is in place it starts interacting with compliance obligations. Auditors will check boxes because the policy is there, and there’s evidence from a control framework that it’s being properly enacted.
So if we want to change something we need to figure out the dependency graph of those compliance obligations. Can a revised policy with new controls also satisfy those obligations? Maybe; but we can only reason about those things if the graph is understood. Without it we’re left guessing, or worse sent off on a treasure hunt to figure things out retrospectively. That’s a lot of work, and not much fun, which is an obvious source of inertia.
Have you seen good tools for this?
I encourage the use of decision logs (and particularly architectural decision records [ADRs]) to keep track of the why? But I’ve not seen much in the way of managing the dependency graph.
I think compliance bus (as opposed to compliance projects) approaches that I’ve seen in some banks are helpful. But more so in an assumed accretive environment rather than one where there’s active effort to undo the sins of the past.
Notes
[1] Refreshingly it was a lot less about AI than the present zeitgeist might have implied.
[2] Season 3 is in the can and almost ready to hit the wires. I hope…
Filed under: security, strategy, technology | 1 Comment
Tags: ADRs, AFCEA, Agile, architecture, change, compliance, culture, debt, decisions, innovation, policy
Sometimes I need an older or newer version of CMake to the one installed by the system package manager on whatever I’m using, and I’ve found using a Python venv provides an easy way to do that. It’s all facilitated by the fact that CMake is a PyPI package [1].
For example, my Kubuntu desktop presently has CMake 4.0.2, as I installed it as a snap, which is very up to date. But (for now) anything that I try to build that includes cJSON fails, because it specifies CMake 3(.0) and CMake 4 is only compatible back to 3.5 [2].
First I need to create and activate a venv[3,4]:
uv venv cmake3.31.6
source cmake3.31.6/bin/activate
NB not all of the patch releases seem to make it to PyPI, so 3.31.7 isn’t there
Then install CMake and verify that I have the expected version:
uv pip install cmake==3.31.6
cmake --version
I can then go off and do my build :) The venv helpfully adds (cmake3.31.6) to my prompt, so I know what’s going on.
The example above is for an older CMake, but I’ve also used the same approach to get a newer CMake.
Notes
[1] Simon Willison has an excellent blog post “Bundling binary tools in Python wheels” about how Zig is packaged on PyPI.
[2] I opened an issue on this before finding that there’s a PR already open :/
[3] I have a habit of keeping my venvs in ~/python/venvs/ but I get that this isn’t necessarily part of Python orthodoxy.
[4] I’m using uv here for creating the venv and installing into it rather than the old school `python -m venv` and `pip install`.
Filed under: howto | Leave a Comment
Tags: CMake, python, uv, venv
May 2025
Pupdate
The fair weather has (mostly) continued, which allowed for some nice long walks.
Milo turned four at the start of the month :)
Brussels
The end of the month brought the half term holiday, and Mrs S wanted to spend the first weekend away somewhere. Brussels quickly made the top of the list after my great time there for FOSDEM back in February. We went by train, which got us there and back with minimal fuss, and stayed in Hotel9 – right next door to where I stayed last time (and very close to Centraal station).
The highlight of the trip was dinner a La Table de Mus, which delivered a 6 course tasting menu (and wine flight) that was easily one of the best meals of my life. I’ll definitely visit again next time I’m in the city; I may have to plan another trip just so I can go back there…
We also both really enjoyed doing a Belgian Chocolate Workshop where we were taught how to temper chocolate and turn it into pralines.
It was also nice to wander around the city, see the sights, and enjoy a few beers and cocktails.
Andor
I’ve been a Star Wars fan since the first film in ’77. So of course I’ve been watching Andor, and I really enjoyed the first season.
Season 2 took things to an entirely new level. Easily the best thing that’s ever been done in the franchise, and quite possibly some of the best TV ever made.
The way some episodes captured the banality of evil in the mundanity of life as an Imperial bootlicker was incredible. But there was also some great action, and they did a brilliant job of filling in some plot gaps.
I can only hope that the same production values and attention to detail make it into future parts of the franchise.
I also totally got an ear worm with the “Niamos” techno track at the Chandrilla wedding, and I wasn’t alone.
Careless people
I might never have heard of “Careless People” if it wasn’t for Meta’s clumsy attempt to block its promotion leading to an inevitable Streisand effect.
Cory Doctorow has an excellent review on his blog, so I won’t rehash the points he made there, other than to say I also really enjoyed Sarah Wynn-Williams narration of the audiobook. Did I learn anything from the book, not really; but it was nevertheless entertaining.
What did surprise me was the Nick Clegg shaped hole in the narrative. Given the nature of Wynn-Williams’s role, and what Clegg was supposed to be doing I’d have thought that he’d have at least got a mention. His notional replacement Joel Kaplan is one of the starring characters. I smell lawfare, and the long shadow of English libel law.
Blurb
I blurbed my first book :)
Jamie Dobson asked me to review his “Visionaries, Rebels and Machines” (affiliate link), and I really enjoyed it. His editor went with this comment:

That’s not quite what I’d originally said, which was:
Covering a lot of ground to explain how we ended up with cloud and AI, I particularly enjoyed the focus on the leadership approaches taken by the people who made things happen. The Talent Density chapter is delicious.
Adding:
Or in the spirit of less is more, you might simply want to go with: “The Talent Density chapter is delicious.”
But I’m delighted that the book is out there (soon), and I’m looking forward to collaborating with Jamie on future projects.
Solar Diary
Given how warm and sunny it’s been I wasn’t surprised that this May was better than last, but weirdly not as good as 2023 :/

Filed under: monthly_update | Leave a Comment
Tags: Andor, blurb, Brussles, Careless People, chocolate, Jamie Dobson, La Table de Mus, Miniature Dachshund, Niamos, Nick Clegg, pupdate, Sarah Wynn-Williams, solar, Star Wars, Visionaries Rebels and Machines
Battery Bother
TL;DR
I was foolish to believe that paying a premium for a battery with a 5y guarantee would actually get me a battery that lasted 5y :(
Background
The original battery in my 2010 XC60 died after a little over 5y. I replaced it with an Exide EA852 from Tayna that lasted a bit over 4.7y, so a few months past its 4y guarantee.
It was Oct 2020, so still the midst of Covid craziness, and the XC60 was $wife’s daily driver and needed to be reliable. So I splashed out on a Halfords Yuasa battery with a 5y guarantee as I was able to collect it from the store a few miles away.
Fail, but the wrong sort
I got back from Florida last month to find a car that wouldn’t start, so I had to break out the booster pack. Even after a full charge it was only a few weeks until it failed again.
I got a Topdon battery tester that was telling me it needed replacement.
First visit to Halfords
I took the car to Halfords, and explained the situation then had to wait for somebody to do the test. Whilst waiting I saw this chart:
Hardly very confidence inspiring – essentially a list of reasons why they’ll wriggle out of providing a replacement. After some waiting around whilst they served other customers they attached a Yuasa branded testing machine which apparently reported the battery as OK.
“Did you charge the battery?” – well yes, I did, as I wanted the car to run. “Maybe bring it back next time it’s flat”.
Second visit to Halfords
I didn’t have to wait too long for the car to fail to start again. My tester was even more sure of the need to replace:
I jumped the car with the booster again and headed over to Halfords. Their tester also showed REPLACE, followed by Warranty Rejected.
I expressed my dissatisfaction with the situation – paying a premium for a 5y battery that hadn’t lasted 5y. But apparently I’d been holding it wrong, or driving it wrong, or something like that. The warranty only covers ‘manufacturing defects’ or ‘cell failures’, and a battery with a 5y guarantee isn’t actually guaranteed to last 5y.
Apparently I should put it on a smart charger every week or so, just like all the other perfectly normal people do all the time :/
I did not buy another battery from Halfords. They gave me a boost and I took the car home and ordered another Exide EA852. It was a nightmare to fit, as the bolt for the retaining bracket had rusted into the captive nut in the battery box :( I guess it’s going to be 4.7(ish) years until I need to deal with this stuff again (assuming I keep the car that long).
Filed under: could_do_better, grumble | Leave a Comment
Tags: battery, Exide, guarantee, Halfords, Volvo, warranty, XC60, Yuasa




















