<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet href="/feeds.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="https://chameth.com/">
    <title>Chameth.com - short posts</title>
    <subtitle>Personal homepage of Chris Smith</subtitle>
    <link href="https://chameth.com/short.xml" rel="self"/>
    <link href="https://chameth.com/"/>
    <icon>https://chameth.com/favicon.png</icon>
    <updated>2026-03-14T00:00:00Z</updated>
    <id>https://chameth.com/</id>
    <author>
        <name>Chris Smith</name>
    </author>
    <entry>
        <title>The longest way to represent a date</title>
        <link href="https://chameth.com/the-longest-way-to-represent-a-date/" rel="self"/>
        <updated>2026-03-14T00:00:00Z</updated>
        <id>https://chameth.com/the-longest-way-to-represent-a-date/</id>
        <content xml:lang="en" type="html">&lt;p&gt;The other day, someone on IRC posed this question: “What is the longest way to represent a date using any means possible that isn’t just repeated filler?”&lt;/p&gt;
&lt;p&gt;Some people jumped for writing the date out in languages that had longer translations. My immediate reaction was instead to suggest an obnoxious string-based representation of a unix timestamp: “one second after one second after one second after … midnight on January 1st 1970”. It’s &lt;em&gt;very&lt;/em&gt; repetitive, but it’s not filler: taking out any of the repetitions would change the value. Effectively it’s a &lt;a href=&#34;https://en.wikipedia.org/wiki/Successor_function&#34;&gt;successor function&lt;/a&gt; for unix timestamps, writ long. Some quick napkin maths suggests the full string representation would be around 30GiB&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;An obvious approach to make it bigger is to make it more precise. If we do the same sort of successor function for &lt;em&gt;milliseconds&lt;/em&gt; it’d be a bit over 1000x longer&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. It actually ends up being just over 35TiB&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;There’s no reason to stop there, though. You can step down to microseconds, nanoseconds, and so on… or… we can just skip right to the end. How about: “one oscillation of the caesium-133 hyperfine transition frequency after one oscillation of the caesium-133 hyperfine transition frequency after … midnight on January 1st 1970”? There are over 9 billion of those every second, and the phrasing is &lt;em&gt;wordy&lt;/em&gt;. That comes out to almost 1ZiB&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. If we pooled all the data storage on the planet together we could save a couple hundred of these timestamps.&lt;/p&gt;
&lt;p&gt;One final step, then: why use the unix epoch when we could use the universe’s own&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;? We’re something around 4×10^17 seconds past the big bang, so… hold on, I need to look up some units… that’d be over 200,000 yobibytes&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;. There’s not actually a standard prefix for that order of magnitude, according to Wikipedia. I think it should be 200 robibytes. Does anyone have a contact at the IEC?&lt;/p&gt;
&lt;p&gt;That is a big number. Is it impossibly big? If we wanted to track our current time, we’d need to write around 600GiB/s&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; to disk. That’s a bit more than we can manage at the minute, but isn’t completely outrageous. What about storage? Apparently hard drives require around a million atoms to store a bit of data. There’s some research showing it’s possible to use as few as 12, but I don’t think it’s anything that can be used at scale anytime soon&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;. So just for the direct data storage, not counting all the other infrastructure you need for a disk drive to &lt;em&gt;work&lt;/em&gt; we’d need around 10^36 atoms. If we sourced our atoms for our local &lt;a href=&#34;https://en.wikipedia.org/wiki/Instrumental_convergence#Paperclip_maximizer&#34;&gt;paperclip maximiser&lt;/a&gt; we’d need around 200 trillion paperclips. For just one timestamp.&lt;/p&gt;
&lt;p&gt;On the plus side, this timestamp format would compress &lt;em&gt;wonderfully&lt;/em&gt;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;17 bytes of repetition * 1773528583 seconds ~= 3×10^10. &lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;There’d be a thousand times more repetitions, and each one would have the extra five bytes from the “milli” prefix. &lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;22 bytes of repetition * 1773528583000 milliseconds ~= 3×10^13. &lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;72 bytes of repetition * 1773528583 seconds * 9192631770 oscillations per second ~= 1×10^21. &lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;Other than it being impractical, not known to a decent accuracy, and the myriad other problems, of course. &lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;72 bytes of repetition * 4×10^17 seconds * 9192631770 oscillations per second ~= 3×10^29. &lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;72 bytes of repetition * 9192631770 oscillations per second ~= 6×10^11. &lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;Not that we could scale conventional drives up this much, either. &lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>Exposing game servers over Tailscale</title>
        <link href="https://chameth.com/exposing-game-servers-over-tailscale/" rel="self"/>
        <updated>2025-12-07T00:00:00Z</updated>
        <id>https://chameth.com/exposing-game-servers-over-tailscale/</id>
        <content xml:lang="en" type="html">&lt;p&gt;I’ve recently been playing a lot of &lt;a href=&#34;https://factorio.com/&#34;&gt;Factorio&lt;/a&gt; with a friend. I’ve been
