Wednesday, 4 February, 2026

Tom Loosemore (LinkedIn warning) on how he vibe coded a useful app in no time at all:

It really was – and is – that easy. That said, under the bonnet Replit has written a horridly inaccessible, unsupportable, unextendable hairball of JavaScript. It’s more of a toy than a product.

#

Monday, 2 February, 2026

Dave Richardson at Newark and Sherwood District Council – Nine Councils. One Message. A playbook for Multi‑Council Digital Collaboration:

When all nine councils across Nottingham and Nottinghamshire were tasked with communicating the complexities of local government reorganisation (LGR), it was clear that traditional, council‑by‑council messaging wouldn’t be enough. Residents needed clarity. Communications teams needed speed. And every authority needed a neutral, trusted space to share information.

#

Mike Gallagher – In public : Notes on working in the open:

The phrase “make things open: it makes things better” gets tossed around a lot and sounds simple, but I think it encapsulates a profound set of ideas that define what is specific to working in the public sector. We need to continue to sing this song so that future generations know what we mean and why we mean it.

#

Friday, 30 January, 2026

📅 Weeknote w/e Friday 30 January 2026

Wallis the cat

January has felt like a looooong month, and I haven’t really enjoyed it. Doesn’t feel like I am remotely up to speed after the festive break, still! So tired. So very tired.

This week’s worky highlights:

  • Getting some of the info-gov stuff sorted for clients using Skillstats – DPIAs and that sort of thing. Slightly dull but really important.
  • We are ever closer to the launch of the LGR DDaT Playbook, so that is fun. Looking forward to finding out what people make of it, and what they think we ought to work on next.
  • Plenty of signups happening for LGRCamp, which is nice to see.
  • Had a lovely meetup of the LocaliseLive! crowd. Heard some great stories of how different councils are making use of technology in a quiet, efficient but innovative way.
  • Nice chat with Neilly and his colleagues at the BFI to see if they could use Skillstats to help them baseline their various digital capability building efforts.

Not really work stuff:

  • Managed to go a week with just posting on this blog and not tweaking anything on it, which is, I think, a result.
  • Chatted with some learning and development folk reminded me of the really good bit of Learning Pool when I worked there some 15 years ago: the catalogue of shared e-learning that councils had access to. LP is a very different beast now and not much interested in local gov, which is a shame. More of a shame is that there are now few councils sharing this kind of content and instead having to but it individually or create it themselves. Someone (huh) should bring the shared library back!
  • Nick reminded me of the existence of GovGroups, and I gave it a quick spring clean. Worth checking out if you need a simple online group for something.

Media consumption:

  • We had never watched CItizen Kane so have started that. Also halfway through Netflix Damon/Affleck number The Rip which I am liking more than anyone else.
  • Now that the new series of Traitors has finished, we have started watching it, because binging.
  • Have started Until I find You by John Irving. I think I have read it before, as bits feel familiar, but that could just be the usual Irving wrestling, unreliable memory, weird sex, odd family dynamics stuff. It’s good, but then I really like his stuff.
#📅 Weeknote w/e Friday 30 January 2026

Mahad Kalam – The UK paid £4.1 million for a bookmarks site:

The UK Government recently unveiled its ‘AI Skills Hub’, which wants to provide 10 million workers with AI skills by 2030. The main site was delivered by PwC for the low, low price of.. £4.1 million (~$5,657,000).

It is not good. Like, at all – the UI is insanely bad and it’s clear that this was just a vibecoded site (to be fair, this is the AI Skills Hub, but c’mon, where is the pride in your work? I would be ashamed to even release this as a prototype!)

Also on this, Scotty Quilter – The UK Government’s AI Skills Hub: A Critical Analysis:

On 28 January 2026, the UK Government launched an expanded AI Skills Hub with the ambitious goal of upskilling 10 million workers by 2030. Backed by £27 million in public funding and partnerships with 25+ organisations, this initiative has been presented as Britain’s answer to the AI skills crisis. However, a closer examination reveals fundamental flaws in both design and execution that risk undermining the very goals the programme seeks to achieve.

#

Wednesday, 28 January, 2026

Am finding the WP Reset plugin useful, particularly at the start of a project where I might be trying lots of different stuff out. Quickly takes a site back to the bare bones, clearing out the database and so on, to give you a fresh start.

