Sadder Than Fiction

Duration

Podcast Version

This post is also available as a podcast. Listen here, download for later, or subscribe wherever you consume podcasts.

On a number of occasions over the first two decades of this century I’ve attempted to write a particular short story with a science fiction/alternate history feel. Now, I’ve given up on it, and that’s… fine.

Fiction

The story’s taken several forms over the years, but the theme’s always been the same: a crazy narrative spun by an isolated society turns out, incredibly, to be true. But ultimately the people who discover that fact choose to keep it a secret because the flawed lie they live in is preferable to the instability and chaos that they fear could result. It taps into ideas about conspiracy theories, hidden worlds, and the choices we make when we have to choose between living authentically or living comfortably.

Screenshot from Obsidian, showing a Writing folder containing Suicide of a Time Traveller, Compression, Everybody Remembers That Show, and (selected) The Korean Incident.
Guess this Obsidian note is off to the “Never” folder, now.

In its most-concrete form, the story covered the political aftermath of the capture by the DPRK of a fishing boat that (allegedly) drifted into North Korean waters1. The North Korea of the story represents the country at its most isolationist and mysterious, and the captured trawler crew are surprised to experience at Pyongyang a socialist utopia supported by futuristic technology. It turns out that North Korea’s in-universe propaganda is true: they really are an advanced self-reliant nation whose message of peace is being distorted by Western imperialist leaders. Insofar as the truth is known in the West, it’s suppressed for fear that the Korean model represents a democratic, post-scarcity future that threatens to undermine the power of the oligarchs of the world.

When the boat and those aboard it are repatriated with the assumption that they will act as ambassadors to the outside world, the crew are subjected to interrogations and cajoling by their home nations. They mustn’t talk about what they saw North of the 38th parallel, they’re told, with threats of imprisonment and violence if they do and financial inducements offered for their compliance. But in the end, the most-effective message for getting the wayward fisherfolk on side is their realisation that the world isn’t ready for the truth. In a dialogue between the imprisoned seafarers, they agree that they should take the bribes and return quietly to their families, not for their own sake but because they believe that telling their story would lead to a terrible war between two equally-matched parties: a small nation armed with futuristic sci-fi weapons, on one side, and the might of the nuclear superpowers of the rest of the world.

As the sun sets behind growing clouds, a small fishing vessel flying a red flag glides across a moderately-smooth ocean.

As a final twist, it’s revealed that the captain of the vessel was actually a spy, aware of the truth the entire time, who allowed the boat to go off-course with an aim of gathering information on the North Korean situation. The story finishes with the captain, having been instrumental in persuading their crew not to share what they saw, wavering in their confidence, and possibly being implied to be the author of the story.

Re-reading my notes and drafted content, I’ve got to admit that it’s got a certain feel of… Dr. Strangelove discovers Wakanda? Or maybe more like the Pueblo incident set in the world of They Live.2 It might’ve been fun to finish, someday, but now it’s not.

Sadder

That nod to Dr. Strangelove is apt, because my aim was to write something which looked farcically at the nature of political competition on a global scale, in a world in which the zaniest possible conspiracy theory turned out to be true. Strangelove used the existence of a Project Sundial-style doomsday device as the surprise truth; I was using the idea that DPRK propaganda might actually be more-honest than the narratives of its rivals3.

George C. Scott playing General Turgidson in Dr. Strangelove.
“Gee, I wish we had one of them doomsday machines,” was funnier when nuclear annihilation was the only existential threat we were routinely talking about. Nowadays saying it sounds like it carries a bit of Farnsworth’s dejected “I don’t want to live on this planet anymore” energy.

In my off-and-on-again long-running effort to pen the story, I last made any real effort back in around 2015-2016. Since then, the entire concept hasn’t been funny any more. Today, the story would be less farce than lampoonery, and not in a good way.

When I first envisaged the concept of the story, researching conspiracy theories meant laughing at Flat Earthers and picking holes in the arguments of the proponents of a “moon landing hoax”. For the most part, conspiracy theories seemed ridiculous, but not dangerous4. But somewhere along the way from then to now, conspiracy theories started becoming more… mainstream?

Woman wearing a tinfoil hat, thinking "if it looks like a duck and it quacks like a duck, it's probably... part of Bill Gates' secret drone army, delivering microchips for the Reptilians to put into our vaccines!"
Don’tcha miss when conspiracy theorists were mostly harmless idiots?

And that made the story… not fun, any more. Convicted felon Donald Trump loves to claim that a deep state cabal of leftists and big tech companies are suppressing his voice. Or that immigrants are eating pets. Or that the announcement of Osama bin Laden’s death was timed carefully so that people would watch news about that rather than Trump’s show Celebrity Apprentice5.

It turns out that my comedy villain – the leader of the “free” world who leverages enormous power to lie to and manipulate everybody – isn’t a laughing matter any more.

Perhaps I should try my hand at writing bleak, dystopian fiction instead.

Footnotes

1 Like this incident in 2009, perhaps, although there are lots of similar examples before and since.

2 In my notes somewhere I’ve got a concept that I never explored for the story which was that North Korea is under the control of a benevolent alien species trying to uplift humanity, while much of the rest of the developed world is under the influence of a malicious alien species who’re using their position to push humans to terraform Earth into something more-suited to their needs. So maybe like The Forge of God but with a climate change message? I never really worked on this idea though because it felt like I was weaving too many concepts into one tiny narrative.

3 Both are bonkers-crazy ideas, but Project Sundial is, sadly, more-believable: Kurzgesagt did a fun video about it recently.

4 Obviously I know there are exceptions and I’m speaking from a position of privilege. For a long while, for example, conspiracy theories relating to holocaust denialism have caused real harm to people. And of course there’s for a long while been actual damage caused by folks who (loudly) subscribe to false beliefs about HIV, or 9/11, or Sandy Hook, and countless others.

5 This is the kind of conspiracy theory that should be funny: idiot who bitches about claimed birthplace of president annoys that president enough that he times a battle with a wanted terrorist, so that the terrorist’s death will coincide with the timeslot of the idiot’s TV programme. But somehow, the way that politics has gone lately, especially in the USA, means that it’s not funny any more. Easily-disprovable conspiracy theories were amusing when they were the territory of crazy fringe groups; once they get tens of thousands of (armed, militant) believers, they go from being an amusement to being a dangerous cult.

× × × ×

XPath Scraping AdamKoszary.co.uk

Adam Koszary – whom I worked alongside at the Bodleian – the social media specialist who brought the “absolute unit” meme to the masses, started blogging earlier (again?) this year. Yay!

But he’s completely neglected to put an RSS feed on hew new blog. Boo!

Dan, wearing a VR headset, sits in an office environment, watched by Adam.
People who saw Adam and I work together might have questioned the degree to which it counted as “work”, but that’s another story.

I’ve talked at length about how I use FreshRSS‘s “XPath Scraping” feature (for Bev’s blog, Far Side, Forward, new Far Side, and Vmail, among others), but earlier this week somebody left a comment to ask me more about how I test and debug my XPath scrapers. Given that I now need to add one for Adam’s blog, I’m in a wonderful position to walk you through it!

Setting up and debugging your FreshRSS XPath Scraper

Okay, so here’s Adam’s blog. I’ve checked, and there’s no RSS feed1, so it’s time to start planning my XPath Scraper. The first thing I want to do is to find some way of identifying the “posts” on the page. Sometimes people use solid, logical id="..." and class="..." attributes, but I’m going to need to use my browser’s “Inspect Element” tool to check:

Screenshot showing Inspect Element in use on Adam's blog.
If you’re really lucky, the site you’re scraping uses an established microformat like h-feed. No such luck here, though…

The next thing that’s worth checking is that the content you’re inspecting is delivered with the page, and not loaded later using JavaScript. FreshRSS’s XPath Scraper works with the raw HTML/XML that’s delivered to it; it doesn’t execute any JavaScript2, so I use “View Source” and quickly search to see that the content I’m looking for is there, too.

HTML source code showing id="posts" highlighted.
New developers are sometimes surprised to see how different View Source and Inspect Element’s output can be3. This looks pretty promising, though.
Now it’s time to try and write some XPath queries. Luckily, your browser is here to help! If you pop up your debug console, you’ll discover that you’re probably got a predefined function, $x(...), to which you can path a string containing an XPath query and get back a NodeList of the element.

First, I’ll try getting all of the links inside the #posts section by running $x( '//*[@id="posts"]//a' )  –