hosting, but my desktop computer is behind far too many layers of NAT, and I can’t be bothered
dealing with setting up port forwards. Up until today we made do with Steam’s networking support,
which in our case ended up relaying the connection via one of their servers. This is amazing as
a free, no-hassle service, but the performance was so-so. We’d get random lag spikes, or the
initial map download would crawl along at about 1/100th of the speed we should be able to get.
We’re both fans of &lt;a href=&#34;https://tailscale.com/&#34;&gt;Tailscale&lt;/a&gt; though, so maybe there’s an easy solution
there?&lt;/p&gt;
&lt;p&gt;Tailscale even have an article on &lt;a href=&#34;https://tailscale.com/blog/factorio-multiplayer-video&#34;&gt;sharing a Factorio server&lt;/a&gt;
but it’s a ten minute long video&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and focused on setting up an actual dedicated server in Docker
rather than just clicking the convenient “Host” button in the game client. What we did instead was:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I shared my desktop’s Tailscale node with my friend, by creating a sharing link in the &lt;a href=&#34;https://login.tailscale.com/admin/machines&#34;&gt;Admin console&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My friend accepted the link, and could then see my machine in their admin panel&lt;/li&gt;
&lt;li&gt;I used &lt;code&gt;tailscale lock&lt;/code&gt; to sign my friend’s desktop’s node key, as I have &lt;a href=&#34;https://tailscale.com/kb/1226/tailnet-lock&#34;&gt;tailnet lock&lt;/a&gt; enabled&lt;/li&gt;
&lt;li&gt;I added a grant to my tailnet’s ACL to permit access from my friend to the specific IP/port on my tailnet:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&#34;chroma-chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;		&lt;span class=&#34;chroma-p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;			&lt;span class=&#34;chroma-nt&#34;&gt;&amp;#34;src&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;friend@example.com&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;			&lt;span class=&#34;chroma-nt&#34;&gt;&amp;#34;dst&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;chroma-p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;100.0.0.42&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;fd7a::42&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;			&lt;span class=&#34;chroma-nt&#34;&gt;&amp;#34;ip&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;:&lt;/span&gt;  &lt;span class=&#34;chroma-p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;chroma-s2&#34;&gt;&amp;#34;udp:34197&amp;#34;&lt;/span&gt;&lt;span class=&#34;chroma-p&#34;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;chroma-line&#34;&gt;&lt;span class=&#34;chroma-cl&#34;&gt;		&lt;span class=&#34;chroma-p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After this, my friend could connect to Factorio by entering the Tailscale IP address, or the Tailscale hostname (as they use &lt;a href=&#34;https://tailscale.com/kb/1081/magicdns&#34;&gt;MagicDNS&lt;/a&gt;).
Running &lt;code&gt;tailscale status&lt;/code&gt; shows that Tailscale managed to establish a direct connection despite the many layers of NAT involved,
and the performance improvements were significant and immediate.&lt;/p&gt;
&lt;p&gt;We did a bit of testing, and confirmed that no other services on my machine are accessible. And sharing a machine by default
only allows it to accept incoming connections, so I can’t get unwanted access to anything on my friend’s Tailnet, either.&lt;/p&gt;
&lt;p&gt;I’ve &lt;a href=&#34;https://chameth.com/how-i-use-tailscale/&#34;&gt;written before&lt;/a&gt; about all the different ways I use Tailscale; this is yet
another new way it’s solved a problem for me.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr/&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I’m not a fan of video tutorials at the best of times, but especially not when I want to do something as quickly as possible so I can get back to &lt;del&gt;my addiction&lt;/del&gt; growing the factory. &lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;↩︎&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</content>
    </entry>
    <entry>
        <title>Moving back to a dynamic website</title>
        <link href="https://chameth.com/moving-back-to-a-dynamic-website/" rel="self"/>
        <updated>2025-10-28T00:00:00Z</updated>
        <id>https://chameth.com/moving-back-to-a-dynamic-website/</id>
        <content xml:lang="en" type="html">&lt;p&gt;For the past few weeks I’ve been working on converting chameth.com from a static site into a dynamically generated site backed by a database. This is the exact opposite process to one I went through maybe a decade ago. So why the change, and what’s different?&lt;/p&gt;