#

Carl Haggerty – Introducing the Chrysalis Work:

Working in a council right now can feel a lot like being inside a chrysalis. The old shape of things is still visible – job titles, structures, budgets, habits – but much of what we relied on no longer quite fits, and what’s emerging isn’t yet clear.

The language of “transformation” is everywhere. New operating models, corporate programmes, refreshed strategies, renamed projects – on paper it looks and sounds like big change. But when I tune into what it actually feels like inside, most of what has been labelled “transformation” has been far more modest: service‑by‑service tweaks, done at pace, layered onto old structures, old habits and the same silos that quietly shape everything.

#

Monday, 26 January, 2026

John Gruber reports on the new version of OmniOutliner (6) which includes a featured called Omni Links:

OmniOutliner has always been document-based, and version 6 continues to be. There are advantages and disadvantages to both models, but one of the advantages to library-based apps is that they more easily allow the developer to create custom URL schemes to link to items in the app’s library. Omni Links is an ambitious solution to bring that to document-based apps. Omni Links let you copy URLs that link not just to an OmniOutliner document, but to any specific row within an OmniOutliner document. And you can paste those URLs into any app you want (like, say, Apple Notes or Things, or events in your calendar app). From the perspective of other apps, they’re just URLs that start with omnioutliner://. They’re not based on anything as simplistic as a file’s pathname. They’re a robust way to link to a unique document, or a specific row within that document. Create an Omni Link on your Mac, and that link will work on your iPhone or iPad too — or vice versa. This is a very complex problem to solve, but Omni Links delivers on the age-old promise of “It just works”, abstracting all the complexity.

I’ve been using OmniOutliner for years, to help structure longer documents and put ideas into some kind of order. Am going to have to try this out, because I’m hoping it will let me link to external documents from within an outline – for example to where I am writing up the thing listed in the outline. I know what I mean anyway.

There’s another Mac app which might do something vaguely similar called Hookmark, which I have never gotten round to checking out properly.

#

📅 Weeknote w/e Friday 23 January 2026

Blogging has been a little light this week. Just not that much stuff to link to, and I’ve been in a headspace where I’ve not had too many share-worthy thoughts or ideas. I’ve been tired – maybe that’s the reason.

I also didn’t post this on Friday but left it til the following Monday! Silly David.

This week’s worky highlights:

  • Some more great chats with people about Skillstats, which fills me with hope that this might be a thing and eventually contribute to me being able to retire at some point in the next few decades (an increasing concern as the years pass…!)
  • A lovely chat with Marcus Rees-Harris. We definitely have met at some point, we are sure, but it was lovely to have a proper chat with someone I have been connected to online for some time. He is thriving in a new role, and it was great to see.
  • Been working with Nick on LGR Camp, which is now open for registration.

Not really work stuff:

  • Had a nice discussion over email with Giles Turnbull about finding files in MacOS (I suggested trying out HoudahSpot and Find any File)

Media consumption:

  • Finished the Pirates of the Caribbean series of films. Fourth was very poor, I thought, the fifth and final one slightly better.
  • Watched The War of the Worlds (the Tom Cruise one) again with the family and found it kind of ok but also weirdly low stakes.
  • Have found the Past, Present, Future podcast presented by David Runciman really interesting and it makes a break from all the football ones I otherwise listen to.
#📅 Weeknote w/e Friday 23 January 2026

Tuesday, 20 January, 2026

Laura Czapiewski – Why human trust shapes AI success:

The psychology of digital has never been more important than now, in the age of AI. There are countless examples of where AI has proved to be far more reliable than humans in performing certain tasks, but people don’t trust it. It is somehow more palatable to accept human error than that of machines. We should never disregard this when designing AI solutions. It may not be a technical requirement, but the human need is just as important. We should never only consider the accuracy of AI models when evaluating its success.

#

Monday, 19 January, 2026

Government customer services to be modernised with help of industry experts:

The government is launching CustomerFirst, a new unit within the Department for Science, Innovation and Technology, to modernise public services and improve the experience for millions of people who rely on them.

Am sure there’s a few councils that could share experience of ‘customer first’ programmes. About 15 years’ worth!

#

A roadmap for modern digital government:

Our plan to build a modern digital government that works for you – making life easier, driving growth and delivering smarter, more efficient public services

#

Friday, 16 January, 2026

📅 Weeknote w/e Friday 16 January 2026

Let’s see how long I can keep this up for!

This week’s worky highlights:

  • We are recruting for two big roles at Luton
  • Also at Luton, we have identified 5 big areas of work that we need some more investment in to make them happen, so have been planning the development of business cases to support those.
  • We are making good progress towards the first release of content in the LGR DDaT playbook. Izy is leaving us to go on maternity leave and is a huge loss, but we heard about how her role will be covered in future and that was very reassuring!
  • Chatting with Nick Hill about LGRCamp – an event he is planning to bring everyone together to talk about the digital bits of LGR, which will be a great day and one I am looking forward to!
  • Made some serious progress with Skillstats – I now have my first properly paying customer to join the two others that are sort of paying (but as part of wider consultancy pieces of work).
  • I also have got to the point where the cyber, digital, data, and technology specialist skills assessment is more or less complete. This will, I think, be really helpful for areas going through local government reorganisation in particular – but also any organisation wanting to baseline the specialist CDDaT skillset within their teams
  • Had a natter with Red Hat’s Johnny Williams, who was lots of fun as well as being super knowledgeable. A great contact to have made.

Not really work stuff:

Media consumption:

  • Tracy and I have started Stranger Things from scratch so we can remember it all before tackling the new series.
  • We watched Top Gun with the kids, as well as the two Robert Downey Jr Sherlock Holmes films, which were a bit meh. Catch Me If You Can with Tom Hanks and Leonardo di Caprio was more fun.
  • Am working my way through The Revolutionists by Jason Burke in the 5 minutes between getting in bed and falling asleep. It’s very good and am frustrated that my limited reading time is making it feel a bit like a slog – which it isn’t!
#📅 Weeknote w/e Friday 16 January 2026

Fixed an issue in my Tidycal appointment booking thingy, where Teams meetings were being booked but no meeting link provided. It was a simple case of disconnecting the accounts and then reconnecting them (yup, turn it off and on again, basically). Not a biggie but I’ve had to do it several times now, so might look for another solution.

#

Thursday, 15 January, 2026

Wow – Microsoft Copilot blamed by Chief Constable for Maccabi Tel Aviv ban:

The incident and subsequent review have reignited debates about police decision-making, community engagement, and the balance between public safety and fairness in policing high-profile events. It has also highlighted the hallucination risks posed by AI technologies such as Microsoft Copilot if not used properly. West Midlands Police has pledged to improve its processes.

So much to unpack there.

#

Now I’m wondering whether I should just put everything pre-2026 into an ‘Archive’ category and just start afresh from this year…

A though just occurred – part of the reason why the categories are in a mess is probably because tags didn’t exist in WordPress until 2007, so multiple categories on posts was a regular thing in the early days.

#

Recategorising over 3,000 blog posts

I have been frustrated with the state of the categories on this blog for some years now. That’s right – years. This site has been going in one form or another for over 20 years – the first post being in 2004 – and there’re over 3,000 posts on here in total.

Over that time, category use in WordPress has been variable. This has resulted in a morass of categories, which I am never quite sure which to choose when posting.

So, I wanted to find a way to recategorise everything in a reasonably efficient way, and thought with a mix of Google’s Gemini LLM tool and some choice WordPress plugins, I might be able to get it done.

Delete the old categories

First step – after backing everything up of course – was to remove all the categories I am currently using (there were hundreds). To do this I used the free WP Bulk Delete plugin, which was very easy. I then deactivated and uninstalled the plugin to keep things neat.

Export post data

Next, I used the free version of WP All Export to produce a CSV file of every post (the post ID, title, and content) on the blog. That done, again the plugin was deactivated and uninstalled.

Define the new categories

Now I needed to come up with a set of categories to cover the content in the blog. Being lazy, I decided to ask Gemini to do it for me. Here’s the prompt, which I got to after a bit of back and forth with Gemini:

**Role:** You are an expert WordPress Archivist and Data Taxonomist.

**Context:** I have uploaded a CSV containing 3,031 blog posts from a 20-year archive. The current categorization is a mess. I need to completely restructure the site content into a clean, modern, and mutually exclusive taxonomy.