A browser's debug console executes $x('//*[@id="posts"]//a') , and gets 14 results.
Once you’ve run a query, you can expand the resulting array and hover over any element in it to see it highlighted on the page. This can be used to help check that you’ve found what you’re looking for (and nothing else).
In my first attempt, I discovered that I got not only all the posts… but also the “tags” at the top. That’s no good. Inspecting the URLs of each, I noticed that the post URLs all contained /posts/, so I filtered my query down to $x( '//*[@id="posts"]//a[contains(@href, "/posts/")]' ) which gave me the expected number of results. That gives me //*[@id="posts"]//a[contains(@href, "/posts/")] as the XPath query for “news items”:
FreshRSS XPath feed configuration page showing my new query in the appropriate field.
I like to add the rules I’ve learned to my FreshRSS configuration as I go along, to remind me what I still need to find.

Obviously, this link points to the full post, so that tells me I can put ./@href as the “item link” attribute in FreshRSS.

Next, it’s time to see what other metadata I can extract from each post to help FreshRSS along:

Inspecting the post titles shows that they’re <h3>s. Running $x( '//*[@id="posts"]//a[contains(@href, "/posts/")]//h3' ) gets them. Within FreshRSS, everything “within” a post is referenced relative to the post, so I convert this to descendant::h3 for my “XPath (relative to item) for Item Title:” attribute.

An XPath query identifying the titles of the posts.
I was pleased to see that Adam’s using a good accessible heading cascade. This also makes my XPathing easier!

Inspecting within the post summary content, it’s… not great for scraping. The elements class names don’t correspond to what the content is4: it looks like Adam’s using a utility class library5.

Everything within the <a> that we’ve found is wrapped in a <div class="flex-grow">. But within that, I can see that the date is directly inside a <p>, whereas the summary content is inside a <p> within a <div class="mb-2">. I don’t want my code to be too fragile, and I think it’s more-likely that Adam will change the class names than the structure, so I’ll tie my queries to the structure. That gives me descendant::div/p for the date and descendant::div/div/p for the “content”. All that remains is to tell FreshRSS that Adam’s using F j, Y as his date format (long month name, space, short day number, comma, space, long year number) so it knows how to parse those dates, and the feed’s good.

If it’s wrong and I need to change anything in FreshRSS, the “Reload Articles” button can be used to force it to re-load the most-recent X posts. Useful if you need to tweak things. In my case, I’ve also set the “Article CSS selector on original website” field to article so that the full post text can be pulled into my reader rather than having to visit the actual site. Then I’m done!

Adam's blog post "Content of the Week #7: 200 Creators" viewed in FreshRSS.
Yet another blog I can read entirely from my feed reader, despite the fact that it doesn’t offer a “feed”.

Takeaways

  • Use Inspect Element to find the elements you want to scrape for.
  • Use $x( ... ) to test your XPath expressions.
  • Remember that most of FreshRSS’s fields ask for expressions relative to the news item and adapt accordingly.
  • If you make a mistake, use “Reload Articles” to pull them again.

Footnotes

1 Boo again!

2 If you need a scraper than executes JavaScript, you need something more-sophisticated. I used to use my very own RSSey for this purpose but nowadays XPath Scraping is sufficient so I don’t bother any more, but RSSey might be a good starting point for you if you really need that kind of power!

3 If you’ve not had the chance to think about it before: View Source shows you the actual HTML code that was delivered from the web server to your browser. This then gets interpreted by the browser to generate the DOM, which might result in changes to it: for example, invalid elements might be removed, ambiguous markup will have an interpretation applied, and so on. The DOM might further change as a result of JavaScript code, browser plugins, and whatever else. When you Inspect Element, you’re looking at the DOM (represented “as if” it were HTML), not the actual underlying HTML

4 The date isn’t in a <time> element nor does it have a class like .post--date or similar.

5 I’ll spare you my thoughts on utility class libraries for now, but they’re… not positive. I can see why people use them, and I’ve even used them myself before… but I don’t think they’re a good thing.

× × × × × × ×

Sabbatical Magic

A couple of weeks ago, I kicked off my first sabbatical since starting at Automattic a little over five years ago1.

Dan sits in front of two laptops (one of which shows a photo of an echidna for some reason), in a meeting room full of casually-dressed volunteers.
The first weekend of my sabbatical might have set the tone for a lot of the charity hacking that will follow, being dominated by a Three Rings volunteering weekend.

The first fortnight of my sabbatical has consisted of:

  1. Three Rings CIC’s AGM weekend and lots of planning for the future of the organisation and how we make it a better place to volunteer, and better value for our charity users,
  2. building a first draft of Three Rings’ new server architecture, which turns out to mostly work but still needs some energy thrown at it,
  3. a geohashing expedition with the dog, and
  4. a family holiday to Catalonia, Spain.
Dan, Ruth, and JTA with their children and a tour guide called Julie, enjoying churros in a Barcelona cafe.
You’d be amazed how many churros these children can put away.

The trip to Spain followed a model for European family breaks that we first tried in Paris last year2, but was extended to give us a feel for more of the region than a simple city break would. Ultimately, we ended up in three separate locations:

  1. Barcelona, where we stayed in a wonderful skyscraper hotel with fantastic breakfasts and, after I was able to get enough sleep, explored the obvious touristy bits of the city (e.g. la Sagrada Família3 and other Gaudían architecture, the chocolate museum, the fort at Montjuic, and because it’s me, of course, a widely varied handful of geocaches).
  2. The PortAventura World theme park, whose accommodation was certainly a gear shift after the 5-star hotel we’d come from4 but whose rides kept us and the kids delighted for a couple of days (Shambhala was a particular hit with the eldest kid and me).
  3. A villa in el Vilosell – a village of only 190 people – at which the kids mostly played in the outdoor pool (despite the sometimes pouring rain) but we did get the chance to explore the local area a little. Also, of course, some geocaching: some local caches are 1-2 years old and yet had so few finds that I was able to be only the tenth or even just the third person to sign the logbooks!
Dan and the kids atop the remains of a castle tower.
All that remains of the Castell del Vilosell is part of a single tower, but it affords excellent views over the rest of the village as well as being home to a wonderfully-placed geocache.

I’d known – planned – that my sabbatical would involve a little travel. But it wasn’t until we began to approach the end of this holiday that I noticed a difference that a holiday on sabbatical introduces, compared to any other holiday I’ve taken during my adult life…

Perhaps because of the roles I’ve been appointed to – or maybe as a result of my personality – I’ve typically found that my enjoyment of the last day or two of a week-long trip are marred somewhat by intrusive thoughts of the work week to follow.

Dan sits at a laptop in a hotel bar, a view of Barcelona out of the window behind him, a beer bottle alongside him.
I’m not saying that I didn’t write code while on holiday. I totally did, and I open-sourced it too. But programming feels different when your paycheque doesn’t depend on it.

If I’m back to my normal day job on Monday, then by Saturday I’m already thinking about what I’ll need to be working on (in my case, it’s usually whatever I left unfinished right before I left), contemplating logging-in to work to check my email or Slack, and so on5.

But this weekend, that wasn’t even an option. I’ve consciously and deliberately cut myself off from my usual channels of work communication, and I’ve been very disciplined about not turning any of them back on. And even if I did… my team aren’t expecting me to sign into work for about another 11 weeks anyway!

Dan, standing in an airport departure lounge, mimes "mind blown" to the camera.
🤯🤯🤯

Monday and Tuesday are going to mostly be split between looking after the children, and voluntary work for Three Rings (gotta fix that new server architecture!). Probably. Wednesday? Who knows.

That’s my first taste of the magic of a sabbatical, I think. The observation that it’s possible to unplug from my work life and, y’know, not start thinking about it right away again.

Maybe I can use this as a vehicle to a more healthy work/life balance next year.

Footnotes

1 A sabbatical is a perk offered to Automatticians giving them three months off (with full pay and benefits) after each five years of work. Mine coincidentally came hot on the tail of my last meetup and soon after a whole lot of drama and a major shake-up, so it was a very welcome time to take a break… although of course it’s been impossible to completely detach from bits of the drama that have spilled out onto the open Web!

2 I didn’t get around to writing about Paris, but I did write about how the hotel we stayed at introduced our eldest, and by proxy re-introduced me, to Wonder Boy, ultimately leading to me building an arcade cabinet on which I finally, beat the game, 35 years after first playing it.

3 Whose construction has come on a lot since the last time I toured inside it.

4 Although alcohol helped with that.

5 I’m fully aware that this is a symptom of poor work/life balance, but I’ve got two decades of ingrained bad habits working against me now; don’t expect me to change overnight!