&lt;p&gt;I’d actually been toying with the idea of switching for a while. Every now and then I’d have a thought along the lines of “it would be nice if I could add X to my website… but how would that work with static site generation?”. Comments, private drafts, dynamic themes based on the date, and many more little bits and pieces. You can definitely &lt;em&gt;do&lt;/em&gt; them with a static site generator, but it felt like going against the grain. The beauty of a static site is that it’s… well… static. Shoehorning in dynamic features takes away a lot of the benefits, or leads to having lots of weird seams where you join the static and dynamic pieces together.&lt;/p&gt;
&lt;p&gt;A bunch of things have changed since I originally switched to a static site generator. In no particular order:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The advent of containers, and managing them with config like in &lt;code&gt;docker-compose&lt;/code&gt;, means standing up and managing a database for the site is trivial.&lt;/li&gt;
&lt;li&gt;I’ve learnt and really like Golang, which makes writing HTTP-based servers a breeze, and makes it easy to deploy the site as a single binary (in a container).&lt;/li&gt;
&lt;li&gt;LLM agents are good enough that I can have it do all the boring CRUD work needed to actually make a dynamic site work (&lt;em&gt;so&lt;/em&gt; many admin functions…).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/csmith/chameth.com/&#34;&gt;The code&lt;/a&gt; is open source if you’re interested. I’ve made no effort to make it generally useful outside of this website, but it might serve as a useful reference if you want to do something similar. Now that’s done, I can safely procrastinate on all those dynamic features I had planned!&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>Avoiding the Consequences of Dumb Laws with Tailscale</title>
        <link href="https://chameth.com/avoiding-the-consequences-of-dumb-laws-with-tailscale/" rel="self"/>
        <updated>2025-09-30T00:00:00Z</updated>
        <id>https://chameth.com/avoiding-the-consequences-of-dumb-laws-with-tailscale/</id>
        <content xml:lang="en" type="html">&lt;p&gt;More and more sites are implementing privacy-invading age checks or just
completely blocking the UK thanks to the &lt;a href=&#34;https://www.legislation.gov.uk/ukpga/2023/50/contents&#34;&gt;Online Safety Act&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Protecting kids from &lt;em&gt;some&lt;/em&gt; content online is certainly a noble goal, but
the asinine guidance from Ofcom, threats of absolutely disproportionate fines,
and the stupidly broad categories of content have resulted in companies just
giving up or going through a tick-box exercise that offers very little
protection but lots of inconvenience and a complete invasion of privacy.&lt;/p&gt;
&lt;p&gt;Instead of uploading my ID to some third party company, I’ve taken to proxying
my traffic through to a country that doesn’t have such stupid laws. Thankfully,
Tailscale makes this really easy. I’ve discussed &lt;a href=&#34;https://chameth.com/how-i-use-tailscale/&#34;&gt;how I use Tailscale&lt;/a&gt;
before, but not really covered &lt;em&gt;app connectors&lt;/em&gt;. I find Tailscale’s description
of these pretty confusing, but they basically amount to automatic, DNS-based
subnet routing configurations (or, to put it another way, a per-website exit
node). You can safely ignore all references to ‘SaaS apps’ in their docs.&lt;/p&gt;
&lt;p&gt;I create a custom app connector, and give it the domains to be included:&lt;/p&gt;
&lt;figure class=&#34;image full&#34;&gt;
  &lt;picture&gt;
      &lt;source srcset=&#34;https://chameth.com/avoiding-the-consequences-of-dumb-laws-with-tailscale/apps.avif&#34; type=&#34;image/avif&#34;/&gt;
      &lt;source srcset=&#34;https://chameth.com/avoiding-the-consequences-of-dumb-laws-with-tailscale/apps.webp&#34; type=&#34;image/webp&#34;/&gt;
      &lt;img src=&#34;https://chameth.com/avoiding-the-consequences-of-dumb-laws-with-tailscale/apps.png&#34; alt=&#34;Screenshot of the app section in the Tailscale admin console. It shows a table with two entries: &amp;#39;reddit&amp;#39; and &amp;#39;bluesky&amp;#39;. Each entry has a list of domain names like &amp;#39;*.reddit.com, *.reddit.it&amp;#39;.&#34; loading=&#34;lazy&#34; width=&#34;1151&#34; height=&#34;397&#34;/&gt;
  &lt;/picture&gt;
  &lt;figcaption&gt;&lt;p&gt;App configuration in the Tailscale admin console&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Tailscale then magically resolves those domains, and has the ‘connector’