**Goal:** We need to assign one single, perfect category to every post in this CSV so I can import it back into WordPress.

1. Scan the “Title” and “Content/Excerpt” columns of the uploaded CSV to understand the breadth of topics covered over the last 20 years.

2. Propose a list of **12-15 high-level categories**.
– These must be mutually exclusive (no overlap).
– They must be comprehensive (cover all topics in the file).
– Use simple, standard naming conventions (e.g., “Technology,” “Travel,” “Personal,” not “My Cool Tech Stuff”).

3. Output this proposed list to me with a brief explanation of what belongs in each.

This produced 12 suggested categories, which seemed fine to me.

  • Digital Government

    Content: Public sector digital transformation, local government (councils), civic tech, and policy discussions.

  • Social Media & Community

    Content: Analysis of platforms (Twitter, Facebook, etc.), online community management, and social networking trends.

  • Technology & Software

    Content: General tech news, software reviews (e.g., Zoho, Gmail), hardware, and internet tools.

  • Web & WordPress

    Content: Web design, development, specific WordPress plugins/themes, and CMS discussions.

  • Blogging & Content

    Content: The practice of blogging, writing, online journalism, and digital media trends.

  • Open Data & Transparency

    Content: Open government data, freedom of information, transparency, and data standards (“Mash the State”).

  • Productivity & Work

    Content: Workflow tips, remote work, collaboration tools, and personal effectiveness.

  • Events & Speaking

    Content: Conference write-ups, presentation slides, workshops, and event announcements.

  • Links

    Content: Your archive contains hundreds of “Links for [Date]” and “Bookmarks” posts. These are distinct resources and deserve their own home.

  • Daily Notes

    Content: Short, micro-blog style updates, status messages, and quick thoughts (e.g., “Five for Friday”).

  • Reviews

    Content: Specific reviews of books, products, or services that don’t fit strictly into “Technology.”

  • Personal

    Content: Life updates, off-topic reflections (e.g., “Woken by a cat”), and general musings.

Match posts to new categories

Now I needed to match each of my 3,000+ posts with one of these 12 categories and list them in a CSV file.

Gemini suggested a Python script, so I fired up a terminal window and ran this script:

import pandas as pd

# 1. Load your CSV
# Make sure the filename matches your export exactly
df = pd.read_csv(‘Posts-Export-2026-January-15-1048.csv’)

# 2. Define the Categories and Keywords
categories = {
“Curated Links”: {
“keywords”: [“links for”, “bookmarks”, “reading list”, “worth reading”, “link dump”, “daily links”],
“weight”: 10
},
“Digital Government”: {
“keywords”: [“council”, “localgov”, “gov”, “civic”, “policy”, “public sector”, “democracy”, “e-gov”, “citizen”, “government”, “public service”, “whitehall”, “civil service”],
“weight”: 1
},
“Social Media & Community”: {
“keywords”: [“twitter”, “facebook”, “social media”, “community”, “network”, “platform”, “linkedin”, “instagram”, “social network”, “online community”],
“weight”: 1
},
“Web & WordPress”: {
“keywords”: [“wordpress”, “plugin”, “theme”, “css”, “html”, “web design”, “cms”, “blog engine”, “php”, “javascript”, “code”, “developer”, “site”, “website”],
“weight”: 1
},
“Technology & Software”: {
“keywords”: [“google”, “apple”, “software”, “app”, “iphone”, “mac”, “tech”, “tool”, “hardware”, “zoho”, “gmail”, “browser”, “firefox”, “chrome”, “device”, “mobile”, “internet”],
“weight”: 1
},
“Open Data & Transparency”: {
“keywords”: [“open data”, “foi”, “transparency”, “mashup”, “dataset”, “freedom of information”, “data”, “ckan”, “statistics”],
“weight”: 1
},
“Productivity & Work”: {
“keywords”: [“productivity”, “work”, “gtd”, “email”, “inbox”, “office”, “remote”, “collaboration”, “workflow”, “management”, “meeting”, “career”],
“weight”: 1
},
“Events & Speaking”: {
“keywords”: [“conference”, “camp”, “barcamp”, “presentation”, “slides”, “event”, “talk”, “session”, “meetup”, “workshop”, “govcamp”, “speaking”],
“weight”: 1
},
“Blogging & Content”: {
“keywords”: [“blogging”, “writing”, “journalism”, “media”, “post”, “content”, “publish”, “blogger”, “feed”, “rss”],
“weight”: 1
},
“Reviews”: {
“keywords”: [“review”, “book review”, “product review”, “thoughts on”, “impression”],
“weight”: 2
},
“Daily Notes”: {
“keywords”: [“five for friday”, “update”, “status”, “note”, “snippet”, “aside”, “quick update”],
“weight”: 1
},
“Personal”: {
“keywords”: [“holiday”, “cat”, “home”, “life”, “family”, “personal”, “thoughts”, “rant”, “weekend”, “music”, “film”],
“weight”: 1
}
}