× × × × ×

Hero of Alexandria

A little under two millennia ago1 there lived in the Egyptian city of Alexandria a Greek mathematician and inventor named Hero2, and he was a total badass who invented things that you probably thought came way later, and come up with mathematical tricks that we still use to this day3.

Inventions

Illustration of an aeolipile, showing a heated sphere or cylinder of water spraying steam in two different directions, causing it to rotate.
If you know of Hero’s inventions because of his aeolipile4,known as “Hero’s engine”, I’ve got bad news: it was probably actually invented by his predecessor Vitruvius. But Hero did come up with a way to use the technique to make a pneumatic temple door that automatically opened when you lit the fires alongside it.
Hero is variably credited with inventing, in some cases way earlier than you’re expecting:
  • automatic doors (powered either by pressure plates or by lit fires),
  • vending machines, which used the weight of a dispensed coin to open a valve and dispense holy water,
  • windmills (by which I mean wind-powered stationary machines capable of performing useful work),
  • the force pump – this is the kind of mechanism found in traditional freestanding village water pumps – for use in a fire engine,
  • float-valve and water-pressure based equilibrium pumps, like those found in many toilet cisterns, and
  • a programmable robot: this one’s a personal favourite of mine because it’s particularly unexpected – Hero’s cart was a three-wheeled contraption whose wheels were turned by a falling weight pulling on a rope, but the rope could be knotted and looped back over itself (here’s a modern reimplementation using Lego) to form a programmed path for the cart
Illustration showing mechanism of action of a fire-powered automatic door: heated air expands to displace water into a vessel whose now-increased weight pulls ropes wrapped around two wheels which pull open a pair of temple doors.
It’s just headcanon, but I choose to believe that the reason Hero needed to invent the fire extinguisher might have involved the number of “attempting to make fire do work” inventions that he came up with.

Mathematics

If you know of Hero because of his mathematical work, it’s probably thanks to his pre-trigonometric work on calculating the area of a triangle based only on the lengths of its sides.

But I’ve always been more-impressed by the iterative5 mechanism he come up with by which to derive square roots. Here’s how it works:

  1. Let n be the number for which you want to determine the square root.
  2. Let g1 be a guess as to the square root. You can pick any number; it can be 1.
  3. Derive a better guess g2 using g2 = ( g1 + n / g1 ) / 2.
  4. Repeat until gN gN-1, for a level of precision acceptable to you. The algorithm will be accurate to within S significant figures if the derivation of each guess is rounded to S + 1 significant figures.

That’s a bit of a dry way to tell you about it, though. Wouldn’t it be better if I showed you?

Put any number from 1 to 999 into the box below and see a series of gradually-improving guesses as to its square root6.

Interactive Widget

(There should be an interactive widget here. Maybe you’ve got Javascript disabled, or maybe you’re reading this post in your RSS reader?)

Maths is just one of the reasons Hero is my hero. And now perhaps he can be your hero too.

Footnotes

1 We’re not certain when he was born or died, but he wrote about witnessing a solar eclipse that we know to have occurred in 62 CE, which narrows it down a lot.

2 Or Heron. It’s not entirely certain how his name was pronounced, but I think “Hero” sounds cooler so I’m going with that.

3 Why am I blogging about this? Well: it turns out that every time I speak on some eccentric subject, like my favourite magic trick, I come off stage with like three other ideas for presentations, which leads to an exponential growth about “things I’d like to talk about”. Indeed, my OGN talk on the history of Oxford’s telephone area code was one of three options I offered to the crowd to vote on at the end of my previous OGN talk! In any case, I’ve decided that the only way I can get all of this superfluity of ideas out of my head might be to blog about them, instead; so here’s such a post!

4 If the diagram’s not clear, here’s the essence of the aeolipile: it’s a basic steam reaction-engine, in which steam forces its way out of a container in two different directions, causing the container to spin on its axis like a catherine wheel.

5 You can also conceive of it as a recursive algorithm if that’s your poison, for example if you’re one of those functional purists who always seem somehow happier about their lives than I am with mine. What’s that about, anyway? I tried to teach myself functional programming in the hope of reaching their Zen-like level of peace and contentment, but while I got reasonably good at the paradigm, I didn’t find enlightenment. Nowadays I’m of the opinion that it’s not that functional programming leads to self-actualisation so much as people capable of finding a level of joy in simplicity are drawn to functional programming. Or something. Anyway: what was I talking about? Oh, yeah: Hero of Alexandria’s derivation of square roots.

6 Why yes, of course I open-sourced this code.

× ×

Hour of Ambiguity

Here in my hotel room, high above Barcelona, I woke up. It was still dark outside, so I looked to my phone – sitting in its charging cradle – as a bedside clock. It told me that the time was 02:30 (01:30 back home), and that the sun would rise at 07:17.

But how long would it be, until then?

Daylight savings time is harmonised across Europe by EU Directive 2000/84/EC1, but for all the good this harmonisation achieves it does not perfectly remove every ambiguity from questions like this. That it’s 02:30 doesn’t by itself tell me whether or not tonight’s daylight savings change has been applied!

It could be 00:30 UTC, and still half an hour until the clocks go back, or it could be 01:30 UTC, and the clocks went back half an hour ago. I exist in the “hour of uncertainty”, a brief period that happens once every year2. Right now, I don’t know what time it is.

I remember when it first started to become commonplace to expect digital devices to change their clocks twice a year on your behalf. You’d boot your PC on a morning and it’d pop up a dialog box to let you know what it had done: a helpful affordance that existed primarily, I assume, to discourage you from making the exact same change yourself, duplicating the effort and multiplying the problem. Once, I stayed up late on last Saturday in March to see what happened if the computer was running at the time, and sure enough, the helpful popup appeared as the clocks leapt forward, skipping over sixty minutes in an instant, keeping them like leftovers to be gorged upon later.

Computers don’t do that for us anymore. They still change their clocks, but they do it silently, thanklessly, while we sleep, and we generally don’t give it a second thought.

That helpful dialog that computers used to have had a secondary purpose. Maybe we should bring it back. Not as a popup – heaven knows we’ve got enough of those – but just a subtle subtext at the bottom of the clock screens on our phones. “Daylight savings: clock will change in 30 minutes” or “Daylight savings: clock changed 30 minutes ago”. Such a message could appear for, say, six hours or so before and after our strange biannual ritual, and we might find ourselves more-aware as a result.

Of course, I suppose I could have added UTC to my world clock. Collapsed the waveform. Dispelled the ambiguity. Or just allowed myself to doze off and let the unsleeping computers do their thing while I rested. But instead I typed this, watching as the clock reached 02:59 and then to 02:00. I’d started writing during summertime; I’d finished after it ended, a few minutes… earlier?

Daylight savings time remains a crazy concept.

Footnotes

1 Why yes, I am the kind of nerd who didn’t have to look that up. Why do you ask?

2 In places that observe a one-hour shift for summertime.

My Oldest Article of Clothing

There’s a pretty, lightweight, short-sleeved shirt that I own. If you know me personally, it’s reasonably likely you’ll have seen me wearing it at some point.

Dan wearing an off-white shirt decorated with intricate inky designs reminiscent of dragons.
It’s a perfectly nice casual shirt. And it’s also really quite old.

And I’m confident that it’s the oldest piece of clothing I own. I first got it in the winter of 2001/2002, which makes it a massive 23 years old!

Given that I seem to be incapable of owning clothing without holing it in short order1, why has this shirt lasted so long? Is it imbued with some form of mystical draconic longevity?2

A 23-year-old shirt that’s been worn most months would most-likely already represent good value, but I bought this particular garment second-hand, from a stall in Preston’s Covered Market. For 50 pence! That’s cheap enough that it would have been the best-value shirt I’d ever owned even if it had fallen apart as quickly as my clothes do typically.

That it’s instead lasted over two decades is just… mind-boggling.

Footnotes

1 My socks wear holes within a year or two; my trousers gain crotch tears, possibly as a result of over-aggressive cycling, within a similar timespan; my t-shirts for some reason reliably get holes under the left armpit usually within four years, and so on.

2 With thanks to the Wayback Machine, I found an original web page about my shirt on the designer’s website (in an example of full “early 2000s” web design – look at those image navigation buttons with no alt-text! – as well as other retro touches like being able to order by fax before paying in deutschemarks). They’re still making shirts, I see, although no longer in this design.

×

How I Learned to Enjoy Pickled Onion Monster Munch

Duration

Podcast Version