advertise routes for them. Any client that accepts routes will start sending
requests to the connector, which passes them onto the Internet at large. Any
other traffic is left alone, unlike when you use an exit node.&lt;/p&gt;
&lt;p&gt;The special bit here is how you can specify wildcard domains. Tailscale proxies
the DNS requests from clients (so it can inject responses for nodes on your
tailnet), which means it can dynamically update the routes as you resolve new
domains. I tried to set this up more manually, and quickly came unstuck: despite
using the same DNS servers, my server and my desktop would get different responses
for the same query as it varied by geography. Trying to get the full set of
IPs (and keeping them updated) would have been a nightmare. Tailscale expanding
the wildcards nicely sidesteps all of that.&lt;/p&gt;
&lt;p&gt;At first I was just proxying the traffic to one of my servers, but just today
I added a new connector for Imgur and found I was still blocked, just for
different reasons. They not only block my entire country but also a load
of known datacenter IP ranges. Hmph. I fixed this by hacking up a new side
project: &lt;a href=&#34;https://github.com/csmith/tsv&#34;&gt;tsv&lt;/a&gt;. It’s a simple Go app that accepts
traffic from the tailnet (advertising itself as both an app connector and an
exit node), and passes it on to another VPN.&lt;/p&gt;
&lt;p&gt;There are lots of other ways you could accomplish this, but this makes it so
all my devices can still access services without any additional configuration.
As long as Tailscale is installed, the Internet will still work as it’s meant
to, without all the nonsense. If I come across a site that doesn’t work, adding
it is trivial: I just make a new app connector in Tailscale.&lt;/p&gt;
&lt;p&gt;Obvious disclaimer: the laws in the UK are binding on the service providers,
not the end user. Doing this sort of thing in other countries might be illegal.
I don’t know; do your own research! Also all of this is a workaround
for something that should be fixed at a legislative level, but I’m not holding
my breath.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <title>Blogging and the Imaginary Quality Bar</title>
        <link href="https://chameth.com/blogging-and-the-imaginary-quality-bar/" rel="self"/>
        <updated>2025-09-18T00:00:00Z</updated>
        <id>https://chameth.com/blogging-and-the-imaginary-quality-bar/</id>
        <content xml:lang="en" type="html">&lt;p&gt;Recently I realised that I’ve developed a self-imposed quality bar for blog
posts. They need to be a certain length, and have a certain &lt;em&gt;substance&lt;/em&gt; to them.
They need to be generally useful in some way I can’t quite define, to some
imagined future audience. They need to have images to break up the page, and
opengraph data for when they’re linked to on social media. But… maybe they
don’t? Those things all make sense for longer “article” type posts, but not so
much for a personal blog.&lt;/p&gt;
&lt;p&gt;I’ve done some fiddling so that I can make posts without all that extra stuff.
We’ll see how it goes. The posts won’t be distinguished on the site (yet?), but
I have set up separate RSS feeds for just &lt;a href=&#34;https://chameth.com/short.xml&#34;&gt;short form posts&lt;/a&gt; and
&lt;a href=&#34;https://chameth.com/long.xml&#34;&gt;long form posts&lt;/a&gt; in case subscribers are radically opposed to one
or the other. Now I can start blogging like it’s 2005 again. But hopefully
with a bit less cringe.&lt;/p&gt;
&lt;p&gt;I’ve been staring at this post in my editor for about five minutes. The urge
to make it longer, more thorough, more article-like is really strong. This
entire paragraph is only here as a compromise with myself so I can actually
save and commit the post.&lt;/p&gt;
</content>
    </entry>
</feed>