def categorize_post(row):
title = str(row[‘Title’]).lower()
content = str(row[‘Content’]).lower()

# Priority Rule: Curated Links
if any(k in title for k in categories[“Curated Links”][“keywords”]):
return “Curated Links”

# Priority Rule: Daily Notes (Short content check)
if len(content) < 200 and "href" not in content and len(title) < 30: return "Daily Notes" # Scoring Logic scores = {cat: 0 for cat in categories} def score_text(text, multiplier=1): for cat, data in categories.items(): for keyword in data['keywords']: if keyword in text: scores[cat] += (1 * multiplier * data.get('weight', 1)) # Title gets 3x weight score_text(title, multiplier=3) # Check first 1000 chars of content score_text(content[:1000], multiplier=1) best_cat = max(scores, key=scores.get) if scores[best_cat] == 0: return "Personal" return best_cat # 3. Apply the function df['New_Category'] = df.apply(categorize_post, axis=1) # 4. Save the result output_filename = 'Categorized_Posts_Archive.csv' df[['id', 'New_Category']].to_csv(output_filename, index=False) print(f"Success! File saved as: {output_filename}")

This worked as expected and spat out a new CSV file listing post ids next to the new category.

Apply new categories to posts in WordPress

Now I needed to get WordPress to look at this CSV file and update the content database so that each post is assigned to the right new category. To do that I used WP All Import, which I paid for – although I’m not sure I actually needed to.

This stage of the process was the most frustrating as WP All Import is necessarily quite fiddly, and it took about 5 goes to get it to do what I wanted. But I got there in the end.

The result

Well, in a sense, success! In the space of less than an hour I have recategorised over 3,000 posts on my blog into just 12 different categories.

On the other hand… it turns out I hate these categories and the ways Gemini associated them with posts is often really stupid.

The learning

Using Gemini made this possible. On my own, I couldn’t have done it. This is 100% true of the Python scripting, which I have zero knowledge of, but also it would have taken me ages to figure out the steps I needed to take (am sure they seem obvious to others!).

However, I will inevitably redo the process, with categories and definitions I have produced myself, to try and get better results.

For now, though, it’ll do.

#Recategorising over 3,000 blog posts

Some major reworking of this blog over the last few days. Dramatically simplified things – sadly the micropost format that Steph helped me build didn’t make the cut.

Instead I am making use of the default WordPress ‘asides’ post format to add what used to be microposts. This has helped me cut down the number of plugins running on the site significantly.

Also, I removed Google Analytics because I never looked at it, and don’t really care how many people read this anyway.

I also replaced the theme, switching from GeneratePress to Blocksy – which I know is a bit bloated but which I understand and can oo things with.

I’ve added a bit to the About page to describe how the blog works, plugins and custom code used, and so on, if you are sufficiently interested to look.

#

Wednesday, 14 January, 2026

Roger Swannell – Getting agile governance right:

In a traditional waterfall or stage-gated development process quality assurance and approval checks happen towards the end of the work. It makes sense if you’re optimising for efficiency as all the quality check governance happens when the development is as close to it’s live and finished state as possible. But it’s based on the assumption that it’s possible to know ahead of the development work all the possible considerations and implications, which approval checks can refer to and confirm met or not.

The agile perspective is that its not possible to know all those implications ahead of doing the development work and so the better approach is to get smaller feedback more regularly and respond to it more quickly. This is better than waiting until near the end because changes are easier to make whilst development work is in progress. This approach optimises for effectiveness where getting it right is more important than doing it quickly.

#