This post is also available as a podcast. Listen here, download for later, or subscribe wherever you consume podcasts.

Right in time for International Crisp Sandwich Day (St. Crispin’s Day) tomorrow, I’ve taught myself to enjoy Pickled Onion Monster Munch.

Three jars of homemade pickled eggs; one in each of a chilli-spiced vinegar, balsamic vinegar, and white vinegar.
You might reasonably have assumed I’d have already enjoyed pickled onion crisps. After all, I not only enjoy actual pickled onions but also the far more “acquired taste” of pickled eggs, shown.

There’s a need for somebody… anybody… to eat Pickled Onion Monster Munch in our household, because we have a bit of an oversupply. In order to reliably get both of the other flavours that people like (Roast Beef and Flamin’ Hot, respectively), we end up buying multipacks that also contain Pickled Onion flavour, and these unwanted extras pile up in the snack cupboard until we happen to have a houseguest that we can palm them off onto.

Snack cupboard next to a 12-pack of Monster Munch featuring three flavours: Roast Beef, Flamin' Hot, and Pickled Onion.
Yes, I’m aware that there are multipacks of individual flavours, but none of our local supermarkets seem to stock multipacks of Flamin’ Hot, which is objectively the best flavour of Monster Munch and anybody who claims otherwise is wrong.

My entire life, I’ve claimed not to like pickled onion flavour crisps. As a kid, I would only eat salt & vinegar and ready salted flavours, eventually expanding my palate into “meaty” flavours like chicken and roast beef (although never, absolutely never, prawn cocktail). Later, I’d come to also enjoy cheese & onion and variants thereof, and it’s from this that I realise that I’m probably being somewhat irrational.

Because if you think about it: if you want to make a “pickled onion” flavour crisp, what flavouring ingredients would you use? It turns out that most crisp manufacturers use a particular mixture of (a) the ingredient that makes salt & vinegar crisps taste “vinegary” and (b) the ingredient that makes cheese & onion crisps taste “onioney”. So in summary:

  1. I like pickled onions.
  2. I like salt & vinegar crisps, which include an ingredient to make them taste vinegary.
  3. I like cheese & onion crisps, which include an ingredient to make them taste onioney.
  4. Therefore, I ought to like pickled onion crisps, which use two ingredients I like to try to emulate a food I like.
A packet of Pickled Onion Monster Munch, held in a hand.
I should like this. Right?

Maybe that deliberate and conscious thought process is all I need? Maybe that’s it, and just having gone through the reasoning, I will now like pickled onion crisps!

Conveniently, I have a cupboard in my kitchen containing approximately one billion packets of Pickled Onion Monster Munch. So let’s try it out.

The first time I’ve tried a pickled onion flavour crisp in almost 30 years, captured on camera for your amusement.

It turns out they’re okay!

They’re not going to dethrone either of the other two flavours of Monster Munch that we routinely restock on, but at least now I’m in a position where I can do something about our oversupply.

And all it took was stopping to think rationally about it. If only everything were so simple.

× × ×

Bad Names for Servers

Six or seven years ago our eldest child, then a preschooler, drew me a picture of the Internet1. I framed it and I keep it on the landing outside my bedroom – y’know, in case I get lost on the Internet and need a map:

Framed child-drawn picture showing multiple circles, connected by lines, each with a number 0 or 1 in it.
Lots of circles, all connected to one another, passing zeroes and ones around. Around this time she’d observed that I wrote my number zeroes “programmer-style” (crossed) and clearly tried to emulate this, too.

I found myself reminded of this piece of childhood art when she once again helped me with a network map, this weekend.

As I kick off my Automattic sabbatical I’m aiming to spend some of this and next month building a new server architecture for Three Rings. To share my plans, this weekend, I’d been drawing network diagrams showing my fellow volunteers what I was planning to implement. Later, our eldest swooped in and decided to “enhance” the picture with faces and names for each server:

Network diagram but with entities having faces and named Chungus, Atul, Summer, Gwen, Alice, Astrid, and Demmy.
I don’t think she intended it, but she’s made the primary application servers look the grumpiest. This might well fit with my experience of those servers, too.

I noted that she named the read-replica database server Demmy2, after our dog.

French Bulldog with her tongue sticking out.
You might have come across our dog before, if you followed me through Bleptember.

It’s a cute name for a server, but I don’t think I’m going to follow it. The last thing I want is for her to overhear me complaining about some possible future server problem and misinterpret what I’m saying. “Demmy is a bit slow; can you give her a kick,” could easily cause distress, not to mention “Demmy’s dying; can we spin up a replacement?”

I’ll stick to more-conventional server names for this new cluster, I think.

Footnotes

1 She spelled it “the Itnet”, but still: max props to her for thinking “what would he like a picture of… oh; he likes the Internet! I’ll draw him that!”

2 She also drew ears and a snout on the Demmy-server, in case the identity wasn’t clear to me!

× × ×

Nex in CapsulePress

I’ve added Nex support to CapsulePress!

What does that mean?

Screenshot showing DanQ.me homepage via Nex, in Lagrange browser.
Here’s how nex://danq.me/ looks in my favourite desktop Gemini/smolweb browser Lagrange.

Nex is a lightweight Internet protocol reminiscent to me of Spartan (which CapsulePress also supports), but even more lightweight. Without even affordances like host identification, MIME types, response codes, or the expectation that Gemtext might be supported by the client, it’s perhaps more like Gopher than it is like Gemini.

It comes from the ever-entertaining smolweb hub of Nightfall City, whose Web interface clearly states at the top of every page the command you could have run to see that content over the Nex protocol. Lagrange added support for Nex almost a year ago and it’s such a lightweight protocol that I was quickly able to adapt CapsulePress’s implementation of Spartan to support Nex, too.

require 'gserver'
require 'word_wrap'
require 'word_wrap/core_ext'

class NexServer < GServer
  def initialize
    super(
      (ENV['NEX_PORT'] ? ENV['NEX_PORT'].to_i                           : 1900),
      (ENV['NEX_HOST']                                                 || '0.0.0.0'),
      (ENV['NEX_MAX_CONNECTIONS'] ? ENV['NEX_MAX_CONNECTIONS'].to_i : 4)
    )
  end

  def handle(io, req)
    puts "Nex: handling"
    io.print "\r\n"
    req = '/' if req == ''
    if response = CapsulePress.handle(req, 'nex')
      io.print response[:body].wrap(79)
    else
      io.print "Document not found\r\n"
    end
  end

  def serve(io)
    puts "Nex: client connected"
    req = io.gets.strip
    handle(io, req)
  end
end
This is genuinely the entirety of my implementation of my Nex server, atop CapsulePress. And it’s mostly boilerplate.

Why, you might ask? Well, the reasons are the same as all the other standards supported by CapsulePress:

  1. The smolweb is awesome.
  2. Making WordPress into a CMS things it was never meant to do is sorta my jam.
  3. It was a quick win while I waited for the pharmacist to shoot me up with 5G microchips my ‘flu and Covid boosters.

If you want to add Nex onto your CapsulePress, just git pull the latest version, ensure TCP port 1900 isn’t firewalled, and don’t add USE_NEX=false to your environment. That’s all!

×

Firsts and Lasts

Duration

Podcast Version

This post is also available as a podcast. Listen here, download for later, or subscribe wherever you consume podcasts.

A lot of attention is paid, often in retrospect, to the experience of the first times in our lives. The first laugh; the first kiss; the first day at your job1. But for every first, there must inevitably be a last.

I recall a moment when I was… perhaps the age our eldest child is now. As I listened to the bats in our garden, my mother told me about how she couldn’t hear them as clearly as she could when she was my age. The human ear isn’t well-equipped to hear that frequency that bats use, and while children can often pick out the sounds, the ability tends to fade with age.

Face of a bat, hanging upside-down.
“Helloooo? Are you even listening to me?”

This recollection came as I stayed up late the other month to watch the Perseids. I lay in the hammock in our garden under a fabulously clear sky as the sun finished setting, and – after being still and quiet for a time – realised that the local bat colony were out foraging for insects. They flew around and very close to me, and it occurred to me that I couldn’t hear them at all.

There must necessarily have been a “last time” that I heard a bat’s echolocation. I remember a time about ten years ago, at the first house in Oxford of Ruth, JTA and I (along with Paul), standing in the back garden and listening to those high-pitched chirps. But I can’t tell you when the very last time was. At the time it will have felt unremarkable rather than noteworthy.

First times can often be identified contemporaneously. For example: I was able to acknowledge my first time on a looping rollercoaster at the time.

The Tower of Terror, Camelot Theme Park, circa 1990s; a steel rollercoaster track dips in and out of a fibreglass castle structure.
The Tower of Terror at Camelot, circa 1994, was my first looping rollercoaster2. The ride was disassembled in 2000 and, minus its “tower” theming3lived on for a while as Twist ‘N’ Shout at Loudoun Castle in Ayrshire, Scotland before that park shut down. I looked at some recent satellite photography and I’m confident it’s now been demolished.
Last times are often invisible at the time. You don’t see the significance of the everyday and routine except in hindsight.

I wonder what it would be like if we had the same level of consciousness of last times as we did of firsts. How differently might we treat a final phone call to a loved one or the ultimate visit to a special place if we knew, at the time, that there would be no more?

Would such a world be more-comforting, providing closure at every turn? Or would it lead to a paralytic anticipatory grief: “I can’t visit my friend; what if I find out that it’s the last time?”

Footnotes

1 While watching a wooden train toy jiggle down a length of string, reportedly; Sarah Titlow, behind the school outbuilding, circa 1988; and five years ago this week, respectively.

2 Can’t see the loop? It’s inside the tower. A clever bit of design conceals the inversion from outside the ride; also the track later re-enters the fort (on the left of the photo) to “thread the needle” through the centre of the loop. When they were running three trains (two in motion at once) at the proper cadence, it was quite impressive as you’d loop around while a second train went through the middle, and then go through the middle while a third train did the loop!

3 I’m told that the “tower” caught fire during disassembly and was destroyed.

× ×

Meetup Magic

I’ve spent the last week1 in Tulum, on Mexico’s beautiful Yucatan Peninsula, for an Automattic meetup. And as usual for these kinds of work gatherings, it was magical (and, after many recent departures, a welcome opportunity to feel a closer connection to those of us that remain).

Dan and four other men stand around a firepit, in front of a tropical beach and a twilight sky.
Obviously, meeting in-person with my immediate team2 was a specific goal for the event.
Only after deciding the title of this blog post did I spot my own accidental wordplay. I mean that it was metaphorically magical, of course, but there also happened to be more than a little magic performed there too, thanks to yours truly.
Dan standing on stage in front of a seated audience; a screen behind him shows a close-up of his hands holding several playing cards.
I made magic a theme of a “flash talk”. After that ~350 people was a suboptimal audience size for close-up magic and offering to later replicate the trick I was describing in-person to anybody in the room… I ended up performing it many, many more times.

No, I mean that the whole thing felt magical. Like, I’ve discovered, every Automattic meetup I’ve been to has been. But this is perhaps especially true of the larger ones like Vienna last year (where my “flash talk” topic was Finger for WordPress; turns out I love the excuse to listen to other people’s nerdity and fly my own nerd flag a little).

Beautiful sunrise, with reds, oranges, yellows and pinks dappling across the clouds, seen from a Caribbean beach.
There’s plenty of reasons it was a magical trip, as I’ll explain. But after arriving late and exhausted, this view from the doorstep of my bedroom the following morning was a great start. I made a habit of a pre-breakfast swim each morning in the warm Caribbean waters.

Our events team, who are already some of the most thoughtful and considerate planners you might ever meet, had gone above and beyond in their choice of location. The all-inclusive resort they’d booked out for pretty-much our exclusive use was a little isolated and not the kind of place I’d have chosen for a personal holiday. But it provided all of the facilities my team, sibling teams, and division could desire for work, rest and play.

One day, I returned to my room and discovered that in the course of their tidying, the hotel’s housekeeping team had been asked to tidy up any stray charging cables using reusable Automattic-branded cable ties. These are the kinds of nice touches that show how hard our events coordinators think about their work3!

As usual, an Automattic meetup proved to be a series of long but energising days comprising a mixture of directly work-related events, social team-building and networking opportunities, chances for personal growth and to learn or practice skills, and a sweet sprinkling of fun and memorable activities.

Stalactite-strewn cave deeply filled with clear blue water.
A particular treat as a trip to swim through a cenote – caverns formed by sinkhole erosion of the limestone sediment by rainwater, often considered sacred to the Maya – complete with fish, bats, and the ugliest spiders you’ll ever see.4
Harvey Mackay said5 that if you choose a job you love, you’ll never work a day in your life. That might not ring true for me every day of my working life, but it certainly feels significant when I’m at Automattic meetups.
Two men and two women sit around a sticker-covered Macbook laptop, collectively looking at its screen.
Work that feels like fun, and fun that contributes to work? Is that the secret sauce? My colleague Boro and I certainly tried to bring that energy to our workshop on the philosophy of code reviews, pictured.

Our meetups might not feel like “work” (even when they clearly are!), but rather like… I don’t know… a holiday with 400 of the coolest, friendliest, most-interesting people you could ever meet6… which just happens to have an overarching theme of something that you love.

Even the appearance of Hurricane Milton, which briefly threatened chaos to the peninsula before it was determined that its path was definitely dominated by a Florida-ward direction, couldn’t dampen our spirits but did bring us some of the most spectacular fireworks nature has to offer.

Recently-developed changes to strategic priorities, and the departure of a few of our colleagues during the recent aforementioned “realignment”, meant that my “superteam” – my team and its siblings – had a lot to talk about. How can we work better together? How can we best meet the needs of the company while also remaining true to its open-source ideology? What will our relationships with one another and with other parts of the organisation look like in the year to come?

Dan sits with seven other men in an ourdoor bar area, with water trickling down an ornamental wall behind them.
All the best meetings take place in bars, right?

Every morning for a week I’d wake early and walk the soft warm sands and swim in the sea, before meeting with colleagues for breakfast. Then a day of networking and workshops, team-time activities, meetings, and personal development, which gave way to evenings with so much on offer that FOMO was inevitable7.

A group of people lie or sit cross-legged on towels in front of a collection of musical instruments.
I continue to appreciate the ways that Automattic provides the time and space for me to expand my horizons. Whether that’s at one end of a spectrum learning a new technical skill. or at the other sitting-in on a “sound bath”8.
Automattic remains… automaggical to me. As I rapidly approach five years since I started here (more on that later, I promise, because, well: five years is a pretty special anniversary at Automattic…), it’s still the case that routinely I get to learn new things and expand myself while contributing to important and influential pieces of open source software.

Our meetups are merely an intense distillation of what makes Automattic magical on a day-to-day basis.

Dan lies in a hammock under a warm sun, smiling.
At home, I usually start my day with a skim of my RSS reader from bed. But with the sea calling to me, first, each morning of the Tulum meetup, I instead had to suffice with reading my feeds from the nearest available hammock to the beach on my doorstep.

Did I mention that we’re recruiting?

Footnotes

1 Travelling light, as has become my normal.

2 Excluding the two who couldn’t make it in person and the one who’s on parental leave.

3 Another example might be the pronoun pin badges that they made available in various locations, which I’ve written about already.

4 The spiders, which weave long thin strand webs that hang like tinsel from the cave roof, catch and eat mosquitoes, which I’m definitely in favour of.

5 Okay, fine: Harvey Mackey isn’t the original source, and it’s not clear who was.

6 Also, partially-tame trash pandas, which joined iguanas, agouti, sand pipers, and other wildlife around (and sometimes in) our accommodation.

7 I slightly feel like I missed-out by skipping the board gaming, and it sounds like the movie party and the karaoke events were a blast too, but I stand by my choices to drink and dance and perform magic and chat about technology and open source and Star Wars and blogging and music and travel and everything else that I found even the slightest opportunity to connect on with any of the amazing diverse and smart folks with whom I’m fortunate enough to work.

8 While I completely reject the magical thinking espoused by our “sound bath” facilitator, it was still a surprisingly relaxing and meditative experience. It was also a nice chill-out before going off to the higher-energy environment that came next at the poolside bar: drinking cocktails and dancing to the bangin’ tunes being played by our DJ, my colleague Rua.

× × × × × × × ×

We’ll Pay You to Go (so we’re confident in who stays…)

This week has been a wild ride at Automattic. I’ve shared my take on our recent drama already1.

Off the back of all of this, our CEO Matt Mullenweg realised:

It became clear a good chunk of my Automattic colleagues disagreed with me and our actions.

So we decided to design the most generous buy-out package possible, we called it an Alignment Offer: if you resigned before 20:00 UTC on Thursday, October 3, 2024, you would receive $30,000 or six months of salary, whichever is higher.

HR added some extra details to sweeten the deal; we wanted to make it as enticing as possible.

I’ve been asking people to vote with their wallet a lot recently, and this is another example!

This was a really bold move, and gave many people I know pause for consideration. “Quit today, and we’ll pay you six months salary,” could be a pretty high-value deal for some people, and it was offered basically without further restriction2.

A 2008 Havard Business Review article (unpaywalled version) talked about a curious business strategy undertaken by shoe company Zappos:

Every so often, though, I spend time with a company that is so original in its strategy, so determined in its execution, and so transparent in its thinking, that it makes my head spin. Zappos is one of those companies

It’s a hard job, answering phones and talking to customers for hours at a time. So when Zappos hires new employees, it provides a four-week training period that immerses them in the company’s strategy, culture, and obsession with customers. People get paid their full salary during this period.

After a week or so in this immersive experience, though, it’s time for what Zappos calls “The Offer.” The fast-growing company, which works hard to recruit people to join, says to its newest employees: “If you quit today, we will pay you for the amount of time you’ve worked, plus we will offer you a $1,000 bonus.” Zappos actually bribes its new employees to quit!

Bill Taylor (Harvard Business Review)

I’m sure you can see the parallel. What Zappos do routinely and Automattic did this week have a similar outcome

By reducing – not quite removing – the financial incentive to remain, they aim to filter their employees down to only those whose reason for being there is that they believe in what the company does3. They’re trading money for idealism.

The Automattic Creed represented in a series of stylised quotes, as a poster.
Patrick Rauland made this poster of the Automattic Creed (which I’ve written about before) 8 years ago, after having left the company, saying of Automatticians: “they don’t accept the world as it is, they believe in openness & transparency, and they are constantly experimenting and trying new things”.

Buried about half way through the Creed is the line I am more motivated by impact than money, which seems quite fitting. Automattic has always been an idealistic company. This filtering effort helps validate that.

The effect of Automattic’s “if you don’t feel aligned with us, we’ll pay you to leave” offer has been significant: around 159 people – 8.4% of the company – resigned this week. At very short notice, dozens of people I know and have worked with… disappeared from my immediate radar. It’s been… a lot.

I chose to stay. I still believe in Automattic’s mission, and I love my work and the people I do it with. But man… it makes you second-guess yourself when people you know, and respect, and love, and agree with on so many things decide to take a deal like this and… quit4.

Histogram estimating the number of departures by division, which each Automattician shown as a silhouette and Dan (in Woo division) highlighted.
Departures have been experienced across virtually all divisions, but not always proportionally.
(These numbers are my own estimation and might not be entirely accurate.)

There’ve been some real heart-in-throat moments. A close colleague of mine started a message in a way that made me briefly panic that this was a goodbye, and it took until half way through that I realised it was the opposite and I was able to start breathing again.

But I’m hopeful and optimistic that we’ll find our feet, rally our teams, win our battles, and redouble our efforts to make the Web a better place, democratise publishing (and eCommerce!), and do it all with a commitment to open source. There’s tears today, but someday there’ll be happiness again.

Footnotes

1 For which the Internet quickly made me regret my choices, delivering a barrage of personal attacks and straw man arguments, but I was grateful for the people who engaged in meaningful discourse.

2 For example, you could even opt to take the deal if you were on a performance improvement plan, or if you were in your first week of work! If use these examples because I’m pretty confident that both of them occurred.

3 Of course, such a strategy can never be 100% effective, because people’s reasons for remaining with an employer are as diverse as people are.

4 Of course their reasons for leaving are as diverse and multifaceted as others’ reasons for staying might be! I’ve a colleague who spent some time mulling it over not because he isn’t happy working here but because he was close to retirement, for example.

× ×

Digital Dustbusting

tl;dr: I’m tidying up and consolidating my personal hosting; I’ve made a little progress, but I’ve got a way to go – fortunately I’ve got a sabbatical coming up at work!

At the weekend, I kicked-off what will doubtless be a multi-week process of gradually tidying and consolidating some of the disparate digital things I run, around the Internet.

I’ve a long-standing habit of having an idea (e.g. gamebook-making tool Twinebook, lockpicking puzzle game Break Into Us, my Cheating Hangman game, and even FreeDeedPoll.org.uk!), deploying it to one of several servers I run, and then finding it a huge headache when I inevitably need to upgrade or move said server because there’s such an insane diversity of different things that need testing!

Screenshot from Cheating Hangman: I guessed an 'E', but when I guessed an 'O' I was told that there was one (the computer was thinking of 'CLOSE'), but now there isn't because it's switched to a different word that ends with 'E'.
My “cheating hangman” game spun out from my analysis of the hardest words for an optimal player to guess, which was in turn inspired by the late Nick Berry’s examination of optimal strategy.

I can simplify, I figured. So I did.

And in doing so, I rediscovered several old projects I’d neglected or forgotten about. I wonder if anybody’s still using any of them?

Hosting I’ve tidied so far…

  • Cheating Hangman is now hosted by GitHub Pages.
  • DNDle, my Wordle-clone where you have to guess the Dungeons & Dragons 5e monster’s stat block, is now hosted by GitHub Pages. Also, I fixed an issue reported a month ago that meant that I was reporting Giant Scorpions as having a WIS of 19 instead of 9.
  • Abnib, which mostly reminds people of upcoming birthdays and serves as a dumping ground for any Abnib-related shit I produce, is now hosted by GitHub Pages.
  • RockMonkey.org.uk, which doesn’t really do much any more, is now hosted by GitHub Pages.
  • EGXchange, my implementation of a digital wallet for environmentally-friendly cryptocurrency EmmaGoldCoin, which I’ve written about before, is now hosted by GitHub Pages.
  • Sour Grapes, the single-page promo for a (remote) murder mystery party I hosted during a COVID lockdown, is now hosted by GitHub Pages.
  • A convenience-page for giving lost people directions to my house is now hosted by GitHub Pages.
  • Dan Q’s Things is now automatically built on a schedule and hosted by GitHub Pages.
  • Robin’s Improbable Blog, which spun out from 52 Reflect, wasn’t getting enough traffic to justify “proper” hosting so now it sits in a Docker container on my NAS.
  • My μlogger server, which records my location based on pings from my phone, has also moved to my NAS. This has broken Find Dan Q, but I’m not sure if I’ll continue with that in its current form anyway.
  • All of my various domain/subdomain redirects have been consolidated on, or are in the process of moving to, to a tiny Linode/Akamai instance. It’s a super simple plain Nginx server that does virtually nothing except redirect people – this is where I’ll park the domains I register but haven’t found a use for yet, in future.
Screenshot showing EGXchange, saying "everybody has an EGX wallet, log in to yours now".
I was pretty proud of EGXchange.org, but I’ll be first to admit that it’s among the stupider of my throwaway domains.

It turns out GitHub pages is a fine place to host simple, static websites that were open-source already. I’ve been working on improving my understanding of GitHub Actions anyway as part of what I’ve been doing while wearing my work, volunteering, and personal hats, so switching some static build processes like DNDle’s to GitHub Actions was a useful exercise.

Stuff I’m still to tidy…

There’s still a few things I need to tidy up to bring my personal hosting situation under control:

DanQ.me

Screenshot showing this blog post.
You’re looking at it. But later this year, you might be looking at it… elsewhere?

This is the big one, because it’s not just a WordPress blog: it’s also a Gemini, Spartan, and Gopher server (thanks CapsulePress!), a Finger server, a general-purpose host to a stack of complex stuff only some of which is powered by Bloq (my WordPress/PHP integrations): e.g. code to generate the maps that appear on my geopositioned posts, code to integrate with the Fediverse, a whole stack of configuration to make my caching work the way I want, etc.

FreeDeedPoll.org.uk

Right now this is a Ruby/Sinatra application, but I’ve got a (long-running) development branch that will make it run completely in the browser, which will further improve privacy, allow it to run entirely-offline (with a service worker), and provide a basis for new features I’d like to provide down the line. I’m hoping to get to finishing this during my Automattic sabbatical this winter.

Screenshot showing freedeedpoll.org.uk
The website’s basically unchanged for most of a decade and a half, and… umm… it looks it!

A secondary benefit of it becoming browser-based, of course, is that it can be hosted as a static site, which will allow me to move it to GitHub Pages too.

Geohashing.site

When I took over running the world’s geohashing hub from xkcd‘s Randall Munroe (and davean), I flung the site together on whatever hosting I had sitting around at the time, but that’s given me some headaches. The outbound email transfer agent is a pain, for example, and it’s a hard host on which to apply upgrades. So I want to get that moved somewhere better this winter too. It’s actually the last site left running on its current host, so it’ll save me a little money to get it moved, too!

Screenshot from Geohashing.site's homepage.
Geohashing’s one of the strangest communities I’m honoured to be a part of. So it’d be nice to treat their primary website to a little more respect and attention.

My FreshRSS instance

Right now I run this on my NAS, but that turns out to be a pain sometimes because it means that if my home Internet goes down (e.g. thanks to a power cut, which we have from time to time), I lose access to the first and last place I go on the Internet! So I’d quite like to move that to somewhere on the open Internet. Haven’t worked out where yet.

Next steps

It’s felt good so far to consolidate and tidy-up my personal web hosting (and to rediscover some old projects I’d forgotten about). There’s work still to do, but I’m expecting to spend a few months not-doing-my-day-job very soon, so I’m hoping to find the opportunity to finish it then!

× × × × ×

What if Emails were Multilingual?

Multilingual emails

Back when I was a student in Aberystwyth, I used to receive a lot of bilingual emails from the University and its departments1. I was reminded of this when I received an email this week from CACert, delivered in both English and German.

Top part of an email from CACert, which begins with the text "German translation below / Deutsche Uebersetzung weiter unten".
Simply putting one language after the other isn’t terribly exciting. Although to be fair, the content of this email wasn’t terribly exciting either.

Wouldn’t it be great if there were some kind of standard for multilingual emails? Your email client or device would maintain an “order of preference” of the languages that you speak, and you’d automatically be shown the content in those languages, starting with the one you’re most-fluent in and working down.

The Web’s already got this functionality2, and people have been sending multilingual emails for much longer than they’ve been developing multilingual websites3!

Enter RFC8255!

It turns out that this is a (theoretically) solved problem. RFC8255 defines a mechanism for breaking an email into multiple different languages in a way that a machine can understand and that ought to be backwards-compatible (so people whose email software doesn’t support it yet can still “get by”). Here’s how it works:

  1. You add a Content-Type: multipart/multilingual header with a defined boundary marker, just like you would for any other email with multiple “parts” (e.g. with a HTML and a plain text version, or with text content and an attachment).
  2. The first section is just a text/plain (or similar) part, containing e.g. some text to explain that this is a multilingual email, and if you’re seeing this then your email client probably doesn’t support them, but you should just be able to scroll down (or else look at the attachments) to find content in the language you read.
  3. Subsequent sections have:
    • Content-Disposition: inline, so that for most people using non-compliant email software they can just scroll down until they find a language they can read,
    • Content-Type: message/rfc822, so that an entire message can be embedded (which allows other headers, like the Subject:, to be translated too),
    • a Content-Language: header, specifying the ISO code of the language represented in that section, and
    • optionally, a Content-Translation-Type: header, specifying either original (this is the original text), human (this was translated by a human), or automated (this was the result of machine translation) – this could be used to let a user say e.g. that they’d prefer a human translation to an automated one, given the choice between two second languages.

Let’s see a sample email:

Content-Type: multipart/multilingual;
 boundary=10867f6c7dbe49b2cfc5bf880d888ce1c1f898730130e7968995bea413a65664
To: <b24571@danq.me>
From: <rfc8255test-noreply@danq.link>
Subject: Does your email client support RFC8255?
Mime-Version: 1.0
Date: Fri, 27 Sep 2024 10:06:56 +0000

--10867f6c7dbe49b2cfc5bf880d888ce1c1f898730130e7968995bea413a65664
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset=utf-8

This is a multipart message in multiple languages. Each part says the
same thing but in a different language. If your email client supports
RFC8255, you will see this message in your preferred language out of
those available. Otherwise, you will probably see each language after
one another or else each language in a separate attachment.

--10867f6c7dbe49b2cfc5bf880d888ce1c1f898730130e7968995bea413a65664
Content-Disposition: inline
Content-Type: message/rfc822
Content-Language: en
Content-Translation-Type: original

Subject: Does your email client support RFC8255?
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0

RFC8255 is a standard for sending email in multiple languages. This
is the original email in English. It is embedded alongside the same
content in a number of other languages.

--10867f6c7dbe49b2cfc5bf880d888ce1c1f898730130e7968995bea413a65664
Content-Disposition: inline
Content-Type: message/rfc822
Content-Language: fr
Content-Translation-Type: automated

Subject: Votre client de messagerie prend-il en charge la norme RFC8255?
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0

RFC8255 est une norme permettant d'envoyer des courriers
électroniques dans plusieurs langues. Le présent est le courriel
traduit en français. Il est intégré à côté du même contenu contenu
dans un certain nombre d'autres langues.

--10867f6c7dbe49b2cfc5bf880d888ce1c1f898730130e7968995bea413a65664--
Why not copy-paste this into a raw email and see how your favourite email client handles it! That’ll be fun, right?

Can I use it?

That proposed standard turns seven years old next month. Sooo… can we start using it?4

Turns out… not so much. I discovered that NeoMutt supports it:

NeoMutt’s implementation is basic, but it works: you can specify a preference order for languages and it respects it, and if you don’t then it shows all of the languages as a series of attachments. It can apparently even be used to author compliant multilingual emails, although I didn’t get around to trying that.

Support in other clients is… variable.

A reasonable number of them don’t understand the multilingual directives but still show the email in a way that doesn’t suck:

Screenshot from Thunderbird, showing each language one after the other.
Mozilla Thunderbird does a respectable job of showing each language’s subject and content, one after another.

Some shoot for the stars but blow up on the launch pad:

Screenshot from GMail, showing each language one after the other, but with a stack of extra headers and an offer to translate it to English for me (even though the English is already there).
GMail displays all the content, but it pretends that the alternate versions are forwarded messages and adds a stack of meaningless blank headers to each. And then offers to translate the result for you, even though the content is already right there in English.

Others still seem to be actively trying to make life harder for you:

ProtonMail’s Web interface shows only the fallback content, putting the remainder into .eml attachments… which is then won’t display, forcing you to download them and find some other email client to look at them in!5

And still others just shit the bed at the idea that you might read an email like this one:

Screenshot from Outlook 365, showing the message "This message might have been moved or deleted".
Outlook 365 does appallingly badly, showing the subject in the title bar, then the words “(No subject)”, then the message “This message might have been removed or deleted”. Just great.

That’s just the clients I’ve tested, but I can’t imagine that others are much different. If you give it a go yourself with something I’ve not tried, then let me know!

I guess this means that standardised multilingual emails might be forever resigned to the “nice to have but it never took off so we went in a different direction” corner of the Internet, along with the <keygen> HTML element and the concept of privacy.

Footnotes

1 I didn’t receive quite as much bilingual email as you might expect, given that the University committed to delivering most of its correspondence in both English and Welsh. But I received a lot more than I do nowadays, for example

2 Although you might not guess it, given how many websites completely ignore your Accept-Language header, even where it’s provided, and simply try to “guess” what language you want using IP geolocation or something, and then require that you find whatever shitty bit of UI they’ve hidden their language selector behind if you want to change it, storing the result in a cookie so it inevitably gets lost and has to be set again the next time you visit.

3 I suppose that if you were sending HTML emails then you might use the lang="..." attribute to mark up different parts of the message as being in different languages. But that doesn’t solve all of the problems, and introduces a couple of fresh ones.

4 If it were a cool new CSS feature, you can guarantee that it’d be supported by every major browser (except probably Safari) by now. But email doesn’t get so much love as the Web, sadly.

5 Worse yet, if you’re using ProtonMail with a third-party client, ProtonMail screws up RFC8255 emails so badly that they don’t even work properly in e.g. NeoMutt any more! ProtonMail swaps the multipart/multilingual content type for multipart/mixed and strips the Content-Language: headers, making the entire email objectively less-useful.

× × × ×

WP Engine’s Three Problems

Duration

Podcast Version

This post is also available as a podcast. Listen here, download for later, or subscribe wherever you consume podcasts.

If you’re active in the WordPress space you’re probably aware that there’s a lot of drama going on right now between (a) WordPress hosting company WP Engine, (b) WordPress hosting company (among quite a few other things) Automattic1, and (c) the WordPress Foundation.

If you’re not aware then, well: do a search across the tech news media to see the latest: any summary I could give you would be out-of-date by the time you read it anyway!

Illustration showing relationships between WordPress and Automattic (licensing trademarks and contributing effort to), between WordPress and WP Engine (the latter profits from the former), and between Automattic and WP Engine (throwing lawsuits at one another).
I tried to draw a better diagram with more of the relevant connections, but it quickly turned into spaghetti.

A declaration of war?

Like others, I’m not sure that the way Matt publicly called-out WP Engine at WCUS was the most-productive way to progress a discussion2.

In particular, I think a lot of the conversation that he kicked off conflates three different aspects of WP Engine’s misbehaviour. That muddies the waters when it comes to having a reasoned conversation about the issue3.

Matt Mullwenweg on stage at WordCamp US 2024, stating how he feels that WP Engine exploits WordPress (to great profit) without contributing back.
I’ve heard Matt speak a number of times, including in person… and I think he did a pretty bad job of expressing the problems with WP Engine during his Q&A at WCUS. In his defence, it sounds like he may have been still trying to negotiate a better way forward until the very second he walked on stage that day.

I don’t think WP Engine is a particularly good company, and I personally wouldn’t use them for WordPress hosting. That’s not a new opinion for me: I wouldn’t have used them last year or the year before, or the year before that either. And I broadly agree with what I think Matt tried to say, although not necessarily with the way he said it or the platform he chose to say it upon.

Misdeeds

As I see it, WP Engine’s potential misdeeds fall into three distinct categories: moral, ethical4, and legal.

Morally: don’t take without giving back

Matt observes that since WP Engine’s acquisition by huge tech-company-investor Silver Lake, WP Engine have made enormous profits from selling WordPress hosting as a service (and nothing else) while making minimal to no contributions back to the open source platform that they depend upon.

If true, and it appears to be, this would violate the principle of reciprocity. If you benefit from somebody else’s effort (and you’re able to) you’re morally-obliged to at least offer to give back in a manner commensurate to your relative level of resources.

Two children sit on a bed: one hands a toy dinosaur to the other.
The principle of reciprocity is a moral staple. This is evidenced by the fact that children (and some nonhuman animals) seem to be able to work it out for themselves from first principles using nothing more than empathy. Companies, however aren’t usually so-capable. Photo courtesy Cotton.

Abuse of this principle is… sadly not-uncommon in business. Or in tech. Or in the world in general. A lightweight example might be the many millions of profitable companies that host atop the Apache HTTP Server without donating a penny to the Apache Foundation. A heavier (and legally-backed) example might be Trump Social’s implementation being based on a modified version of Mastodon’s code: Mastodon’s license requires that their changes are shared publicly… but they don’t do until they’re sent threatening letters reminding them of their obligations.

I feel like it’s fair game to call out companies that act amorally, and encourage people to boycott them, so long as you do so without “punching down”.

Ethically: don’t exploit open source’s liberties as weaknesses

WP Engine also stand accused of altering the open source code that they host in ways that maximise their profit, to the detriment of both their customers and the original authors of that code5.

It’s well established, for example, that WP Engine disable the “revisions” feature of WordPress6. Personally, I don’t feel like this is as big a deal as Matt makes out that it is (I certainly wouldn’t go as far as saying “WP Engine is not WordPress”): it’s pretty commonplace for large hosting companies to tweak the open source software that they host to better fit their architecture and business model.

But I agree that it does make WordPress as-provided by WP Engine significantly less good than would be expected from virtually any other host (most of which, by the way, provide much better value-for-money at any price point).

Fake web screenshot showing turdpress.com, "WordPress... But Shit".
There’s nothing to stop me from registering TurdPress.com and providing a premium WordPress web hosting solution with all the best features disabled: I could even disable exports so that my customers wouldn’t even be able to easily leave my service for greener pastures! There’s nothing stop me… but that wouldn’t make it right7.
It also looks like WP Engine may have made more-nefarious changes, e.g. modifying the referral links in open source code (the thing that earns money for the original authors of that code) so that WP Engine can collect the revenue themselves when they deploy that code to their customers’ sites. That to me feels like it’s clearly into the zone ethical bad practice. Within the open source community, it’s not okay to take somebody’s code, which they were kind enough to release under a liberal license, strip out the bits that provide their income, and redistribute it, even just as a network service8.

Again, I think this is fair game to call out, even if it’s not something that anybody has a right to enforce legally. On which note…

Legally: trademarks have value, don’t steal them

Automattic Inc. has a recognised trademark on WooCommerce, and is the custodian of the WordPress Foundation’s trademark on WordPress. WP Engine are accused of unauthorised use of these trademarks.

Obviously, this is the part of the story you’re going to see the most news media about, because there’s reasonable odds it’ll end up in front of a judge at some point. There’s a good chance that such a case might revolve around WP Engine’s willingness (and encouragement?) to allow their business to be called “WordPress Engine” and to capitalise on any confusion that causes.

Screenshot from the WordPress Foundation's Trademark Policy page, with all but the first line highlighted of the paragraph that reads: The abbreviation “WP” is not covered by the WordPress trademarks, but please don’t use it in a way that confuses people. For example, many people think WP Engine is “WordPress Engine” and officially associated with WordPress, which it’s not. They have never once even donated to the WordPress Foundation, despite making billions of revenue on top of WordPress.
I don’t know how many people spotted this ninja-edit addition to the WordPress Foundation’s Trademark Policy page, but I did.

I’m not going to weigh in on the specifics of the legal case: I Am Not A Lawyer and all that. Naturally I agree with the underlying principle that one should not be allowed to profit off another’s intellectual property, but I’ll leave discussion on whether or not that’s what WP Engine are doing as a conversation for folks with more legal-smarts than I. I’ve certainly known people be confused by WP Engine’s name and branding, though, and think that they must be some kind of “officially-licensed” WordPress host: it happens.

If you’re following all of this drama as it unfolds… just remember to check your sources. There’s a lot of FUD floating around on the Internet right now9.

In summary…

With a reminder that I’m sharing my own opinion here and not that of my employer, here’s my thoughts on the recent WP Engine drama:

  1. WP Engine certainly act in ways that are unethical and immoral and antithetical to the spirit of open source, and those are just a subset of the reasons that I wouldn’t use them as a WordPress host.
  2. Matt Mullenweg calling them out at WordCamp US doesn’t get his point across as well as I think he hoped it might, and probably won’t win him any popularity contests.
  3. I’m not qualified to weigh in on whether or not WP Engine have violated the WordPress Foundation’s trademarks, but I suspect that they’ve benefitted from widespread confusion about their status.

Footnotes

1 I suppose I ought to point out that Automattic is my employer, in case you didn’t know, and point out that my opinions don’t necessarily represent theirs, etc. I’ve been involved with WordPress as an open source project for about four times as long as I’ve had any connection to Automattic, though, and don’t always agree with them, so I’d hope that it’s a given that I’m speaking my own mind!

2 Though like Manu, I don’t think that means that Matt should take the corresponding blog post down: I’m a digital preservationist, as might be evidenced by the unrepresentative-of-me and frankly embarrassing things in the 25-year archives of this blog!

3 Fortunately the documents that the lawyers for both sides have been writing are much clearer and more-specific, but that’s what you pay lawyers for, right?

4 There’s a huge amount of debate about the difference between morality and ethics, but I’m using the definition that means that morality is based on what a social animal might be expected to decide for themselves is right, think e.g. the Golden Rule etc., whereas ethics is the code of conduct expected within a particular community. Take stealing, for example, which covers the spectrum: that you shouldn’t deprive somebody else of something they need, is a moral issue; that we as a society deem such behaviour worthy of exclusion is an ethical one; meanwhile the action of incarcerating burglars is part of our legal framework.

5 Not that nobody’s immune to making ethical mistakes. Not me, not you, not anybody else. I remember when, back in 2005, Matt fucked up by injecting ads into WordPress (which at that point didn’t have a reliable source of funding). But he did the right thing by backpedalling, undoing the harm, and apologising publicly and profusely.

6 WP Engine claim that they disable revisions for performance reasons, but that’s clearly bullshit: it’s pretty obvious to me that this is about making hosting cheaper. Enabling revisions doesn’t have a performance impact on a properly-configured multisite hosting system, and I know this from personal experience of running such things. But it does have a significant impact on how much space you need to allocate to your users, which has cost implications at scale.

7 As an aside: if a court does rule that WP Engine is infringing upon WordPress trademarks and they want a new company name to give their service a fresh start, they’re welcome to TurdPress.

8 I’d argue that it is okay to do so for personal-use though: the difference for me comes when you’re making a profit off of it. It’s interesting to find these edge-cases in my own thinking!

9 A typical Reddit thread is about 25% lies-and-bullshit; but you can double that for a typical thread talking about this topic!

× × × × ×