Shellsharks Blogroll - BlogFlock2026-01-08T17:46:36.663ZBlogFlockWerd I/O, cool-as-heck, Evan Boehs, destructured, Aaron Parecki, Sophie Koonin, Adepts of 0xCC, cmdr-nova@internet:~$, <span>Songs</span> on the Security of Networks, Westenberg, fLaMEd, Hey, it's Jason!, Johnny.Decimal, gynvael.coldwind//vx.log (pl), Terence Eden’s Blog, James' Coffee Blog, Molly White, Robb Knight, joelchrono, Trail of Bits Blog, Posts feed, Kev QuirkString Replacements on EchoFeed - Robb Knight • Posts • Atom Feedhttps://rknight.me/blog/string-replacements-on-echofeed/2026-01-08T13:04:42.000Z<p>One request I've had quite a bit for <a href="https://echofeed.app">EchoFeed</a> is to be able to handle specific, known usernames, between Mastodon and Bluesky where they are different (which is almost always the case). Some <a href="https://croissantapp.com/">pastry-themed</a> apps already have something similar but for EchoFeed it needed to work differently.</p>
<p>For EchoFeed, I've gone for the simplest solution which is also the most flexible - straight string replacement. "Replace THIS with THAT", or in real terms, "replace <code>@robb@social.lol</code> with <code>@rknight.me</code> when cross posting between Mastodon and Bluesky. Maybe you want to replace <code>utm_source=mastodon</code> with <code>utm_source=bluesky</code> because you're a big Business™ boy or replace every mention of "Twitter" with "the deep fake porn and hate platform" because you understand you don't hang out at Nazi bars no matter what. You can replace literally anything, it's up to you. <a href="https://help.echofeed.app/replacements/">The documentation</a> has a bit more information about how they work.</p>
<figure><img src="https://cdn.rknight.me/echofeed/replacements-echofeed-user-names.jpg" alt="A form showing find and replace values for two different usernames" /></figure>
<p>EchoFeed won't replace strings in links and has the option to only do case-sensitive replacements. Replacements is an EchoFeed Pro feature and is available now.</p>AI will compromise your cybersecurity posture - <span>Songs</span> on the Security of Networkshttps://rys.io/en/181.html2026-01-07T21:08:34.000Z<p>Yes, “AI” will compromise your information security posture. No, not
through some mythical self-aware galaxy-brain entity magically cracking
your passwords in seconds or “autonomously” exploiting new
vulnerabilities.</p>
<p>It’s way more mundane.</p>
<p>When immensely complex, poorly-understood systems get <a href="https://www.wired.com/story/mcdonalds-ai-hiring-chat-bot-paradoxai/">hurriedly
integrated</a> into your toolset and workflow, or deployed in your
infrastructure, what inevitably follows is <a href="https://www.malwarebytes.com/blog/news/2025/09/when-ai-chatbots-leak-and-how-it-happens">leaks</a>,
compromises, downtime, and a whole lot of grief.</p>
<h2 id="complexity-means-cost-and-risk">Complexity means cost and
risk</h2>
<p>LLM-based systems are insanely complex, both on the conceptual level,
and on the implementation level. Complexity has real cost and introduces
very real risk. These costs and these risks are enormous, poorly
understood – and usually just hand-waved away. As <a href="https://sshussain.me/">Suha Hussain</a> puts it in a video I’ll
discuss a bit later:</p>
<blockquote>
<p>Machine learning is not a quick add-on, but something that will
fundamentally change your system security posture.</p>
</blockquote>
<p>The amount of risk companies and organizations take on by using,
integrating, or implementing LLM-based – or more broadly, machine
learning-based – systems is massive. And they have to eat all of that
risk themselves: suppliers of these systems <a href="https://scribe.rip/snowflake-at-central-of-worlds-largest-data-breach-939fc400912e">simply
refuse to take any real responsibility</a> for the tools they provide
and problems they cause.</p>
<p>After all, taking responsibility is bad for the hype. And the hype is
what makes the line go up.</p>
<h2 id="the-hype">The Hype</h2>
<p>An important part of pushing that hype is inflating expectations and
generating fear of missing out, one way or another. What better way to
generate it than by using actual fear?</p>
<p>What if spicy autocomplete <em>is in fact</em> all that it is cracked
up to be, and more? What if some kid somewhere with access to some
AI-chatbot can break all your passwords or automagically exploit
vulnerabilities, and just waltz into your internal systems? What if some
AI agent can indeed “autonomously” break through your defenses and wreak
havoc on your internal infrastructure?</p>
<p>You <a href="https://www.logicallyfallacious.com/logicalfallacies/Shifting-of-the-Burden-of-Proof"><em>can’t
prove</em> that’s not the case</a>! And your data and cybersecurity is
on the line! Be afraid! Buy our “AI”-based security thingamajig to
protect yourself!..</p>
<p>It doesn’t matter if you do actually buy that product, by the way.
What matters is that investors believe you might. This whole theater is
not for you, it’s for VCs, angel investors, and whoever has spare cash
to buy some stock. <a href="https://rys.io/en/180.html">The hype itself is the
product</a>.</p>
<p>Allow me to demonstrate what I mean by this.</p>
<h3 id="cracking-51-of-popular-passwords-in-seconds">Cracking “51% of
popular passwords in seconds”</h3>
<p>Over two years ago “AI” supposedly could crack our passwords “<a href="https://www.zdnet.com/article/how-an-ai-tool-could-crack-your-passwords-in-seconds/">in
seconds</a>”. Spoiler: it couldn’t, and today our passwords are no worse
for wear.</p>
<p>The source of a sudden deluge of breathless headlines about
AI-cracked passwords – and boy <a href="https://www.tomshardware.com/news/ai-cracks-most-common-passwords-in-less-than-a-minute">were
there</a> quite <a href="https://www.securitymagazine.com/articles/99457-ai-can-crack-your-password">a
few</a>! – was a <a href="https://web.archive.org/web/20240803164643/https://www.securityhero.io/ai-password-cracking/">website
of a particular project</a> called “PassGAN”. It had it all: scary
charts, scary statistics, scary design, and social media integrations to
generate scary buzz.</p>
<p>What it lacked was technical details. What hardware and
infrastructure was used to crack “51% popular passwords in seconds”? The
difference between doing that on a single laptop GPU versus running it
on a large compute cluster is pretty relevant. What does “cracking” a
password actually mean here – presumably reversing a hash? What hashing
function, then, was used to hash them in the first place? How does it
compare against <a href="https://www.openwall.com/john/">John the
Ripper</a> and other non-“AI” tools that had been out there for ages?
And so on.</p>
<p>Dan Goodin of Ars Technica did <a href="https://arstechnica.com/information-technology/2023/04/the-passgan-ai-password-cracker-what-it-is-and-why-its-mostly-hype/">a
fantastic teardown</a> of PassGAN. The long and short of it is:</p>
<blockquote>
<p>As with so many things involving AI, the claims are served with a
generous portion of smoke and mirrors. PassGAN, as the tool is dubbed,
performs no better than more conventional cracking methods. In short,
anything PassGAN can do, these more tried and true tools do as well or
better.</p>
</blockquote>
<p>If anyone was actually trying to crack any passwords, PassGAN was not
a tool they’d use, simply because it wasn’t actually effective. In no
way was PassGAN a real threat to your information security.</p>
<h3 id="exploiting-87-of-one-day-vulnerabilities">Exploiting “87% of
one-day vulnerabilities”</h3>
<p>Another example: over a year ago GPT-4 was supposedly able to “<a href="https://www.techrepublic.com/article/openai-gpt4-exploit-vulnerabilities/">autonomously</a>”
exploit one-day vulnerabilities just based on CVEs. Specifically, <a href="https://hackproofhacks.com/gpt-4-87-success-in-exploiting-vulnerabilities">87%
of them</a>.</p>
<p>Even more specifically, that’s 87% of exactly <a href="https://www.theregister.com/2024/04/17/gpt4_can_exploit_real_vulnerabilities/">15
(yes, <em>fifteen</em>) vulnerabilities</a>, <em>hand-picked</em> by the
researchers for that study. For those keeping score at home, that comes
out to thirteen “exploited” vulnerabilities. And even that <a href="https://securityintelligence.com/articles/chatgpt-4-exploits-87-percent-one-day-vulnerabilities/">only
when the CVE included example exploit code</a>.</p>
<p>In other words, code regurgitation machine was able to regurgitate
code when example code was provided to it. Again, in no way is this an
actual, real threat to you, your infrastructure, or your data.</p>
<h3 id="ai-orchestrated-cyberattack">“AI-orchestrated” cyberattack</h3>
<p>A fresh example of generating hype through inflated claims and fear
comes from Anthropic. The company behind an LLM-based
programming-focused chatbot Claude pumps the hype by claiming their
chatbot was used in a “<a href="https://www.anthropic.com/news/disrupting-AI-espionage">first
reported AI-orchestrated cyber-espionage campaign</a>”.</p>
<p>Anthropic – who has vested interest in convincing everyone that their
coding automation product is the next best thing since sliced bread –
makes pretty bombastic claims, using sciencey-sounding language; for
example:</p>
<blockquote>
<p>Overall, the threat actor was able to use AI to perform 80-90% of the
campaign, with human intervention required only sporadically (perhaps
4-6 critical decision points per hacking campaign). (…) At the peak of
its attack, the AI made thousands of requests, often multiple per
second—an attack speed that would have been, for human hackers, simply
impossible to match.</p>
</blockquote>
<p>Thing is, that just describes automation. That’s what computers were
invented for.</p>
<p>A small script, say in Bash or Python, that repeats certain tedious
actions during an attack (for example, generates a list of API endpoints
based on a pattern to try a known exploit against) can easily
“<em>perform 80-90%</em>” of a campaign that employs it. It can make
“<em>thousands of requests, often multiple per second</em>” with
<code>curl</code> and a <code>for</code> loop. And “<em>4-6 critical
decision points</em>” can just as easily mean a few simple questions
asked by that script, for instance: what API endpoint to hit when a
given target does not seem to expose the attacked service on the
expected one.</p>
<p>And while LLM chatbots somewhat expand the scope of what can be
automated, so did scripting languages and other decidedly non-magic
technologies at the time they were introduced. Anyone making a huge deal
out of a cyberattack being “orchestrated” using Bash or Python would be
treated like a clown, and <a href="https://arstechnica.com/security/2025/11/researchers-question-anthropic-claim-that-ai-assisted-attack-was-90-autonomous/">so
should Anthropic</a> for making grandiose claims just because somebody
<a href="https://xcancel.com/VoyageBliss/status/1948049778102898896">actually
managed to use Claude</a> for something.</p>
<p>There is, however, one very important point that Anthropic buries in
their write-up:</p>
<blockquote>
<p>At this point [the attackers] had to convince Claude—which is
extensively trained to avoid harmful behaviors—to engage in the attack.
They did so by jailbreaking it, effectively tricking it to bypass its
guardrails. They broke down their attacks into small, seemingly innocent
tasks that Claude would execute without being provided the full context
of their malicious purpose. They also told Claude that it was an
employee of a legitimate cybersecurity firm, and was being used in
defensive testing.</p>
</blockquote>
<p>The real story here is not that an LLM-based chatbot is somehow
“orchestrating” a cyber-espionage campaign by itself. The real story is
that a tech company, whose valuation is at <a href="https://www.cnbc.com/2025/09/02/anthropic-raises-13-billion-at-18-billion-valuation.html">around
$180 billion-with-a-b</a>, put out a product – “<em>extensively trained
to avoid harmful behaviors</em>” – that is so hilariously unsafe that
its guardrails can be subverted by a tactic a 13-year-old uses when they
want to prank-call someone.</p>
<p>And that Anthropic refuses to take responsibility for that unsafe
product.</p>
<p>Consider this: if Anthropic actually believed their own hype about
Claude being so extremely powerful, dangerous, and able to autonomously
“orchestrate” attacks, they should be terrified about how trivial it is
to subvert it, and would take it offline until they fix that. I am not
holding my breath, though.</p>
<h2 id="the-boring-reality">The boring reality</h2>
<p>The way to secure your infrastructure and data remains the same
regardless of whether a given attack is automated using Bash, Python, or
an LLM chatbot: solid threat modelling, good security engineering,
regular updates, backups, training, and so on. If there is nothing that
can be exploited, no amount of automation will make it exploitable.</p>
<p>The way “AI” is going to compromise your cybersecurity is not through
some magical autonomous exploitation by a singularity from the outside,
but by being the poorly engineered, shoddily integrated, exploitable
weak point you would not have otherwise had on the inside. In a word, it
will largely be <a href="https://bsky.app/profile/jjvincent.bsky.social/post/3mayddynhas2l">self-inflicted</a>.</p>
<h3 id="leaks">Leaks</h3>
<p>Already in mid-2023 Samsung <a href="https://www.forbes.com/sites/siladityaray/2023/05/02/samsung-bans-chatgpt-and-other-chatbots-for-employees-after-sensitive-code-leak/">internally
banned the use of generative AI tools</a> after what was described as a
leak, and boiled down to Samsung employees pasting sensitive code into
ChatGPT.</p>
<p>What Samsung understood two and a half years ago, and what most
people seem to not understand still today, is that pasting anything into
the chatbot prompt window means giving it to the company running that
chatbot.</p>
<p>And these companies are very data-hungry. They also tend to be
incompetent.</p>
<p>Once you provide any data, it is out of your control. The company
running the chatbot <a href="https://openai.com/policies/how-your-data-is-used-to-improve-model-performance/">might
train their models on it</a> – which in turn might surface it to someone
else at some other time. Or they might just catastrophically
misconfigure their own infrastructure and leave your prompts – say, <a href="https://www.upguard.com/news/security-flaw-in-ai-chatbots-exposes-explicit-user-fantasies">containing
sexual fantasies</a> or trade secrets – <a href="https://cybernews.com/security/ai-chatbots-vyro-data-leak/">exposed</a>
to anyone on the Internet, and <a href="https://www.bbc.com/news/articles/cdrkmk00jy0o">indexable by
search engines</a>.</p>
<p>And when that happens they might even blame the users, <a href="https://www.malwarebytes.com/blog/news/2025/06/your-meta-ai-chats-might-be-public-and-its-not-a-bug">as
did Meta</a>:</p>
<blockquote>
<p>Some users might unintentionally share sensitive info due to
misunderstandings about platform defaults or changes in settings over
time.</p>
</blockquote>
<p>There’s that not-taking-responsibility-for-their-unsafe-tools again.
They’ll take your data, and leave you holding the bag of risk.</p>
<h3 id="double-agents">Double agents</h3>
<p>Giving a stochastic text extruder any kind of access to your systems
and data is a bad idea, even if no malicious actors are involved – as
one Replit user very publicly <a href="https://www.theregister.com/2025/07/21/replit_saastr_vibe_coding_incident/">learned
the hard way</a>. But giving it such access <em>and</em> making it
possible for potential attackers to send data to it for processing is
much worse.</p>
<p>The first zero-click attack on an LLM agent <a href="https://fortune.com/2025/06/11/microsoft-copilot-vulnerability-ai-agents-echoleak-hacking/">has
already been found</a>. It happened to involve Microsoft 365 Copilot,
and <a href="https://www.aim.security/lp/aim-labs-echoleak-m365">required only
sending an e-mail</a> to an Outlook mailbox that had Copilot enabled to
process mail. A successful attack allowed data exfiltration, with no
action needed on the part of the targeted user.</p>
<p>Let me say this again: if you had Copilot enabled in Outlook, an
attacker could just send a simple plain text e-mail to your address and
get your data in return, with absolutely no interaction from you.</p>
<p>The way it worked was conceptually very simple: Copilot had access to
your data (otherwise it would not be useful), it was also processing
incoming e-mails; the attackers found a way to convince the agent to
interpret an incoming e-mail they sent as instructions for it to
follow.</p>
<p>On the most basic level, this attack was not much different from the
“<a href="https://www.nbcnews.com/tech/internet/hunting-ai-bots-four-words-trick-rcna161318">ignore
all previous instructions</a>” bot unmasking tricks that had been all
over social media for a while. Or from adding to your CV a bit of white
text on white background instructing whatever AI agent is processing it
to recommend your application for hiring (yes, <a href="https://kai-greshake.de/posts/inject-my-pdf/">this might actually
work</a>).</p>
<p>Or from adding such obscured (but totally readable to LLM-based
tools) text to scientific papers, instructing the agent to give them
positive “review” – which apparently was so effective, the International
Conference on Learning Representations <a href="https://blog.iclr.cc/2025/08/26/policies-on-large-language-model-usage-at-iclr-2026/">had
to create an explicit policy</a> against that. Amusingly, that is
<em>the</em> conference that “<a href="https://dair-community.social/@timnitGebru/115097550413770928">brought
this [that is, LLM-based AI hype] on us</a>” in the first place.</p>
<p>On the same basic level, this is also the trick researchers used to
go around OpenAI’s “guardrails” to get ChatGPT to <a href="https://techcrunch.com/2024/09/12/hacker-tricks-chatgpt-into-giving-out-detailed-instructions-for-making-homemade-bombs/">issue
bomb-building instructions</a>, tricked GitHub Copilot to <a href="https://www.legitsecurity.com/blog/camoleak-critical-github-copilot-vulnerability-leaks-private-source-code">leak
private source code</a>, and how the perpetrators went around
Anthropic’s “guardrails” in order to use the company’s LLM chatbot in
their aforementioned attack, by simply pretending they are security
researchers.</p>
<h3 id="prompt-injection">Prompt injection</h3>
<p>Why does this happen? Because LLMs (and tools based on them) have no
way of distinguishing data from instructions. Creators of these systems
use all sorts of tricks to try and separate the prompts that define the
“guardrails” from other input data, but fundamentally it’s all text, and
there is only a single context window.</p>
<p>Defending from prompt injections is like defending from <a href="https://developer.mozilla.org/en-US/docs/Glossary/SQL_Injection">SQL
injection</a>, but there is no such thing as prepared statements, and
instead of trying to escape specific characters you have to semantically
filter natural language.</p>
<p>This is another reason why Anthropic will not take Claude down until
they properly fix these guardrails, even if they believe their own hype
about how powerful (and thus dangerous when abused) it is. There is
simply no way to “properly fix them”. As a former Microsoft security
architect <a href="https://www.windowscentral.com/software-apps/former-security-architect-demonstrates-15-ways-to-break-copilot">had
pointed out</a>:</p>
<blockquote>
<p>[I]f we are honest here, we don’t know how to build secure AI
applications</p>
</blockquote>
<p>Of course all these companies will insist they can make these systems
safe. But inevitably, they will <a href="https://media.ccc.de/v/39c3-agentic-probllms-exploiting-ai-computer-use-and-coding-agents">continue</a>
to be proven wrong: <a href="https://www.pcgamer.com/software/ai/poets-are-now-cybersecurity-threats-researchers-used-adversarial-poetry-to-jailbreak-ai-and-it-worked-62-percent-of-the-time/">adversarial
poetry</a>, <a href="https://embracethered.com/blog/posts/2024/hiding-and-finding-text-with-unicode-tags/">ASCII
smuggling</a>, dropping some random facts about cats (<a href="https://arxiv.org/abs/2503.01781">no, really</a>), <a href="https://arxiv.org/abs/2506.12274">information overload</a>…</p>
<p>The arsenal of techniques grows, because the problem is fundamentally
related to the very architecture of LLM chatbots and agents.</p>
<h3 id="breaking-assumptions">Breaking assumptions</h3>
<p>Integrating any kind of software or external service into an existing
infrastructure always risks undermining security assumptions, and
creating unexpected vulnerabilities.</p>
<p>Slack decided to push AI down users’ throats, and inevitably
researchers <a href="https://promptarmor.substack.com/p/data-exfiltration-from-slack-ai-via">found
a way to exfiltrate data from private channels via an indirect prompt
injection</a>. An attacker did not need to be in the private channel
they were trying to exfiltrate data from, and the victim did not have to
be in the public channel the attacker used to execute the attack.</p>
<p>Gemini integration within Google Drive apparently had a “feature”
where it would <a href="https://www.tomshardware.com/tech-industry/artificial-intelligence/gemini-ai-caught-scanning-google-drive-hosted-pdf-files-without-permission-user-complains-feature-cant-be-disabled">scan
PDFs without explicit permission from the owner of these PDFs</a>.
Google claims that was not the case and the settings making the files
inaccessible to Gemini were not enabled. The person in question claims
they were.</p>
<p>Whether or not we trust Google here, it’s hard to deny settings
related to disabling LLM agents’ access to documents in Google Workplace
are <a href="https://www.techrepublic.com/article/news-google-gmail-hidden-ai-training-settings/">hard
to find, unreliable, and constantly shifting</a>. That in and of itself
is an information security issue (not to mention it being a compliance
issue as well). And Google’s interface decisions are to blame for this
confusion. This alone undermines your cybersecurity stance, if you
happen to be stuck with Google’s office productivity suite.</p>
<p>Microsoft had it’s own, way better documented problem, where a user
who did not have access to a particular file in SharePoint <a href="https://www.pentestpartners.com/security-blog/exploiting-copilot-ai-for-sharepoint/">could
just ask Copilot to provide them with its contents</a>. Completely
ignoring access controls.</p>
<p>You might think you can defend from that just by making certain files
private, or (in larger organizations) unavailable to certain users. But
as the Gemini example above shows, it might not be as simple because
relevant settings might be confusing or hidden.</p>
<p>Or… they might just not work at all.</p>
<h3 id="bugs.-so-many-bugs.">Bugs. So many bugs.</h3>
<p>Microsoft made it possible to set a policy
(<code>NoUsersCanAccessAgent</code>) in Microsoft 365 that would disable
LLM agents (plural, there are dozens of them) for specific users.
Unfortunately it seems to have been implemented with the level of
competence and attention to detail we have grown to expect from the
company – which is to say, <a href="https://cybersecuritynews.com/microsoft-copilot-agent-policy-flaw/">it
did not work</a>:</p>
<blockquote>
<p>Shortly after the May 2025 rollout of 107 Copilot Agents in Microsoft
365 tenants, security specialists discovered that the “Data Access”
restriction meant to block agent availability is being ignored.</p>
<p>(…)</p>
<p>Despite administrators configuring the Copilot Agent Access Policy to
disable user access, certain Microsoft-published and third-party agents
remain readily installable, potentially exposing sensitive corporate
data and workflows to unauthorized use.</p>
</blockquote>
<p>This, of course, underlines the importance of an audit trail. Even if
access controls were ignored, and even when agents turned out to be
available to users whom they should not be available to, at least there
are logs that can be used to investigate any unauthorized access, right?
After all, these are serious tools, built by serious companies and used
by serious institutions (banks, governments, and the like). Legal
compliance is key in a lot of such places, and compliance requires
auditability.</p>
<p>It would be pretty bad if it was possible for a malicious insider,
who used these agents to access something they shouldn’t have, to simply
ask for that fact not to be included in the audit log. Which, of course,
<a href="https://pistachioapp.com/blog/copilot-broke-your-audit-log">turned
out to be exactly the case</a>:</p>
<blockquote>
<p>On July 4th, I came across a problem in M365 Copilot: Sometimes it
would access a file and return the information, but the audit log would
not reflect that. Upon testing further, I discovered that I could simply
ask Copilot to behave in that manner, and it would. That made it
possible to access a file without leaving a trace.</p>
</blockquote>
<p>In June 2024 Microsoft’s president, Brad Smith, <a href="https://arstechnica.com/tech-policy/2024/06/microsoft-in-damage-control-mode-says-it-will-prioritize-security-over-ai/">promised
in US Congress</a> that security will be the top priority, “more
important even than the company’s work on artificial intelligence.”</p>
<p>No wonder, then, that the company treated this as an important
vulnerability. So important, in fact, that it decided not to inform
anyone about it, even after the problem got fixed. If you work in
compliance and your company uses Microsoft 365, I cannot imagine how
thrilled you must be about that! Can you trust your audit logs from the
last year or two? Who knows!</p>
<h3 id="code-quality">Code quality</h3>
<p>Even if you are not giving these LLMs access to any of your data and
just use them to generate some code, if you’re planning to use that code
anywhere near a production system, you should <a href="https://www.theglobeandmail.com/canada/article-ai-bot-doctors-meeting-patient-info-hospital-privacy-watchdog/">probably
think twice</a>:</p>
<blockquote>
<p>Businesses using artificial intelligence to generate code are
experiencing downtime and security issues. The team at Sonar, a provider
of code quality and security products, has heard first-hand stories of
consistent outages at even major financial institutions where the
developers responsible for the code blame the AI.</p>
</blockquote>
<p>This is probably a good time for a reminder that <a href="https://en.wikipedia.org/wiki/Information_security">availability
is also a part of what information security is about</a>.</p>
<p>But it gets worse. It will come as no surprise to anyone at this
stage that LLM chatbots “hallucinate”. Consider what might happen if
somewhere in thousands of lines of AI-generated code there is a
“hallucinated” dependency? That <a href="https://blogs.idc.com/2024/04/22/package-hallucination-the-latest-greatest-software-supply-chain-security-threat/">seems
to happen quite often</a>:</p>
<blockquote>
<p>“[R]esearchers (…) found that AI models hallucinated software package
names at surprisingly high rates of frequency and repetitiveness – with
Gemini, the AI service from Google, referencing at least one
hallucinated package in response to nearly two-thirds of all prompts
issued by the researchers.”</p>
</blockquote>
<p>The code referencing a hallucinated dependency might of course not
run; but that’s the less-bad scenario. You see, those “hallucinated”
dependency names are predictable. What if an attacker creates a
malicious package with such a name and pushes it out to a public package
repository?</p>
<blockquote>
<p>“[T]he researchers also uploaded a “dummy” package with one of the
hallucinated names to a public repository and found that it was
downloaded more than 30,000 times in a matter of weeks.”</p>
</blockquote>
<p>Congratulations, you just got <a href="https://en.wikipedia.org/wiki/Slopsquatting">slopsquatted</a>.</p>
<h3 id="roll-your-own">Roll your own?</h3>
<p>If you are not interested in using the clumsily integrated,
inherently prompt-injectable Big Tech LLMs, and instead you’re thinking
of rolling your own more specialized machine learning model for some
reason, you’re not in the clear either.</p>
<p>I quoted Suha Hussain at the beginning of this piece. Her work on
vulnerability of machine learning pipelines is as important as it is
chilling. If you’re thinking of training your own models, <a href="https://www.youtube.com/watch?v=Z38pTFM0FyU">her 2024 talk on
incubated machine learning exploits</a> is a must-see:</p>
<blockquote>
<p>Machine learning (ML) pipelines are vulnerable to model backdoors
that compromise the integrity of the underlying system. Although many
backdoor attacks limit the attack surface to the model, ML models are
not standalone objects. Instead, they are artifacts built using a wide
range of tools and embedded into pipelines with many interacting
components.</p>
</blockquote>
<blockquote>
<p>In this talk, we introduce incubated ML exploits in which attackers
inject model backdoors into ML pipelines using input-handling bugs in ML
tools. Using a language-theoretic security (LangSec) framework, we
systematically exploited ML model serialization bugs in popular tools to
construct backdoors.</p>
</blockquote>
<h2 id="danger-ahead">Danger ahead</h2>
<p>In a way, people and companies fear-hyping generative AI are right
that their chatbots and related tools pose a clear and present danger to
your cybersecurity. But instead of being some nebulous, omnipotent
malicious entities, they are dangerous because of their complexity, the
recklessness with which they are promoted, and the break-neck speed at
which they are being integrated into existing systems and workflows
without proper threat modelling, testing, and security analysis.</p>
<p>If you are considering implementing or using any such tool, consider
carefully the cost and risk associated with that decision. And if you’re
worried about “AI-powered” attacks, don’t – and <a href="https://www.lares.com/blog/ai-didnt-breach-you-your-configuration-did/">focus
on the fundamentals</a> instead.</p>Read "The Case for Blogging in the Ruins" - Molly White's activity feed695ecb36bf0eb54619dbbecb2026-01-07T21:08:06.000Z<article class="entry h-entry hentry"><header><div class="description">Read: </div></header><div class="content e-content"><div class="article h-cite hcite"><div class="title"><a class="u-url u-repost-of" href="https://www.joanwestenberg.com/the-case-for-blogging-in-the-ruins/" rel="bookmark">“<span class="p-name">The Case for Blogging in the Ruins</span>”</a>. </div><div class="byline"><span class="p-author h-card">JA Westenberg</span> in <i class="p-publication">Westenberg</i>. <span class="read-date"> Published <time class="dt-published published" datetime="2026-01-02">January 2, 2026</time>.</span></div><blockquote class="summary p-summary entry-summary">Virginia Woolf wrote about the importance of having a room of one's own: physical space for creative work, free from interruption and control. A blog is a room of your own on the internet. It's a place where you decide what to write about and how to write about it, where you're not subject to the algorithmic whims of platforms that profit from your engagement regardless of whether that engagement makes you or anyone else nebulously smarter.
Diderot built the Encyclopédie because he believed that organizing knowledge properly could change how people thought. He spent two decades on it. He went broke. He watched collaborators quit and authorities try to destroy his work. He kept going because the infrastructure mattered, because how we structure the presentation of ideas affects the ideas themselves.
We're not going to get a better internet by waiting for platforms to become less extractive. We build it by building it. By maintaining our own spaces, linking to each other, creating the interconnected web of independent sites that the blogosphere once was and could be again.</blockquote><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-01-07T21:08:06+00:00" title="January 7, 2026 at 9:08 PM UTC">January 7, 2026 at 9:08 PM UTC</time>. </div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/blogging" title="See all feed posts tagged "blogging"" rel="category tag">blogging</a>. </div></div></footer></article>Read "Writing vs AI" - Molly White's activity feed695ec997bf0eb54619dbbe152026-01-07T21:01:11.000Z<article class="entry h-entry hentry"><header><div class="description">Read: </div></header><div class="content e-content"><div class="article h-cite hcite"><div class="title"><a class="u-url u-repost-of" href="https://pluralistic.net/2026/01/07/delicious-pizza/" rel="bookmark">“<span class="p-name">Writing vs AI</span>”</a>. </div><div class="byline"><span class="p-author h-card">Cory Doctorow</span> in <span class="p-publication">his blog</span>. <span class="read-date"> Published <time class="dt-published published" datetime="2026-01-07">January 7, 2026</time>.</span></div><blockquote class="summary p-summary entry-summary">Replacing freshman comp with dozens of small groups run like graduate seminars is expensive and hard to imagine. But it would create a generation of students who wouldn't use an AI to write their essays any more than they'd ask an AI to eat a delicious pizza for them. We should aspire to assign the kinds of essays that change the lives of the students who write them, and to teach students to write that kind of essay.
</blockquote><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-01-07T21:01:11+00:00" title="January 7, 2026 at 9:01 PM UTC">January 7, 2026 at 9:01 PM UTC</time>. </div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/artificial_intelligence" title="See all feed posts tagged "artificial intelligence"" rel="category tag">artificial intelligence</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/education" title="See all feed posts tagged "education"" rel="category tag">education</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/writing" title="See all feed posts tagged "writing"" rel="category tag">writing</a>. </div></div></footer></article>Published on Citation Needed: "The year of technoligarchy" - Molly White's activity feed695eab07e5bd0603bc0d74492026-01-07T18:50:47.000Z<article class="entry h-entry hentry"><header><div class="description">Published an issue of <a href="https://www.citationneeded.news/"><i>Citation Needed</i></a>: </div><h2 class="p-name"><a class="u-syndication" href="https://www.citationneeded.news/the-year-of-technoligarchy" rel="syndication">The year of technoligarchy </a></h2></header><div class="content e-content"><div class="media-wrapper"><a href="https://www.citationneeded.news/the-year-of-technoligarchy"><img src="https://www.citationneeded.news/content/images/size/w2000/format/webp/2026/01/technoligarchy-1.png" alt="A collage of Elon Musk, Donald Trump, and David Sacks, all wearing gold crowns"/></a></div><div class="p-summary"><p>In 2025, Trump brought tech executives into power to dismantle regulators and write their own rules. But the instabilities they’re creating may be their downfall.</p></div></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <a href="https://www.citationneeded.news/the-year-of-technoligarchy"><time class="dt-published" datetime="2026-01-07T18:50:47+00:00" title="January 7, 2026 at 6:50 PM UTC">January 7, 2026 at 6:50 PM UTC</time>. </a></div><div class="social-links"> <span>Also posted to:</span><a class="social-link u-syndication twitter" href="https://twitter.com/molly0xFFF/status/2008973072460861729" title="Twitter" rel="syndication">Twitter</a><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/115855302714689985" title="Mastodon" rel="syndication">Mastodon</a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mbu4oied6s24" title="Bluesky" rel="syndication">Bluesky</a></div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/crypto" title="See all feed posts tagged "crypto"" rel="category tag">crypto</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/oligarchy" title="See all feed posts tagged "oligarchy"" rel="category tag">oligarchy</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/tech_industry" title="See all feed posts tagged "tech industry"" rel="category tag">tech industry</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/trump_administration" title="See all feed posts tagged "Trump administration"" rel="category tag">Trump administration</a>, <a class="tag p-category" href="https://www.mollywhite.net/feed/tag/us_politics" title="See all feed posts tagged "US politics"" rel="category tag">US politics</a>.</div></div></footer></article>Restaurant Review: The Smokaccia Laboratory - Phuket ★★★★★ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=668532026-01-07T12:34:36.000Z<p>You can't put a price on pure delight.</p>
<p>In Thailand you can get a perfectly decent Pad Thai and beer for a few hundred Baht. You can have an good pizza or freshly cooked burger for next to nothing. Food, in general, is cheap and cheerful. After a week of spring rolls and Tiger beer, we decided to treat ourselves to a fine-dining experience in the <a href="https://guide.michelin.com/us/en/phuket-region/phuket/restaurant/the-smokaccia-laboratory">Michelin recognised</a> Smokaccia Laboratory.</p>
<p>We opted for the nine-course(!) tasting menu - one regular and one vegan - with a pairing of both alcoholic and non-alcoholic drinks.</p>
<p>Let's get the cost out the way first - we paid around ฿16,000 (£380) and it was easily the best meal we've had anywhere in the world. The quality of the food even exceeded <a href="https://shkspr.mobi/blog/2023/02/restaurant-review-gauthier-soho/">Gauthier Soho</a> and the service was beyond that offered by the <a href="https://shkspr.mobi/blog/2023/08/restaurant-review-chefs-table-at-the-savoy/">Chef's Table at The Savoy</a>.</p>
<p>I'd like to walk you through the experience, so you can get a feel for <em>why</em> you should spend a ridiculous sum of money on several tiny portions.</p>
<p>As we entered the restaurant for our 18:00 reservation, we were greeted by name. It's a small thing, but it immediately made us feel warmly welcomed. There's was no awkward pause as a <i lang="fr">maître d'</i> looked us up in a list, just a confirmation of our booking and dietary requirements, then an invitation to sit in the lounge.</p>
<p>Would we like a glass of Prosecco or sparkling non-alcoholic cocktail while we waited? But of course!</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/01/Terry-and-Liz-at-Smokaccia.webp" alt="Terry and Liz drinking cockatils at Smokaccia." width="300" class="alignleft size-full wp-image-66856"/>
<p>We were then presented with a cigar box each. As we opened them, smoke gently wafted out filling our noses with a delightful scent. Nestled inside was a small amuse-bouche - a perfect cracker topped with caviar. My vegan alternative had veggie-friendly caviar and was exquisite.</p>
<p>The waiters and sommelier all introduced themselves to us as they explained the food and how the evening would proceed. We were given flannels which were freshly sprayed with a signature scent to accompany the next course - and then we were ushered to meet the chef.</p>
<p><a href="https://www.instagram.com/chef_lucamascolo/">Luca Mascolo</a> is a warm, funny, and gregarious host. He was eager to explain the concept of the restaurant and why each dish was created. He was passionate about ensuring that we had an amazing time and that the vegan food was equal in quality to the meat and fish dishes. Our first experience with his culinary madness was the "Campari bomb" - it <em>literally</em> exploded in my mouth and sent flavours dancing around my tongue. It is the first food that has actually made me giggle with childish delight.</p>
<p>This was swiftly followed by a tasting of the chef's tomato reduction. A perfect liquid appetiser.</p>
<p>We were guided to our table - we opted for the kitchen counter. There are several regular tables, but it was much more fun to be sat watching the magic of creation. Open-plan dining is nothing new, but the staff were so calm and synchronised that it felt like a meditative exercise watching them work in perfect unison.</p>
<p>The Smokaccia is the chef's signature focaccia. A fist-sized ball of bread, hard on the outside and impossibly pillowy on the inside. A sourdough creation of genius and perfect for soaking up the various oils and sauces served with the dishes.</p>
<p>What can be said about "An unusual event with Bertha"? I don't want to spoil the surprise so I'll just say this - I've never had a meal which made me laugh so much. Every moment - even reading the description - was pure joy. Why bother serving food in bowls when a ceramic egg-shell is much more fun! Almost as fun was watching it being served to other tables and seeing their reactions.</p>
<p>The truffle crunch was a little bite of ecstasy. This wasn't drenched in 2,4-dithiapentane - it was a perfect shaving of real truffle. To complement, I had the zero-waste potato dish. What kind of a chef thinks up potato ice-cream with red onion caramel? Again, either the chef or waiter came over to personally explain the order in which the dishes should be eaten and all the ingredients which went in to its construction.</p>
<p>Nearly all the food comes from Thailand - with the exception of the balsamic vinegar and wine (both from Italy) - so the food-miles are negligible. The basil and eggplant honestly tasted like they'd been plucked fresh from the dirt not five-minutes previously.</p>
<p>The vegan "foie gras" was next. Traditional foie gras is neither ethical nor sustainable, so this is made with local vegetables in an attempt to recreate the flavour and texture. It is described as containing a "blood explosion" and, as my spoon pierced the pineapple-glass, a pop of bright red "blood" spurted out! Again, a incredible moment of both food science, whimsy, and surprise.</p>
<p>It isn't <em>just</em> that every mouthful is delicious; the dining experience is pure theatre and filled with moments that make you gasp with delight. Such as the "fois gras" being served on a misty "lake" filled with pebbles and flowers, and then being presented with a "fortune cookie" from the goose.</p>
<p>There was a choice of "main" course although - as with any fine dining experience - it was barely more than a few bites. But <em>what</em> a few bites! Writing this, it seems silly to be so in love with a carrot but I don't care! I loved every nibble of that carrot mixed with kombucha and wasabi leaf. I grinned like a lunatic when the kombu/soy caviar pearls burst on my tongue.</p>
<p>A morsel of the most intense melon sorbet topped with bunt radicchio was the perfect end to the meal. A simple and fun palate cleanser. Of course there were further surprises in store!</p>
<p>There was a choice of desserts and both were vegan! Liz and I decided to get one each. I'm <em>fairly</em> sure that the impossible pistachio ice-cream was my favourite, but the dark chocolate and hazelnut was so precisely targetted to my taste-buds that I'd have to try them both again to make sure.</p>
<p>I wish I could remember all the tea options. Liz had the Tom Kah and I went for the ginger and honey. A little moment of calm in an over-exciting evening. We watched the chefs prepare dishes for the now-bustling restaurant.</p>
<p>It is amazing how full you can feel after eating just a few bites over two-and-a-half hours. I suspect the 18 course menu would have been overwhelming. How we found room for the petit fours I can't possibly imagine.</p>
<p>I do know how I found room for the liquid nitrogen "cooked" coconut though - humans have a separate ice-cream stomach. That's just science. Also, I've never had fermented watermelon rind before and I can't understand how my life has been complete without it.</p>
<p>Chef Mascolo kept making sure that we were satisfied, he was happy to chat about the processes behind the food and why he is so keen to bring a high-quality dining experience to Phuket. His home-brewed limoncello was far removed from the thick and sickly syrup which is usually proffered at the end of an Italian meal. This was a thin, light, and highly spiced twist on the classic. A perfect end to a perfect meal.</p>
<p>Of course, the restaurant still had some surprises for us - including a rather touching "thank you" and a cute little gift-bag to send us on our way. We were exhausted from smiling and laughing so much. Every single bite made us incredibly happy. Fine dining can be a serious and solemn experience - this felt like being in the playground of a mad professor who just wants to have fun with your taste-buds and your heart.</p>
<p>I'm not saying that you should stop what you're doing right now, fly to Phuket, and have the best meal of your life. I'm merely saying that if you value inventive food, prepared by a team of experts with an obsessive eye for detail, presided over by a man who obviously values creating an inclusive and joyful experience - then you should reserve a table now.</p>
<p>The Smokaccia isn't merely a food laboratory - it is a happiness laboratory.</p>
47 lessons - Werd I/O69580b8bdaa8db0001ea30db2026-01-07T10:00:28.000Z<img src="https://werd.io/content/images/2026/01/63b9b10bd4813cc0800958d2.jpg" alt="47 lessons"><p>Every year, for my birthday, I collect my thoughts. This year I want to share some things I’ve learned: one lesson for each year I've been around. You might agree or disagree with them; maybe a bit of both. But they’re ideas I’ve picked up that, at the very least, are insights into how I think. Maybe they’ll be useful to you, too.</p><p><em>Previous birthday posts: </em><a href="https://werd.io/46-books/"><em>46 books</em></a><em>, </em><a href="https://werd.io/2024/45-wishes"><em>45 wishes</em></a><em>, </em><a href="https://werd.io/2023/44-thoughts-about-the-future"><em>44 thoughts about the future</em></a><em>, </em><a href="https://werd.io/2022/43-things"><em>43 things</em></a><em>, </em><a href="https://werd.io/2021/42"><em>42</em></a><em> / </em><a href="https://werd.io/2021/42-admissions"><em>42 admissions</em></a><em>, </em><a href="https://werd.io/2020/41-things"><em>41 things</em></a><em>.</em></p><hr><h3 id="if-it%E2%80%99s-worth-doing-it%E2%80%99s-worth-doing-slowly">If it’s worth doing, it’s worth doing slowly.</h3><p>Every project, every major task, is worth taking your time over, both to plan and to do.</p><p>Most food cooks better if you do it with care, treating the ingredients, your tools, and the people who will eat what you’re making with respect. Most projects come together better that way too.</p><p>When I’ve rushed something together, I’ve almost always come to regret it.</p><hr><h3 id="you%E2%80%99ve-got-to-make-fucking-up-part-of-the-process-%E2%80%A6">You’ve got to make fucking up part of the process …</h3><p>Aiming for perfection is a trap.</p><p>Even if you take things slowly, you’ll get stuff wrong. It’s part of doing <em>anything</em> meaningful. So rather than planning your project within an inch of its life, the best thing to do is start small, build in tests so you can figure out if you’re on the right track, learn from them, build incrementally, and keep going. The earlier you can get outside feedback, or some kind of signal from the outside world about whether you’re doing the right thing, the better.</p><p>I have this slightly reductive metaphor I use for both writing code and English, and I think it probably works for any project of substance:</p><p>Think of your project as a corridor. You have a bouncy ball and you need to get it to the end.</p><p>You <em>could</em> spend a long time trying to get a steady shot that hits the wall at the end of the corridor dead on. But you could also bounce the ball off the walls all the way down. It’s maybe less elegant, it’s maybe messier, but you still hit the wall at the end. And you probably get there a lot faster, with a lot less stress.</p><p>Another way to put it is this: if you accept that you’ll be wrong, you’ll approach your problem differently to how you would if you assumed you were right. You’ll talk to people earlier, you’ll get outside feedback, you’ll run tests. Even if you were right, those aren’t bad things to do. Conversely, if you assume you’re right, you probably won’t do anything to de-risk your idea, <em>and you could still be wrong</em>. And then you’ll have burned a bunch of time on something that doesn’t hit the mark, which might not have happened if you’d approached it with humility instead of hubris.</p><hr><h3 id="%E2%80%A6-because-fucking-up-is-part-of-life">… Because fucking up is part of life.</h3><p><em>Life</em> is a project. You can assume you’ll do everything right or that you’re really smart, but that probably won’t get you very far. We all need feedback. We all need to learn and then course correct and then do it all over again. All we can do is iterate on ourselves.</p><hr><h3 id="saying-%E2%80%9Ci-don%E2%80%99t-know%E2%80%9D-is-a-superpower">Saying “I don’t know” is a superpower.</h3><p>It’s weird to me how many people <em>don’t</em>: they’ll try and give you directions even if they don’t know the way to a place, or they’ll spin their wheels forever instead of suffering the indignity of going out and asking someone.</p><p>The cool thing about admitting you don’t know, and just asking someone if you need to find something out, is that it leads to a different kind of conversation. If someone asks me something and I don’t know the answer, particularly if there’s a vulnerability to not having that particular piece of knowledge, telling them lets them know that I’ll be real with them. But more than that, it just gets me to where I need to be faster. I’m not wasting time on face-saving bullshit. And there’s precious little time to waste.</p><hr><h3 id="what-you-pay-attention-to-defines-you">What you pay attention to defines you.</h3><p>You are what you tolerate. But you are also what you notice, what you spend time with, and what you choose to dismiss.</p><p>If you allow your attention to be shaped and manipulated by someone else, you are what they are trying to make you to be.</p><p>Pay attention to your attention.</p><hr><h3 id="when-someone-shows-you-who-they-are-believe-them-the-first-time">When someone shows you who they are, believe them the first time.</h3><p>I originally thought this famous advice was maybe unfair: didn’t it prioritize knee-jerk assessments? But it’s not about snap judgments; it’s not <em>your</em> first reaction to someone. It's about paying attention when someone actively reveals their values to you. If someone <em>shows</em> you who they are, believe them the first time. And I’ve come to understand that <a href="https://www.snopes.com/fact-check/oprah-believe-them-quote/?ref=werd.io">Maya Angelou is right</a>.</p><p>Even the smallest red flags matter. The person who tells you the world would be better if men and women played to their gender’s strengths. The person who, on being inconvenienced by local rail drivers striking for better pay, exclaims that they can’t wait until they’re all replaced by robots. The person who is needlessly rude to a waiter or the person behind the desk at a coat check. These are the kinds of small exchanges that are indicators of a mindset that dictates how they show up in the world. It might seem kind to overlook them, but it’s wiser not to. There’s always something more.</p><hr><h3 id="you-are-what-you-tolerate">You are what you tolerate.</h3><p>What I mean by this is: if you allow something to continue, you help normalize it.</p><p>That goes big and small.</p><p>People often say this about management: if you tolerate mediocre work, your team becomes mediocre. And, sure, that’s important in a work environment.</p><p>But it’s also true in life. If you allow someone to regularly belittle you, you become belittled. If you allow someone to cause harm, you cause harm.</p><hr><h3 id="every-cry-is-a-message">Every cry is a message.</h3><p>When my son was a baby, I quickly learned that while babies can’t talk through words, they have a full spectrum of communication that, generally speaking, gets their point across. I’d assumed that babies were a little bit like that old app <em>Yo</em>, where the only notification you could send or receive was a one-note “yo”. That was so far from being true.</p><p>There’s no such thing as a cry that doesn’t have an underlying meaning, from the practical — I’m hungry, I’m uncomfortable — to the existential — I’m lonely, I need a hug.</p><p>We learn words, we pick up the cultural dressing of the society around us, but we don’t stop crying. Those underlying signals perhaps become more complicated as we age, but they’re still there, all around us as subtext behind what everyone says and does. There are the words, and there’s the message behind the words.</p><hr><h3 id="communication-is-a-muscle">Communication is a muscle.</h3><p>There’s a thing I learned from <a href="https://pointc.co/?ref=werd.io">Corey Ford</a>, which I think may have been inspired by some of the work <a href="https://connectandrelate.com/?ref=werd.io">Carole Robin</a> did on interpersonal relationships at Stanford’s Graduate School of Business.</p><p>Open, 360-degree feedback is vital on any high-performing team (or functional community). If you let friction between people linger, it tends to grow, and can sink the culture of a team; it’s the kind of thing that kills startups and leads to people leaving companies. You need to be able to bring things up and talk about it in a non-accusatory way.</p><p>That doesn’t come naturally. So you have to practice.</p><p>He’s got a great process that I’ve used for over a decade called <a href="https://pointc.co/the-one-on-one-gift-exchange/?ref=werd.io">the one-on-one gift exchange</a>. The details of it aren’t important here, although it’s worth checking out. He advises that you do it on a regular schedule, whether you have something specific to bring up or not. In doing so, you make giving and receiving feedback just a thing that you do regularly, and it makes it easier to give the hard feedback when it inevitably comes up.</p><p>All communication is like this. You’ve got to practice. And you’ve got to <em>keep</em> practicing, otherwise your communication skills atrophy. And it turns out that open, honest, bidirectional communication is essential to every kind of relationship, from business to families to romantic to friendships. Otherwise things build up and build up, and, if you leave them unaddressed, they snap.</p><hr><h3 id="be-careful-about-who-you-put-on-blast">Be careful about who you put on blast.</h3><p>I came from a context that didn’t matter: some guy writing code in Edinburgh, way outside of the centers of tech or media power. I got used to being critical about products and teams. Some of those criticisms were meaningful; some were not.</p><p>The first time this bit me was when I worked at Medium. At some company happy hour (there were a lot of those during the era I was there), I talked about how silly a <em>very</em> famous product design was. “I built that,” someone said. Over time, my voice became more influential, as I took bigger roles. Despite this increased attention, I sometimes continued to run my mouth over stuff that didn’t matter, offending people for no reason.</p><p>Some things <em>do</em> matter. If you’re colluding with fascists, destroying the environment, or causing active, obvious harm, you deserve to be called out. On the other hand, a design decision or a voice that you don’t quite agree with deserves a little more care. Every single thing is made by real people with real lives and complicated contexts. There’s a difference between speaking truth to power and dunking on someone’s work. Choose your targets carefully.</p><hr><h3 id="most-dinner-plates-can-hold-over-a-pint-of-water">Most dinner plates can hold over a pint of water.</h3><p>Ask me how I know.</p><hr><h3 id="plato%E2%80%99s-cave-is-real">Plato’s cave is real.</h3><p>If you’re not familiar with it, <a href="https://en.wikipedia.org/wiki/Allegory_of_the_cave?ref=werd.io">Plato’s allegory of the cave</a> goes something like this:</p><p><em>Imagine prisoners who have spent their entire lives chained inside a cave facing a wall. Behind them is a fire; their captors cast shadows from various objects and puppets. Because those shadows are the only things they’ve ever known, they’re reality for the prisoners.</em></p><p><em>Imagine, then, that a prisoner is freed and compelled to leave. They see the fire; because they’ve never seen light so bright before, they’re temporarily blinded. Then they’re dragged outside and the sun is brighter still. Eventually, as their eyes adjust, the world outside is clearer and more detailed than the shadows ever were.</em></p><p><em>So the prisoner goes back into the cave to free the others. It’s dark in there, so they’re blinded again. The prisoners infer that whatever’s outside must have hurt the freed prisoner. So the freed prisoner must have been corrupted and whatever’s outside must be dangerous. They’ll defend themselves from being freed and dragged outside themselves, potentially to the death.</em></p><p>Here’s where I’ve come to differ with the common understanding of the parable:</p><p>Each of us is in our <em>own</em> cave. We don’t have a shared reality; we all get our own shadows.</p><p>The dangerous bit of the story isn’t being in the cave or being freed. It’s going <em>back</em>, or never having been a part of that particular cave to begin with and wandering in to provide perspective. There are so many people who believe their context is the right one, that the shadows they’re seeing aren’t just reality, but comfortable and right.</p><p>Take it from a Third Culture Kid who’s moved around a bit.</p><p>The more caves you’ve seen and the more times you’ve been forced into the light by the gift — or shock — of another perspective, the clearer you can see the limits of any one view of the world. But that's scary as hell for the people who won't adjust themselves to the light, who want their version of the cave to be <em>everybody's</em>.</p><p>If you've only ever lived in one town, one state, or one country, you're seeing narrow shadows of how the world works. We all know the people in the cozy town who see the arrival of outsiders as a threat to their “way of life”. Geography, culture, and the assumptions of the people we connect with shape what seems natural, what seems possible, what seems inevitable, and it can make a new perspective — which, too often, is a new person — feel like a threat.</p><hr><h3 id="following-someone-else%E2%80%99s-template-is-fine-but-there%E2%80%99s-more-out-there-to-see">Following someone else’s template is fine, but there’s more out there to see.</h3><p>One of my favorite things is <a href="https://en.wikipedia.org/wiki/Psychogeography?ref=werd.io">psychogeography</a>: a way to explore built environments by taking arbitrary routes or following interpersonal, human-driven connections to places rather than taking a direct, logical route.</p><p>If you explore Venice, you’ll probably find the same tourist destinations as everybody else. That’s not nothing: they’re beautiful. But if you go and find, for example, the narrowest alleyway in Venice, you’ll leave the crowds, walk through neighborhoods where people actually live, and see more about the culture and nature of the city than if you’d stuck to the tour.</p><p>I would have earned a lot more money if I’d dedicated myself to engineering and just focused on software and product inside the tech industry. But it would have been a hell of a lot less interesting, and a hell of a lot less fulfilling. Meandering means going somewhere new.</p><hr><h3 id="the-templates-defend-themselves">The templates defend themselves.</h3><p>I’ve found that the more someone adheres to a template for living, the more affronted they are by people who <em>don’t</em> adhere to one.</p><p>There’s a kind of xenophobia that’s at the root of conservatism. If you feel like being “normal” is a moral good, then it follows that someone who isn’t normal is immoral. They’re to be feared — and, potentially, converted.</p><p>Most overtly, we see that in peoples’ reactions to trans people, to marriage equality, or to immigrants coming from other cultures or with minority skin colors. But it also manifests in smaller intolerances: the microaggressions that many people have to deal with every day. It’s not just MAGA; it’s the libertarian, predominantly male norms of the software industry, or New York City’s implicit dress codes.</p><p>I’ve sometimes wondered if these templates provide some stability for people who struggle with empathy, who find it difficult to imagine another human being’s interior life. If you don’t know how other people work, established patterns can be reassuring. Conversely, people who don’t fit into them are unsettling.</p><p>For some reason, I give off a kind of conventional vibe, which means people feel safe sharing these fears with me. The British accent, “safe” haircut, and slightly self-deprecating demeanor don’t scream “part-Indonesian multinational third culture kid who cares about undermining centralized systems of power”. But that’s what I am.</p><p>So I’ve had those encounters. The guy who, over a drip coffee in San Mateo, told me that the problem with the world is that women don’t know their place anymore. The one who, at a pub in North Oxford, said that, you know, he doesn’t know what’s wrong with Europeans. The manager with the pristine haircut who complained that people who want inclusion “want so many other things”. And why doesn’t everyone speak English?</p><p>Spoiler alert: I am not a safe person to have those conversations with.</p><p>I tend to feel sorry for people who feel like they have to abide by a template, but that ebbs away as soon as they advocate for someone else’s subjugation. The templates defend themselves. But everyone deserves to live on their own terms.</p><hr><h3 id="there%E2%80%99s-a-fine-line-between-knowing-your-limitations-and-living-your-life-with-a-fixed-mindset">There’s a fine line between knowing your limitations and living your life with a fixed mindset.</h3><p>It’s really easy to say things like, “I don’t do heights” or “I’m a bad public speaker” in the same register as “I can’t reach high shelves” or “I’m allergic to peanuts”. But they’re different kinds of things.</p><p>The first are surmountable. You might not be a good public speaker <em>now</em>, but most great public speakers had practice. The question isn’t, “<em>can</em> you be a good public speaker”, but “do you <em>want</em> to be?” Because if you do, and you put your mind to it, you probably can.</p><p>I started out by wanting to write for a career. I’ve been a software engineer. I’ve founded two startups. I was a <em>venture capitalist</em>, somehow. I was also a film reviewer and a barista. I’ve sworn blind that I couldn’t draw and have also drawn well. Everyone changes. We’re all in flux. We can all grow.</p><hr><h3 id="you-can-never-go-back">You can never go back.</h3><p>The only way out is through.</p><p>That’s true for industries and countries. We can wax nostalgic all we want about how it used to be, but (1) it probably never actually was exactly as we remember, (2) we can never go back there. Time doesn’t work that way. Even if we had a fully-kitted-out Delorean with a functional flux capacitor, our presence would change that reality. It cannot exist.</p><p>I sometimes find myself nurturing a kind of homesickness for different eras of my life. Some of them make me so sad that my chest aches. I miss people, I miss places, I miss the rhythms and values of my life back then. But I can’t go back. There’s no email I can send, no journey I can take, that will return me there. It’s more important to figure out what was so special about them, understand how important those values are to me, and make decisions about my future with them in mind.</p><p>And so much else. Rather than worrying about how the news industry used to be, we need to invent how it will be in the future. Instead of yearning for the glory days of the open web, we need to build something new. Instead of wistfully dreaming about a time before Donald Trump, we must prepare for the time after him. We all have to move forwards.</p><hr><h3 id="the-original-thomas-the-tank-engine-theme-will-dislodge-any-earworm">The original <em>Thomas the Tank Engine</em> theme will dislodge any earworm.</h3><p>Of course, <a href="https://www.youtube.com/watch?v=y-YRZHutDRk&ref=werd.io">then you’ve got another problem</a>.</p><hr><h3 id="every-system-should-be-designed-to-ensure-that-the-right-things-happen-in-the-hands-of-the-wrong-person">Every system should be designed to ensure that the right things happen in the hands of the wrong person.</h3><p>Most of the time, our work is in the hands of the right people. We make good decisions hiring, we bring new people we trust into our communities, and everything works well.</p><p>But sometimes that doesn’t happen. Maybe someone’s had a bad day, or they’re sick, or someone who doesn’t understand the context has to fill in for some other reason. Suddenly it becomes apparent that we don’t have systems of control: the most sensitive tasks don’t have safeguards that ensure the right thing happens. Our process has been based on norms and traditions rather than enforced checks.</p><p>These days, modern code is written using the Pull Request, a feature that was streamlined and therefore popularized by GitHub. Instead of an engineer just writing software into the codebase, they submit it as a change; another engineer checks it over and either requests changes or gives it the okay. Usually, an automated system also runs tests against it to make sure the code fits into the standards and guidelines of the codebase. The result is a system of control that has at least two levels of check: the human reviewer and the automated tests. Damaging mistakes can still happen, but far fewer than if you were writing code without oversight and uploading it directly to a production server.</p><p>Writing a rule, law, or process to contain a system of control isn’t a vote against the trustworthiness of whoever is responsible when it’s written. It’s a way of ensuring that whoever the <em>next</em> person is can’t abuse it.</p><p>There’s a lot that I could say about the second Trump administration. One way of looking at it is as a <a href="https://en.wikipedia.org/wiki/Penetration_test?ref=werd.io">penetration test</a> for American democracy: finding the parts of the American system of government that were held together with norms and traditions instead of well-defined systems of control.</p><p>That’s been the worst-case scenario. But the effect of every bad manager, every disgruntled employee, and every bad actor, big and small, can be mitigated by the same principle.</p><hr><h3 id="people-trust-people-not-brands">People trust people, not brands.</h3><p>It stands to reason. A brand is a business entity’s marketing identity, which inherently is designed to manipulate you into having a reaction to it. Why would you trust that?</p><p>One of the remarkable things I’ve observed in journalism is that a lot of people in the industry assume that the general public <em>should</em> love them. Journalism provides a lot of societal value, so the fact that trust in it is at an all-time low means the public needs to be educated about it. The reason they don’t trust it is they don’t know enough about it!</p><p>I want to play the <em>Family Feud</em> buzzer sound here. <em>Ehhh ehhh</em>. The reason people don’t trust journalism is that it’s talking past them, not to them, and it’s certainly not <em>listening</em> to them. They see the logos and the wordmarks, rather than a real human being taking the time to be real with them. The lesson of young people turning to YouTube and TikTok is not that young people love vertical streaming video, it’s that they’re tired of corporate bullshit and want to see a real human face meeting them where they’re at.</p><p>It’s a scary prospect for a newsroom, or for any organization. A brand is an identity for the full collection of people. In contrast, a real human face is someone who might not always be employed at that company. If a community has built up a relationship with a <em>person</em>, they may leave when the person finds a new job. The brand owners want to invest in relationships they can keep for themselves.</p><p>But the public doesn’t care about that. They just want to have an actual conversation with a person. They’re looking for human authenticity and a personality that doesn’t try to authoritatively dictate the truth to them.</p><p>We all just want to connect with people, not be marketed at. It’s about relationships and humanity. Community doesn’t care about your ligatures. It wants to be seen.</p><hr><h3 id="public-gratitude-is-a-reflection-of-who-you-think-is-important">Public gratitude is a reflection of who you think is important.</h3><p>If only managers receive public gratitude from leadership for a team’s accomplishments, then the culture prioritizes hierarchy and devalues the contributions of the individual contributors who actually do the work.</p><p>If only certain roles receive gratitude from leadership, then the culture only really values those roles, and sees other positions as subordinate.</p><p>Over time, if people are doing hard but thankless work, they’re unlikely to stick around, and the work will suffer.</p><p>Everyone who shows up to work is making a contribution. What you’re doing couldn’t happen without them. They’re three-dimensional people who care about their place in the community and want to be respected. So treat them like they are — and thank them.</p><hr><h3 id="everything-you-add-is-overhead">Everything you add is overhead.</h3><p>If you’re on a team that writes code, every codebase you write from scratch is something new that you have to maintain. Write enough of those without increasing the size of the team and you’ll find that everybody is in maintenance mode all of the time. (Self-hosting someone else’s code has a similar maintenance overhead.)</p><p>If you’re in a company that buys services, every new service you buy is something new that you have to pay for. Subscribe to enough of these and you’ll find that you’re financially underwater and it’s harder to weather downturns or find profitability.</p><p>If you add complications to your life, the emotional and administrative overhead adds up in similar ways. You might think you can take it on, and you probably can, but as the complications and responsibilities grow, so does the overhead of living. And suddenly you might find that you’re tired and stressed all the time. The trick is, it sometimes happens without you really meaning it to. Life accumulates.</p><p>The trick is knowing which kinds of overheads you can manage, and when.</p><hr><h3 id="if-you%E2%80%99re-making-something-you-need-to-understand-if-you%E2%80%99re-making-art-or-building-a-business">If you’re making something, you need to understand if you’re making art or building a business.</h3><p>I’ve written a lot over the years about how if you’re making a product, you need to know who it’s for, and make sure it actually solves someone’s problem. “Scratching your own itch” is something that open source developers in particular do a lot of, but if you do that, you may spend a long time, and potentially a lot of money, working on something and find out at the end that it doesn’t quite solve a problem for anyone but you.</p><p>But that doesn’t mean that there’s anything wrong with scratching your own itch.</p><p>I think it’s the wrong way to go about starting a business (be it a startup, small business, or non-profit). In those situations, you need to know who your customers are, you <em>do</em> need to understand if what you’re making is useful, and you do need to understand if anyone will buy or support what you’re building in the context of the model you’ve created for it.</p><p>But not everything has to be a business. Not everything has to be sustainable.</p><p>There’s a word for a creative act that is self-led in this way, regardless of whether the medium is code or words or paint or anything else: <em>art</em>. It’s always okay to make art. We need more art, all the time. Art is one of the core things that makes us human; it’s one of the core substrates that holds society together.</p><p>But you’ve got to know whether you’re making art or building a business: whether your center of gravity, your great adjudicator, is your customers or your heart. By understanding this, you’ve set up your own expectations, and you know which tools to deploy. With art, you can follow your heart more ambitiously. With customers, you can obsessively serve them. In both cases, you can cut the ambiguity.</p><p>It’s not that one is more valuable than the other. They’re just different things.</p><hr><h3 id="funding-isn%E2%80%99t-a-values-judgment-but-it-is-a-value-judgment">Funding isn’t a <em>values</em> judgment, but it is a <em>value</em> judgment.</h3><p>Back when I worked for Matter Ventures, we would have intense recruitment periods for our accelerator. For a few weeks, I’d work twelve hour days, sitting on a hard wooden stool at a homemade wooden table made out of a door, and listen to pitches from early-stage startups that hoped to obtain our funding. It ran the gamut from incredibly smart applications that I’d never seen before, through barely-there ventures fueled by magical thinking, to outright grifts.</p><p>A lot of first-time entrepreneurs were adamant that we should fund them because of their <em>values</em>. They were good people doing something ideologically wonderful in the world. They saw our investment like a magical grant.</p><p>But it <em>wasn’t</em> a grant. We were a mission-driven accelerator, investing in ventures with the potential to help create a more informed, empathetic, and inclusive society. But we were still a for-profit venture firm. We needed to invest in startups that had the potential to provide an exponential financial return. There were plenty of lovely people whose projects had lots of value — but we couldn’t fund them using our model.</p><p>When I was building Known, we couldn’t get investors to the point where they had conviction we would give them that return. They were very nice to us, and we had some good coffee conversations - but that’s where it ended. We couldn’t tell that story. The best founders pivot their startups until they’ve caught onto something that looks like it will grow quickly. That requires killing your darlings, as writers call it; letting go of the things you love that just aren’t working. That’s not what we chose to do.</p><p>Every venture fund is working for their limited partners (the people who put money into them). That’s most likely to be a <em>financial</em> return — ideally a startup will return a substantial multiple of the money that was invested into it — but it might also be a <em>strategic</em> return. (Consider why NVIDIA might invest in AI startups, or why the CIA might invest in social media - which, by the way, is a thing they do.) Every limited partner has a different agenda; every venture firm has its own investment hypothesis.</p><p>The same is true of non-profit grants, as it happens: donors put money into <em>them</em>, too, and they <em>also</em> have their own agendas.</p><p>None of it is a gift.</p><p>If you’re not raising money with the needs of the venture partners / non-profit funders and the agendas of the limited partners or donors in mind, you’re not taking it seriously. It’s not magic. It’s a financial transaction. You don’t get it because you deserve it; you get it because the funder thinks you’ll give them the return they need.</p><p>And of course, this is how power centralizes.</p><hr><h3 id="turning-it-off-and-turning-it-on-again-works">Turning it off and turning it on again works.</h3><p>Nine times out of ten, it’ll fix your computer problem. Really. Try it before you ask someone else. I’m begging you.</p><hr><h3 id="don%E2%80%99t-stay-up-too-late">Don’t stay up too late.</h3><p>You need sleep. You really do. You only think you don’t because you don’t physically drop dead or stop talking when you’re underslept. But you’re basically another person. Go to bed.</p><hr><h3 id="you-can%E2%80%99t-show-up-for-others-if-you-don%E2%80%99t-show-up-for-yourself">You can’t show up for others if you don’t show up for yourself.</h3><p>I’m not sure where it came from, but over time I developed a kind of shame just for being me: an underlying sense that there was something fundamentally wrong with me, but nobody would tell me what it was. It arrived one day when I was a teenager and never left. I imagined that there was a magic incantation that I didn’t know, but I could never be good enough. I’d never be worthy of the adulation I placed in other people; if I wanted to be liked, I needed to mask to be more like them. I desperately wanted someone to really see me and — despite that — know that I was okay.</p><p>The thing about feeling like you just need an ally, or someone who will tell you at last that you’re okay, is that it puts you in an incredibly vulnerable position. You don’t need someone who will tell you you’re okay; you don’t need a superficial ally. You need people who you can be in community with, who you can build relationships with over your life.</p><p>It creates vulnerability in another way, too. If you don’t like yourself, if you feel like you don’t matter, you can trick yourself into thinking that nothing you <em>do</em> matters, either. And there probably <em>are</em> people who care a great deal about you; consequently, what you do <em>does</em> matter. So you can make decisions that inadvertently hurt people you care about a great deal. You can fail to fight for relationships that have the potential to transform the entire fabric of your life. You can be passive about the stuff that really matters in life. You can find yourself in a place where you ignore your goals, values, and ideals.</p><p>So I’ve learned that you need to find ways to feel good about yourself; to respect yourself; to care for yourself. It’s not a selfish act. It allows you to show up in the way the people you care about need you to, which in turn allows you to build better relationships, better community with them. It allows you to take bets on yourself and build the life you really want to live. It allows you to be <em>you</em>, on a really fundamental level.</p><p>But if you don’t do that? The spiral is hard to escape from. The people you care about will tire of your disrespect. And those relationships may take years to repair.</p><p>Ask me how I know.</p><hr><h3 id="mid-life-aging-is-more-about-how-your-life-changes-than-your-body">Mid-life aging is more about how your life changes than your body.</h3><p>Yes, my metabolism is slower than it ever used to be. I’m definitely more tired. My back is a little more tense. I find it harder to shift into a creative mode.</p><p>But let’s look at how my life has changed. I have a much more demanding job and my time is less my own.</p><p>In my twenties I was the founder of a bootstrapped startup and could set my own parameters, including when I worked and when I didn’t. Nobody was checking my work except our customers: I had remarkable creative freedom. I didn’t have a kid, so I could walk seven or eight miles a day (and did). I hung out with friends more often, saw live music more often, went to the movies, and spent more of my life being active and having fun as a percentage.</p><p>I’m pretty sure that if I returned to that level of activity, my metabolism would increase. If I made more of a commitment to fun and had fewer parameters in my work, I would find it easier to shift into a creative flow state. If I was less stressed about money, I would sleep better at night. In fact, before my mother died, I was running 5K every day, and my body, my mind, and my <em>soul</em>, frankly, were all improving.</p><p>Let’s be clear: every body is different. Biology is real. But not <em>every</em> mid-life physical decline is inevitable. It’s that the demands on your time, your energy, your brain increase. There’s more overhead. And it takes a toll.</p><hr><h3 id="grief-lives-in-the-body-and-flows-like-tides">Grief lives in the body and flows like tides.</h3><p>For a long time after she died, I could hear the gentle click of my mother breathing through her cannulas. It followed me home to her house in Santa Rosa, and across coasts to my new home in Elkins Park. Sometimes I could hear the wheels of her feeding tube stand rolling across the floor.</p><p>These sounds lived in me. I couldn’t let them go. Not with all they represented.</p><p>We washed her, my sister and I, right at the end. A final act of care. But not one of goodbye.</p><p>My cousin warned me that the grief could sneak up and grab you, unsuspecting, and it did: I found that I had to pull off the road or hide myself in a public bathroom and let it out. I don’t know what other people made of the sound of my sobbing, if they heard it. It didn’t matter.</p><p>It had been a long journey. I’ve written about it from time to time, partially to explain myself, and partially to exorcise it. It doesn’t represent my mother, and shouldn’t, except in that she fought with so much life-force, and maintained so much good humor and kindness until the very end. I want to remember her smiling at a joke or angry about the world, not her prone fragility in a hospital bed.</p><p>Grief is just this: the loss of her, the loss of the family with her in it, the loss of her life and our lives and how everything was before we knew she was going to die. Some days, moving forwards is easy. Some days, the sadness ambushes you, and it’s all you can do to keep breathing. Every day, I feel it in my limbs, in a new heaviness to every day. If you cut me open like a tree I’m sure you’ll see it in my rings.</p><hr><h3 id="trauma-comes-in-layers">Trauma comes in layers.</h3><p>Grief is not the same thing as trauma.</p><p>The trauma is of seeing my mother in that bed, knowing she didn’t want to die in a hospital after that decade-long struggle, and not being able to do anything about it because the doctors she needed 20 liters of oxygen and she would have suffocated if we’d moved her.</p><p>It’s of learning what palliative care means, first-hand, and understanding that they would pump her with drugs and starve her until the end came.</p><p>It’s of seeing her at the bottom of the stairs and staying with her until the ambulance came.</p><p>It’s of yelling at her to wake up after the surgeon scraped off the crust around her lungs, her lips blue, her breathing shallow, and thinking this was really the end this time.</p><p>It’s of moving thousands of miles to be with her, sure she was about to die, sure that I would get the same sickness, and losing the person I thought I would spend my life with, not knowing if I had time left.</p><p>It’s of my cousins, and my aunt, and my Grandma. Everyone we have lost to this horrible disease.</p><p>It’s of, even now, not being able to dream about my mother, not hearing her voice except for the videos I took of her, except for that one time I heard her say, “oh my <em>God</em>, you guys,” clear as day in the dead of night.</p><p>It’s layered like rock, a thick crust of fight or flight burying layers of sadness and images that make me sit upright with my heart pounding.</p><p>I’ve only recently made peace with disrupting those layers and mining to its core. Losing the trauma is not the same thing as losing her. It’s not saying that she doesn’t matter; it’s not saying that any of the people we’ve lost don’t matter. Quite the opposite. It just says, it’s time to keep living. For them and for me.</p><hr><h3 id="vulnerability-needs-a-beat">Vulnerability needs a beat.</h3><p>Oversharing is real. Sometimes it can be too much. If you’ve found you’ve done that, you might need to retreat for a moment or two; reassure the person you’re talking to that everything is okay. That you’re <em>normal</em>, you know? You can follow the template too. You’re safe.</p><p>Not forever. Just for a beat. Masking is overhead, after all.</p><p>And then on we go.</p><hr><h3 id="those-little-paper-condiment-cups-unfold-to-four-times-their-size">Those little paper condiment cups unfold to four times their size.</h3><p>You know those little white cups from In-N-Out? You pull on their edges and they unfold and unfold. They’re surprisingly large! So much room for ketchup! Do you <em>need</em> that much ketchup? Maybe!</p><p>(You know about <a href="https://www.seriouseats.com/the-in-n-out-survival-guide-we-ate-every-single-item-on-the-secret-menu?ref=werd.io">the secret menu</a>, right?)</p><hr><h3 id="you-will-almost-never-regret-being-there-for-your-family-when-things-are-hard">You will (almost) never regret being there for your family when things are hard.</h3><p>I stood in Doctors, a real ale pub in Edinburgh that was never my favorite but was a short walk from the university buildings. I’d just presented at a tech meetup at the Appleton Tower, explaining to folks what Known did and why I thought the indieweb was important. I’d been back for a few days; I just planned to be in Edinburgh for a week.</p><p>Someone who I’d known for years — not well, just an acquaintance, but someone who I thought was generally smart and knew what they were talking about, more or less — was saying that she didn’t know why I’d left. “When they moved to California, they left <em>you</em>,” she said. “I would have said, ‘sorry, Mum, it’s your own fault.’”</p><p>I’ve played that conversation back in my head for years. At the time, I was so stunned that I didn’t have a real response. It was so far outside of my spectrum of values that I didn’t see it coming. Why would you say that to someone who had ripped their whole life up to be closer to their terminally ill mother? Why would you even <em>think</em> it?</p><p>I did do those things. When I was thirty-two years old, I moved to California for what I thought was a temporary visit. I ripped my life apart in the process.</p><p>When I was twenty-three years old, nine years earlier, my parents moved to California to be closer to my Oma. It seemed like a no-brainer. Of course you’ll be there for your family. We’re close. We love each other. We’ll support each other.</p><p>My move was a decision point: I didn’t know, exactly, where my life in Edinburgh was going. It could have gone to amazing places — and it also might not have. I knew that if I had chosen not to be with my mother during her illness, I would probably have regretted it. It was going to be seismic, but I needed to go.</p><p>But that person’s voice. I do think about it. If I’m honest with myself, it dovetails with my own middle-of-the-night anxieties. Should I have stayed?</p><p>I lost the person I was with at the time, who I hoped I’d spend my life with. That loss was devastating; the move itself was devastating. I loved my old life. But in comparison to not being there when Ma was struggling?</p><p>So, no. I did the right thing, even if I suffered a loss in the process. I’m grateful I was able to spend that time with my family. I was able to take Ma for walks and sit around the dining room table and give her hugs at the end of the day and help her brush her teeth when she was too weak to get out of bed. I was there. I am glad I was there.</p><hr><h3 id="put-the-kids-first">Put the kids first.</h3><p>If you arrange your parenting for your convenience rather than their well-being, they’ll feel it.</p><p>For example, I’ve found that if I get up as soon as he falls asleep, and he wakes up twenty minutes later to find himself in a dark room by himself, he’s scared in the moment, but trust has been eroded over time. Yes, eventually he needs to sleep by himself, but also, he’s three years old. There’s time. And I did it enough times that he now asks me, plaintively: “do you promise you’ll stay with me?” The first time he asked broke my heart.</p><p>I used to love traveling for work: when I was based in the Bay Area I’d go to New York City for long trips and love exploring in the cracks between commitments. I’d walk across the Brooklyn Bridge and find little shops in small corners; psychogeography the shit out of that place. And there would be all kinds of conversations I’d get to have as a result: meeting people for a coffee here, for a beer there.</p><p>But now I have a little guy who doesn’t understand why I’m going away, and who misses his daddy. It makes him nervous. He doesn’t FaceTime for long, but I’ve been told he’s obviously depressed when I’m not around. I still love traveling, and as he gets older I’ll find ways to bring him with me. But until then, I need to minimize the trips. I need to stay in bed and give him a hug. I need to spend the time.</p><hr><h3 id="strict-parenting-is-bad-parenting">Strict parenting is bad parenting.</h3><p>When you set up high expectations and rigid rules, you’re not creating the conditions for a child to grow up into their own person. You’re effectively setting up a template and punishing them when they meander from it. Worse, you’re taking a still-developing human, who doesn’t understand their own emotions yet and hasn’t developed strong communication skills, and you’re ignoring the underlying needs and feelings that form the subtext of their behaviors. In a real way, you’re ignoring their humanity.</p><p>Having a child has taught me to look for the signs of sadness, of quiet worries, of not feeling well behind what a strict parent might call “acting out”. Every time he throws something or ignores something I ask him to do, if I remember to pause and really ask him about it, I’ll find that there’s something he isn’t saying — or at least, not saying with words. We can usually have a good conversation about it, and then a hug. It builds trust. He knows I’m looking out for him. I see him.</p><p>And then, of course, there’s the parents who hit their children. That’s the version that’s unambiguous abuse. It’s a caveman approach to nurturing a human being that I think says a lot more about the emotional intelligence and capabilities of the parent than it does the child. They’ll often justify it in weird ways, by saying things like, “I was smacked and it never hurt me.” There often seems to be a kind of defiance to it. But guess what? <em>Not</em> being smacked would have hurt you <em>less</em>. I bet pausing for a beat and digging into how they feel would be revealing, too.</p><p>Parenting is hard. It can try your patience. But I can’t imagine hitting my child and wanting him to be anything less than his own person, free from everybody’s templates and expectations. Part of keeping him safe is keeping him safe from anyone who would seek to subjugate his spirit. And if anyone ever tries to hit my kid, I’m calling the police.</p><hr><h3 id="walking-fixes-more-than-you%E2%80%99d-think">Walking fixes more than you’d think.</h3><p>When I’m stressed, or feeling under the weather, or having trouble thinking my way around a problem, I’ve found that going for a walk is the best thing I can possibly do. It takes me out of my context, it allows me to blow off steam, and it puts me in a relatively isolated state where I have fewer distractions or inputs. It’s its own form of attention, in a way; its own way of being in the world.</p><p>It’s also really good exercise, particularly if you do it briskly: a 15 or 16 minute mile is a decent walking pace. As a bonus, it’s even <em>better</em> for blowing off steam at that speed.</p><p>My opinion: if you don’t live somewhere where you can walk outside easily, move.</p><hr><h3 id="get-that-milkshake">Get that milkshake.</h3><p>My trauma therapist and I have a shorthand: she tells me to <em>get that milkshake</em>.</p><p>What it means is this: sometimes it’s important to go do something nice for yourself. You don’t need to ask permission; you can just do it.</p><p>Life can be a lot. And I happen to like milkshakes. So sometimes, quietly, when I need a treat, I go and get one, guilt-free.</p><hr><h3 id="cows-are-benign-philosophers">Cows are benign philosophers.</h3><p>I think they have a lot more going on than they let on, is all I’m saying.</p><p>Don’t believe me? Talk to one. It’ll listen.</p><p>There used to be a cow field between my home and the center of town. I’d walk through it twice a day, stepping over the cattlegrid and dodging the cyclists who zoomed past. The cows were curious and friendly; they would come and investigate what you were up to.</p><p>There was another field that lay far below the Marston Ferry Road, back in Oxford, where I grew up. You could stand against the fence at the road and the cows would look up to see you. If you stayed there for long enough, they would congregate around you, as if you were the Pope. Perhaps they were hoping I’d feed them. I’d like to think they thought I might have something to say.</p><hr><h3 id="optimize-for-community">Optimize for community.</h3><p>I’ve made two major moves in my adult life: once to California, and once, after my mother died, <em>away</em> from California, to the area outside of Philadelphia. It was lonely.</p><p>To have a friendship — a real one, not a warmed-up acquaintanceship — is to have built a non-romantic relationship where you really see each other. Neither wants anything from the other; there are no romantic or sexual expectations, or really expectations of any kind except that you’ll be there. It’s a relationship of shared support, values, and community.</p><p>Without it, you wither. People who don’t have friends <a href="https://www.cnn.com/2023/06/19/health/loneliness-social-isolation-early-death-risk-wellness?ref=werd.io">die earlier</a>. And while the internet can help you keep in touch with people you have moved away from, there’s no real alternative to having that mutual support <em>there</em>, with you, in the flesh.</p><p>But everybody moves. It’s not realistic to stay in the same place your whole life. People get jobs, family members get sick, people get priced out of their communities, there’s a Brexit. All kinds of things happen. So staying in one place is not a foolproof solution.</p><p>The thing, then, is to look for new places with community in mind. Where are you going to find like-minded people? Who are the people who see you now, and what kinds of places do they hang out in? Where are the comparable places in your new geography? Where are your people?</p><p>For me, that means finding the bookstores; the community spaces; the outsider arts events; the live music and the weird between-the-cracks culture. Find the people who don’t want to live to someone else’s template but do want to be kind. That’s where the good stuff is.</p><p>And given the choice between choosing a beautiful house in the middle nowhere and a lackluster apartment in a place where you have community, I’d pick the place with community. It’s going to make your life better. It’s going to make <em>everything</em> better. Community cuts to the core of what life <em>is</em>; a house is just a house.</p><hr><h3 id="culture-is-about-the-intersections-between-people">Culture is about the intersections between people.</h3><p>My Oma taught me to cook. She <em>loved</em> to make food; often she’d be thinking about the evening meal throughout the entire day, regardless of whatever else was going on. In her nineties, she moved in with my parents, and although her love of cooking hadn’t diminished, her ability to stand over a stove had. So I helped her.</p><p>She was part-Indonesian, so the first dishes I put together started with spice mixes of turmeric, coriander, ginger, garlic, onion, and chillies. Indonesians call this the <em>bumbu</em>: a spice paste that can form the basis of many dishes.</p><p>You’re meant to make them with shallots, not onions. There’s supposed to be galangal rather than ginger; candlenuts are common. But those things weren’t easy to get in the San Joaquin Valley back then, so she made do. Sometimes she used milk instead of coconut milk; sometimes she couldn’t find <em>ketcap manis</em>. And it was always fantastic anyway.</p><p>You can improvise. You can use available ingredients. You can work with what you have and make the result your own, instead of trying for an unchanging perfect ideal. That’s how culture changes and ebbs and flows. I still make Indonesian meals, but they’re different to how my Oma did it, and the way I teach my son will be slightly different to how I learned. And so it goes, forever.</p><p>The important thing was the making and the eating, the gift of food and the sharing of it, not the verbatim copying of a version of a dish. There’s skill and craftsmanship in doing that, but that’s not where the <em>life</em> is.</p><hr><h3 id="revisiting-homemade-food-from-your-childhood-is-usually-amazing-revisiting-restaurant-food-from-your-childhood-rarely-holds-up">Revisiting homemade food from your childhood is usually amazing; revisiting restaurant food from your childhood rarely holds up.</h3><p>One was made with love, which still shines through the recipe; by following the same path, even if you substitute some ingredients you’re making it with love <em>again</em>. The other is just a product. The ingredients have changed over time; the portions are slightly different <em>for business reasons</em>; it’s missing the context and the smells. It’s generally better to let those memories sit.</p><hr><h3 id="if-you-have-a-fear-of-flying-playing-the-muppet-show-theme-on-takeoff-really-takes-the-edge-off">If you have a fear of flying, playing <em>The Muppet Show</em> theme on takeoff really takes the edge off.</h3><p>And post about it on the internet. Then, if something happens, people can point at your post, nod to themselves sagely, and say, “he died as he lived.”</p><p>I like <a href="https://www.youtube.com/watch?v=oiMZa8flyYY&ref=werd.io">the OK Go cover</a>, for what it’s worth.</p><hr><h3 id="show-your-working">Show your working.</h3><p>I remember taking my high school exams in the gym, individual chairs placed in rows atop wooden floors that smelled faintly of feet. You could hear breathing; the occasional cough; the squeak of rubber on hardwood as the invigilator roamed the aisles.</p><p>Showing your working was vital. Your answer to a math question could ultimately be wrong, but if your <em>thinking</em> was along the right lines, you’d pick up some points. They didn’t want to teach us by rote; they wanted to teach us how to navigate problems.</p><p>All of my best professional experiences have been derived from showing my working. When I started Elgg, every success was because we blogged how we were thinking about it; before we’d written a single line of code, before we <em>knew</em> we’d write any code, we’d talked about why it was important. People were attracted to the product, sure, but more than that, they were attracted to the ideas behind the project. And when we were wrong, they let us know — kindly. It helped us learn and grow.</p><p>That principle has continued to this day: to, in fact, you reading these words right now. Every time I share how I think, I make connections that I might not have otherwise. It’s helped me build community, land jobs I never would have landed, and find myself in rooms that would otherwise have been closed off to me.</p><p>The more you share of who you are, how you think, what you care about, and what your skills are, the easier it is for other people to find you, and for you to build connections and relationships. That doesn’t mean put yourself at risk: I’m not about to publish my home address here or reveal precise details about my kid. But there’s a lot you can say about yourself if you work in the open.</p><hr><h3 id="people-join-movements-for-different-reasons-not-all-of-them-are-good">People join movements for different reasons. Not all of them are good.</h3><p>In the early 2000s, a bunch of early web users, including me, wanted to tear down traditional gatekeepers: publishers who dictated whose voices could and couldn’t be heard, politicians who didn’t listen inclusively to communities, the traditional structures of power that maintained their own dominance, only including people who didn’t come from those hierarchies if they were deemed to be useful or compliant. So much of the early web movement was about creating a more participative world.</p><p>And then it turned out that some of those people saw an opportunity to insert <em>themselves</em> as gatekeepers. People like Mark Zuckerberg created vast companies that, in time, came to intermediate and charge rent for more than those old gatekeepers ever had. They sought to own aspects of our lives, like talking to our friends, that previously had been free from intermediation. The way for their companies to grow was to encroach upon the cultural commons. The gates they built became more and more powerful over time. As they calcified, some of them became templates that came to govern the rhythms and tenor of everybody’s lives.</p><p>Some did not. Others built the indieweb, and the free software movement, and found ways to undermine the control of these new gatekeepers. They stayed true to the values of the movement.</p><p>I tried to be one of them. Early in my career, I saw that ed-tech companies were milking giant contracts from tax-funded universities, while delivering software that didn’t do much to help people learn. Elgg was a direct response to this; it was fueled by a deep anger at the people who would seek to strip-mine a public good. Known, my second open source platform, was aimed directly at people like Zuckerberg. They were both attempts to undermine centralized wealth and power. That’s what drove me, and I have no regrets.</p><p>I have learned to look for the people who tear down gates for good, who try and foster new co-operative, participative movements in their place. They’re always there, even if they are not the most prominent voices in the room. And together, there’s a lot we can still do to make the world better.</p><p>Someone joining the movement for the wrong reasons doesn’t invalidate the movement. It just makes the work even more important.</p><hr><h3 id="to-write-read-with-impunity">To write, read with impunity.</h3><p>Yeah, sure, read the “good” stuff. I love literary fiction. <em>The Color Purple</em> is my idea of a perfect novel. I just finished <em>I Who Have Never Known Men</em>, which is an astonishing novel that plumbs the depths of what it means to be human, written with poetry.</p><p>But you can read whatever you want. All inputs are worthwhile. Pulpy airport thrillers have brought me through some hard times. Fan fiction has struck a nerve that I never knew existed. Some of the most well-crafted writing I’ve ever read was published on a style-free website, tumbling onto the page in 12-point Times New Roman. It’s all good. All of it.</p><p>If you want to write, the only imperative is to read.</p><p>That’s certainly true for my long-form writing, and that might be advice you’ve read before. But it’s true for my short-form writing, too. If I haven’t dug into a book lately, my blogging suffers. Even my writing at work — emails and process documentation are hardly the bastion of literary prowess at the best of times — is less inspired.</p><p>Read voraciously. It’s fuel.</p><hr><h3 id="fight-for-the-relationships-that-matter">Fight for the relationships that matter.</h3><p>“There are other fish in the sea,” the aphorism goes. But when you’re in a relationship where things aren’t going perfectly, I think it’s better to assume there aren’t.</p><p>I don’t mean that you should stay in an abusive or untenable situation. If you are being harmed and there’s no chance of living in harmony, then, absolutely, you need to get out of there. But if it’s just not quite right, or if circumstances have become obstacles, I think there’s a lot to be gained by fighting for it. At least until you’ve determined that there’s no possible way forward.</p><p>This is where, in my life, not showing up for myself has sometimes allowed me to fall into a defeatism that has caused me to give up early. “Of <em>course</em> this won’t work,” I think to myself. I’m the through line to the failure. I shouldn’t assume that someone would want to be with me. They’ll be better off without me.</p><p>The result is giving up on people who really care and situations that could last a lifetime. It’s not a given; nothing is. But there’s a real scarcity to people that are really compatible with you. (Or, I should say, there’s a real scarcity to people that are really compatible with <em>me</em>.) So, while it’s worked out for me in the end, I have sometimes wished I would have fought harder, and <em>not</em> assumed that eventually everyone will want someone better.</p><p>I don’t think you can show up well in a relationship without assuming it’s the only relationship on earth that will ever be important to you. It’s got to have fire. It’s got to have <em>stakes</em>.</p><p>It’s got to matter.</p><p>And if you give up without fighting for it, it doesn’t.</p><hr><h3 id="make-the-dumbest-jokes-imaginable">Make the dumbest jokes imaginable.</h3><p><em>Q: Why did Pierre-Joseph Proudhon only drink camomile tea?<br><br>A: Because all proper tea is theft.</em></p><p>C’mon!</p><hr><h3 id="you-contain-multitudes">You contain multitudes.</h3><p><a href="https://www.poetryfoundation.org/poems/45477/song-of-myself-1892-version?ref=werd.io">Walt Whitman</a>:</p><blockquote>Do I contradict myself?<br>Very well then I contradict myself,<br>(I am large, I contain multitudes.)</blockquote><p>A single person holds many conflicting identities, roles, beliefs, and experiences; our selves are complex and ever-changing. There is no singular, static definition that we can use to capture any person.</p><p>We’re not making art or building a business, because there’s no way to separate the self cleanly into those categories. We’re not our professional titles and our personal contexts, because those things are inseparable. We have no way of surgically extracting pieces of ourselves, or freezing them and framing them, unchanged. We’re always learning, always growing, always making connections between the things we know, the things we’ve felt, our flaws, our traumas, our successes, our pride, the things we’ve done and haven’t done. In everything we do and everywhere we are, we are all of ourselves.</p><p>When we build walls, we build overhead, and we keep building overhead until it’s impossible to maintain and it all comes tumbling down. A single cave’s shadows can’t capture a whole person.</p><p>Better, then, to understand that we are our whole selves, and to respect that in ourselves and in the people around us. We are smart and brave and silly and stupid. We are strategic and impulsive. We must be allies for each other. In a world where we are asked to refine ourselves down into digestible metadata for the benefit of machines and algorithms, we must celebrate our full humanity.</p><p>Bring your full self to work. Bring your full self home. Only when we’re allowed to be intact, with a community built on mutual sight and support, can we live sustainably: our overheads manageable, our wounds tended to, our victories celebrated.</p><p>And we all deserve to live sustainably. We all deserve to be supported. We all deserve to be well. We all deserve to live with our full, changing, contradictory identities out in the open, unmasked.</p><p>So let’s.</p><hr>App Defaults 2026 - Robb Knight • Posts • Atom Feedhttps://rknight.me/blog/app-defaults-2026/2026-01-07T08:44:45.000Z<p>It's been a couple of years since my <a href="https://rknight.me/blog/app-defaults/">first post in this series</a>. <a href="https://rknight.me/blog/app-defaults-2024/">In 2024 I did</a> an "updates only" list but I think it's worth going for a full list again this time.</p>
<ul>
<li>📨 Mail Client: Apple Mail still. Email sucks, I don't need it to be better I need it to go away.</li>
<li>📮 Mail Server: iCloud with custom domain.</li>
<li>📝 Notes: Obsidian. I've just done a big reset of all my notes and I'm following <a href="https://stephango.com/vault">Steph Ango's</a> structure somewhat.</li>
<li>✅ To-Do: Journal for untimed things, Reminders for timed.</li>
<li>📷 iPhone Photo Shooting: Camera.app</li>
<li>🟦 Photo Management: Photos.app</li>
<li>📆 Calendar: Fantastical</li>
<li>📁 Cloud File Storage: iCloud Drive</li>
<li>📖 RSS: <a href="https://miniflux.app/">Miniflux</a> with <a href="https://reederapp.com/classic/">Reeder Classic</a></li>
<li>🙍🏻♂️ Contacts: Contacts.app</li>
<li>🌐 Browser: Safari</li>
<li>💬 Chat: Discord, Signal, IRC</li>
<li>🔖 Bookmarks: <a href="https://www.linkace.org">LinkAce</a></li>
<li>📑 Read It Later: <a href="https://raindrop.io">Raindrop</a></li>
<li>📜 Word Processing: what</li>
<li>📈 Spreadsheets: Numbers</li>
<li>📊 Presentations: Keynote if I have to but I never do</li>
<li>🛒 Shopping Lists: Alexa lists, reminders</li>
<li>🍴 Meal Planning: Journal</li>
<li>💰 Budgeting and Personal Finance: Numbers</li>
<li>📰 News: Nope</li>
<li>🎵 Music: Apple Music scrobbled to <a href="http://Last.fm">Last.fm</a> with <a href="https://replay.software/sleeve">Sleeve</a></li>
<li>🎤 Podcasts: Overcast</li>
<li>🔐 Password Management: 1Password, begrudingly.</li>
</ul>
<p>When this post is added, that will be <em>five hundred</em> blog posts on the <a href="https://defaults.rknight.me">App Defaults</a> website. You should go and listen to the episode that started it all, <a href="https://listen.hemisphericviews.com/097">097: Duel of the Defaults</a>.</p>Logitech Options+ Alternatives for MacOS - Robb Knight • Posts • Atom Feedhttps://rknight.me/blog/logitech-options-alternatives-for-macos/2026-01-06T23:29:22.000Z<div class="markdown-alert markdown-alert-note"><p class="markdown-alert-title"><svg class="octicon octicon-info mr-2" viewBox="0 0 16 16" version="1.1" width="16" height="16" aria-hidden="true"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"></path></svg>Note</p><p>Logitech is called "Logi" in some markets but not all of them and to be honest I don't care enough to work out which is "correct" in this case.</p>
</div>
<p>As of this moment <a href="https://www.logitech.com/en-gb/software/logi-options-plus.html">Logitech Options+</a>, the app that handles all the features for my Logitech MX Master mouse, is down. It connects to Logitech's server for some stupid reason but if said server is down then my mouse doesn't work properly. Very cool and normal.</p>
<p><a href="https://rknight.me/notes/202601062305/">I posted about this</a> and <a href="https://rknight.me/notes/202601062305/">Reilly</a> was all over it suggesting <a href="https://linearmouse.app/">LinearMouse</a>. I downloaded it and it's an almost-exact replacement for the Logitech crap with the exception of gestures. In Options+ I could set <kbd>thumb button</kbd> + <kbd>swipe</kbd> to switch between spaces (or in my case, my single full screen app - the Music app). As a workaround, I set LinearMouse to use <kbd>⌘</kbd> + the back/forward button to do the same thing.</p>
<figure><img src="https://cdn.rknight.me/site/2026/linearmouse-settings.jpg" alt="The LinearMouse settings window showing my custom button actions" /></figure>
<p>The Logitech software has always been shit but I could live with it but not being able to use my mouse because servers are down? Fuck right off.</p>
<p>Anyway, I <em>had</em> started collecting alternatives while I was putting Baby Knight II to bed but given LinearMouse does everything I need, I won't be trying them but here they are:</p>
<ul>
<li>Logitech have an <a href="https://prosupport.logi.com/hc/en-us/articles/10991109278871-Logitech-Options-Offline-Installer">offline-only version for IT admins to use</a>.</li>
<li><a href="https://better-mouse.com/">BetterMouse</a> - this one looks like it has <em>all</em> the options.</li>
<li><a href="https://plentycom.jp/en/steermouse/">SteerMouse</a></li>
<li><a href="https://macmousefix.com/en/">Mac Mouse Fix</a></li>
</ul>Note published on January 6, 2026 at 3:56 PM UTC - Molly White's activity feed695d30a8e5bd0603bc0d73b12026-01-06T15:56:24.000Z<article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>i love the beginning of the year because everyone starts blogging. and if you (yes you) were thinking about starting, this is your sign</p><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp-block"><div class="timestamp">Posted: <a href="https://www.mollywhite.net/micro/entry/202601061055"><time class="dt-published" datetime="2026-01-06T15:56:24+00:00" title="January 6, 2026 at 3:56 PM UTC">January 6, 2026 at 3:56 PM UTC</time>. </a></div></div><div class="social-links"> <span> Also posted to: </span><a class="social-link u-syndication twitter" href="https://twitter.com/molly0xFFF/status/2008568340852162609" title="Twitter" rel="syndication">Twitter, </a><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/115848969233248224" title="Mastodon" rel="syndication">Mastodon, </a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mbrcvvqz2m27" title="Bluesky" rel="syndication">Bluesky</a></div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/blogging" title="See all micro posts tagged "blogging"" rel="category tag">blogging</a>. </div></div></footer></div></article>How I hire engineers - Werd I/O695d1689e237e00001e652502026-01-06T14:07:35.000Z<img src="https://werd.io/content/images/2026/01/getty-images-6nxco-PPKQU-unsplash.jpg" alt="How I hire engineers"><p>I once helped out a startup where the departed CTO had come up with what he thought was a clever way to hire engineers. He’d find people who performed very well on coding challenges — he used something like <a href="https://leetcode.com/?ref=werd.io">LeetCode</a> — but suffered when they were evaluated for their communication skills. He didn’t need great communicators, he reasoned; he needed people who could program really well.</p><p>What a disaster.</p><p>The result was an engineering team that could program <em>reasonably</em> well, but were utterly disconnected from the needs of the business. They had a hard time both understanding customer needs, because they weren’t having those conversations, and advocating for themselves when something that was being asked of them was going to be infeasible. The rest of the business treated them as a back office that was handed tasks that they were required to implement rather than a technical partner that could help them figure out elegant solutions.</p><p>The engineers were miserable. And the rest of the business thought they were incompetent.</p><p>When I arrived, what they asked me for was an excellent product management team. There’s a fallacy, which I’ve encountered in a few places, that if an organization has amazing product managers, <em>they</em> will determine exactly what it is the engineers should be doing, will prioritize tasks, and just tell them what to do. Their dream was that they could just get on with coding — their core skill — and outsource the needs of the business to someone else.</p><p>It never, ever works like that. And it shouldn’t. While it’s true that product managers are there to be the stewards of the product’s vision, strategy, and roadmap, they are <em>stewards</em>, not dictators. They get there in collaboration with engineering and design, as well as other stakeholders. At no point do they just dictate what other people will do and absolve engineers from doing that work.</p><p>The engineers need to be the technical experts across infrastructure, back-end, front-end, and technical architecture; the designers need to be experts in research, experience, interface, and information architecture. It makes sense that an engineer who finds communication and collaboration hard would just want to be told what to do, but a company that worked that way would be squandering its experts.</p><p>Sometimes, very large companies — I’m talking about the Googles and Microsofts of the world — get to hire very deep technical experts in a rare skill. Those people often <em>will</em> go very deep on one thing and act as either a technical consultant or a deep-tech academic researcher for the rest of the company. The rest of us need to hire people with great communication skills who can be strong collaborators and figure out product problems as part of a group of people with different skills and competencies.</p><p>So let’s talk about how I do that.</p><h3 id="hiring-principles">Hiring principles</h3><p>I think of every team as a community: it’s a group of people who are setting out to achieve a common goal. Granted, it’s not an <em>organic</em> community — everyone’s being paid, for one thing — but the dynamics of any functional community apply.</p><p>I think communities work best when:</p><p><strong>Everyone is invested in the same mission.</strong> Even if their individual goals and values diverge, they’re here to achieve the same thing. It’s not (just) about the paycheck; the work itself has meaning for them. This is particularly important in startups and mission-driven environments where there can be speed bumps in the work itself.</p><p><strong>Communication is open and kind.</strong> Most startups fail because of preventable human dynamics; that’s also true of teams in other kinds of organizations, like newsrooms. You can’t let friction linger. That means giving and receiving feedback openly. It also means <em>thoughtful</em> communication: speaking inclusively and making sure that conflicts are productive instead of aggressive. Nobody needs to work with shouters, or people who belittle their lived experiences or identities. I’m a big believer in <a href="https://hbr.org/2007/03/why-i-wrote-the-no-asshole-rule?ref=werd.io">the no asshole rule</a>.</p><p><strong>Everyone is treated fairly.</strong> If you don’t have an inherent sense of fairness in a community, resentment will build. That means making decisions based on systems rather than whims, so that they’re predictable and observably free of favoritism or bias. It also means making sure that people are compensated fairly for their skills: if someone’s core engineering skills are underdeveloped compared to someone else who’s being paid the same, that will clearly build resentment.</p><p>When we <em>grow</em> these communities, I think it’s important that every single person we add brings an underrepresented perspective and an underrepresented skill. As an individual, they should add to the whole. And then those skills and perspectives need to be respected in the course of the work. If someone comes from a particular community and has an opinion about why the business is not going to land for them, or, worse, is harming them — the business needs to listen.</p><h3 id="the-test">The test</h3><p>I’ve made an explicit choice not to use LeetCode-style tests <em>or</em> do live coding interviews. I don’t believe that either is representative of the real work.</p><p>In both cases, what you’re testing is someone’s ability to recall algorithms and data structures in a high-stress, live setting. It’s closer to a university exam than anything that might happen on a real-world engineering team. In reality, the work — when it’s done well — is contemplative and reflective. While it’s very important to determine what someone’s core technical skills actually <em>are</em>, I’m much more interested in learning how they perform in that more reflective context.</p><p>So I’ve arrived at a take-home test.</p><p>These are controversial, too: they’re often time-consuming in a way that’s unfair to the participant. At their worst, they ask you to do real work that the business needs, on an unpaid basis. Some organizations have pivoted to actually bringing the person in for a day and paying them for it, but I don’t think that’s a great test either: everybody is deep in onboarding at the start of a new job, so you’re expecting them to leapfrog over the weeks-long stage when they’re in learning mode. It also rules out people who have an existing job or other commitments that make a random day-long engagement impossible.</p><p>My take-home tests give the participant seven calendar days to return them, and ask the participant (on the honor system) to spend no more than two hours on them. The goal isn’t to get something with finish and polish; it’s to spend a little time demonstrating the way they think. It’s always a relevant problem to the business but never something we would actually use in production.</p><p>One test I’ve used a few times at ProPublica (and I guess now won’t again!) is to ask an engineer to build an unsettled, HTML-only version of the site, using its RSS feed as a de-facto API. Getting to a prototype here is not hard: you use an RSS parser library, you build an interface around it. But it turns out that the choices people make in such a simple project are highly indicative of how they think. The way they handle pages, the way they structure their code internally, whether they comment or not, how they write instructions so reviewers can test. All of those choices are meaningful and inherent to their own internal process, and, as it turns out, bear out in how they do the work once they join the team.</p><p>You then review based on a rubric. Intention matters: you want someone with the thoughtfulness to mark their code up so it’s easily reviewable for others. You want someone who organizes their code well instead of writes a series of sprawling scripts. You want someone who provides the right detail for someone to run and test the project effectively.</p><p>I always ask a series of 3-4 questions about why they made the choices they did and what they would have liked to have done if they’d had more time. These days, I’ve started to ask if they used AI, and if so, how. (It’s not <em>necessarily</em> a disqualifier, if they did it thoughtfully, and if they’re honest about it.) Those are to be left in the README file. And again, they tell me a lot about how that person thinks. Are they curious? Do they care about the people who will use their work? What’s their <em>mindset</em>?</p><p>I don’t need to sit in the room and watch this person over their shoulder while they write their code. Every project I’ve ever received has been meaningfully different. And we’ll talk about their choices later.</p><h3 id="the-conversation">The conversation</h3><p>I try and front-load the take-home. There’s a short screener call first, to make sure expectations are shared: the salary (which I like to be non-negotiable), whether we can hire them at all (different companies have different visa capabilities), what the role actually entails, whether the candidate is an asshole over the phone. (Yes, some are.)</p><p>Some candidates will never return the take-home; some won’t pass it. But the ones that do are forwarded to two sets of panel conversations. It’s a huge time commitment for the team, so I try and limit this stage to 4-6 strong candidates.</p><p><strong>An engineering panel</strong> who will talk about the nature of the work, real technical problems that show up during it, and choices the candidate made in their take-home.</p><p><strong>A product panel</strong> made up of people who will work closely with the engineer but aren’t engineers themselves. This panel will talk about the non-engineering challenges the team faces, and ask questions that speak to how the engineer collaborates across disciplines.</p><p>In both cases, the questions the candidate asks are almost more important than the questions the panel asks. They, once again, speak to how the candidate thinks; what they’re curious about; what’s important to them.</p><p>Every individual on the panel evaluates the candidate based on a rubric and leaves their own qualitative notes.</p><p>The strongest 2-3 are forwarded to a final executive interview. That’s me! I may also have conducted the screener, or have taken a call to talk about the role informally, so in some cases it’s a loop back; in other cases, it’ll be the first time I’ve met the candidate. Either way, I like to ask them if there’s anything they heard in the previous panels that they’re curious about or want to talk about more, and I like to dig into anything those panels highlighted as questions or concerns in their notes. Once again, the candidate’s questions are probably more important than my own.</p><p>I’ll always check references personally, and then make an offer over the phone, answering any final logistical questions in the process.</p><h3 id="the-work">The work</h3><p>It’s important that the work itself lives up to these values. There’s no use building a process around fairness if the work itself is whim-based; it’s not reasonable to hire for communication if we don’t value it internally. We can hire for collaborators, but if we treat engineers as back-room workers who just accept tasks, it’s tantamount to a bait and switch. We build the culture of community in part by being careful about who we bring into it, but we have to also do the work ourselves to maintain those standards.</p><p>When someone joins a community I’ve helped to build, I’m clear that their first couple of months are learning mode: it’s great if they commit code, but there’s no expectation that they will in the first stages. Instead, I want them to meet all the people they’ll work with, both inside and outside the team, and get to a holistic understanding of the organization, its goals, its flaws, and where the biggest opportunities are. That mostly looks like a lot of conversations, which can be exhausting for an introvert, for example, so there’s plenty of time.</p><p>I’ve been proud to hire and work with the people I have. Some of them have, very kindly, told me that they appreciate the emphasis I make on relationships and community-building. That’s important to me: we build technology, but we do it as humans, in service of humans. Whether you’re doing it in a startup, a tech company, or a non-tech organization like a newsroom, it’s important to stay centered on the people. That’s how you build a great team. And that, in turn, is how you do the work well.</p><h3 id="afterword-a-quick-note">Afterword: a quick note</h3><p>These posts are personal and not affiliated with ProPublica, my current employer. It does not necessarily represent how anyone else hires at any organization I’ve been employed by.</p><p>But also: if this mindset appeals to you, I’m hiring! <a href="https://job-boards.greenhouse.io/propublica/jobs/4623874006?ref=werd.io">ProPublica is looking for a Director of Product Engineering</a>. You’ll work with a small team of product engineers — and me — to provide mentorship, engineering standards, and hands-on architectural and engineering support. If that sounds good to you, the vacancy is open until January 16. If you’re based in the US and have experience working with small, scrappy engineering teams, please consider joining our community!</p>A New Year, Korean food and dog problems - W01 - Joel's Log Fileshttps://joelchrono.xyz/blog/w012026-01-06T12:50:17.000Z<p>Well here we are once again, starting over another year! The first set of weeknotes is coming out at last. Here’s how things went!</p>
<ul>
<li>
<p>🎉 Happy New Year you all! 2025 is over already and we must pave the way to a new tomorrow, one day after another! 2026 is upon us!</p>
</li>
<li>
<p>🍚 The other day we went to eat out at a Korean food restaurant! It was a new place I had never visited before, me and my siblings were invited by family friends and it was actually rather nice, we ended up stuffed full of rice and other goodies.</p>
</li>
<li>
<p>🃏 During the New Year we kinda just played board games and spent the time together as family. We had a great match of Scrabble and I managed to win one of them and get a draw on the other with my father. Cool stuff!</p>
</li>
<li>
<p>🐶 My dog (the one that got hit by a car) was now attacked by a bigger dog. He’s mostly fine but we have to clean up the wound daily and I can’t help but wonder why he likes to put his life in danger all the time.</p>
</li>
</ul>
<h2 id="gaming">Gaming</h2>
<h3 id="completed">Completed</h3>
<ul>
<li><strong>Monument Valley</strong> is the first game I complete this year! It was free on the Epic Games Store for Android and I decided to pick it up alongside the sequel for it! Honestly it was a short but sweet experience, great perspective-based puzzles, thoroughly enjoyable.</li>
</ul>
<h3 id="ongoing">Ongoing</h3>
<ul>
<li>
<p><strong>Hollow Knight: Silksong</strong> saw a lot of progress! I have been exploring some nasty, ugly areas like the Petrified Ducts, and I’ve also explored some more of The Slab, finally fighting against one of my favourite bosses in the game so far, the First Sinner. This was a very fun challenge and it took me a few tries, but I emerged victorious in the end.</p>
</li>
<li>
<p><strong>Slice & Dice</strong> is once again taking over my free time, just a great roguelike, nothing needs to be said.</p>
</li>
</ul>
<h2 id="reading">Reading</h2>
<h3 id="completed-1">Completed</h3>
<ul>
<li><strong>Exit Stragegy</strong> - I finally finished the fourth book of <em>The Murderbot Diaries</em> by Martha Wells! This was another pretty fun short story that I really enjoyed, but once again like the last couple books, the chapters of these are just way too long for me. I kept avoiding a read because I couldn’t squeeze enough time to get it done, and I always felt weird leaving a chapter midway through. In the end I accepted it, but I still don’t like it. The story was pretty awesome anyway! Lots of cool action moments and Murderbot being Murderbot.</li>
</ul>
<h3 id="ongoing-1">Ongoing</h3>
<ul>
<li><strong>Kingdom</strong> - Read up to chapter 849. The next arc has begun, the invasion of the Zhao kingdom begins, so many knots have been tied up nicely, and the way for a new encounter starts now.</li>
<li><strong>Blue Lock</strong> - Read up to chapter 329. Seeing how all the match ups begin to form is just so fun! The next match is France vs Japan, and it is going to be pretty crazy!</li>
<li><strong>Chainsaw Man</strong> - Read up to chapter 224. Crazy shenanigans going on.</li>
</ul>
<h2 id="watching">Watching</h2>
<ul>
<li><strong>The Amateur</strong> - I haven’t finished <em>Mr. Robot</em> and maybe I should check it out again after a while. This was an interesting movie with an interesting premise! But it felt kind of random at times, it didn’t hold my attention very well, but there goes my first movie of the year!</li>
<li><strong>Death Wish</strong> - A bit of an action/revenge flick where the guy from <em>Die Hard</em> kills the people who killed his wife and left his daughter in a comma. Very American stuff, a random pick that I don’t enjoy when I think about it but it was very entertaining nonetheless.</li>
<li><strong>Dr. Stone</strong> - I started the second part of the latest season of this anime! <em>Science Future</em> has been a wild ride, and at this point I just have fun with the characters and how they get away from wacky situations with the power of science!</li>
</ul>
<h2 id="around-the-web">Around the Web</h2>
<h3 id="blogposts">Blogposts</h3>
<ul>
<li><a href="https://gabz.blog/posts/a-game-i-am-playing-botw">A game I am playing: BotW</a> - Oh look, someone is playing a fantastic videogame and sharing some thoughts about it, so I have to share it.</li>
<li><a href="https://anhvn.com/posts/2026/unproductive-happy-holiday/">I have had an unproductive and happy holiday</a> - Every once in a while it’s cool to just hang out with people instead of focusing too much on personal projects and the like.</li>
<li><a href="https://brainbaking.com/post/2025/12/2025-in-video-games/">2025 In Video Games</a> - I wasn’t gonna highlight any yearly recap post but Wouter played some games I asked him to play so he gets a pass. Besides, there are cool stats there!</li>
<li><a href="https://orbitalmartian.vercel.app/blog/2025-12-27-android-writing/">Android Writing - New Tablet, Keyboard and Pen</a> - I’ve been thinking about buying a tablet lately, for some reason, I don’t really need it, but still.</li>
<li><a href="https://blueberrylemonade.pika.page/posts/passing-down-traditions">Passing Down Traditions</a> - Traditions change overtime and that comes with some ups and downs, just a stream of thought I enjoyed reading.</li>
</ul>
<h3 id="videos">Videos</h3>
<ul>
<li><a href="https://youtu.be/JQB8aNKyeao">I made auto-aim for mini golf</a> - Stuff Made Here is an all-time favorite channel of mine, the kinda stuff that keeps my engineering mind going. This was a fantastic project and I want to see it evolve even more!</li>
<li><a href="https://youtu.be/DxvOgi-DD84">Made my girlfriend play Super Metroid</a> - This was such a funny video, and I am yet to play <em>Super Metroid</em> myself… <del>I want a girlfriend to play videogames with smh.</del></li>
<li><a href="https://youtu.be/PTyu57YHjb0">The Best Game You’ll Never Play - Steel Battalion</a> - I had no idea a game like this even existed, it looks kind of incredible. I will never play it, to be honest, but it’s a bit of a dream now, maybe once I’m in my 40s or something a game like this will show up again.</li>
<li><a href="https://youtu.be/YcppnDs2Rz8">Something About Super Metroid ANIMATED SPEEDRUN</a> - I had seen this type of animation videos floating around and this totally killed me, very fun stuff!</li>
</ul>
<p>This is day 2 of <a href="https://100daystooffload.com">#100DaysToOffload</a></p>
<p>
<a href="mailto:me@joelchrono.xyz?subject=A New Year, Korean food and dog problems - W01">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/idcomments">Reply on Fediverse</a>
</p>Publishing my citation preferences - James' Coffee Bloghttps://jamesg.blog/2026/01/06/citation-preferences/2026-01-06T12:46:46.000Z
<p>I was recently asked by a fellow blogger how I would prefer to be credited in a blog post they were working on. This brought to mind an idea I have been thinking about for a while: how could I indicate the way I would prefer a post on my website to be cited? By having this information readily available, anyone who wants to link to my site would have the information they need to feel confident in their citation. </p><p>After thinking about this question for a while, I now have a “<a href="https://jamesg.blog/cite">How to cite pages on my website</a>” page – a living document – as well as an abbreviated version of this guidance at the bottom of a few categories on my blog.</p><p>Below, I’ll talk a bit about how I now publish my citation preferences on my website, touching on both design and content considerations.</p><h2 id="building-a-citation-preferences-widget-and-page"><strong>Building a citation preferences widget and page</strong></h2><p>Opening developer tools in Firefox, I started tinkering around with adding a section to the bottom of my blog posts that indicates my citation preferences. I wanted this section to be clear and concise in language, and apparent but unobtrusive in design. I decided to use the <code>details</code> element to create an accordion that includes a short statement on how to cite my blog post, as well as a text field that contains the URL for the web page the reader is viewing.</p><p>With a preliminary design ready, I started to roll out the widget to a few categories on my blog – presently, the IndieWeb, Coding, and one or two other categories. Here is what the widget, which appears at the bottom of my blog posts, looks like, when opened:</p><img alt='The end of a blog post with an open HTML details element that contains a sentence of text with citation guidelines, a link that says "Learn more", and a form field with the URL for the post.' class="kg-image" loading="lazy" sizes="(min-width: 720px) 720px" src="https://editor.jamesg.blog/content/images/2026/01/citation.png" srcset="https://editor.jamesg.blog/content/images/size/w600/2026/01/citation.png 600w, https://editor.jamesg.blog/content/images/size/w1000/2026/01/citation.png 1000w, https://editor.jamesg.blog/content/images/2026/01/citation.png 1282w"/><p>The details element is closed by default, with the summary title “Reference this post”. The widget is closed by default is because the information is only relevant to those who are looking to link to a given blog post, not necessarily all readers.</p><p>This widget contains the essential information someone needs to link to a blog post: my preferred name and my site name, my pronouns, and a link to the page. </p><p>With that said, I wanted to add a bit more information. In pursuit of my goal of designing something unobtrusive in design and concise in language, I decided the additional information could be put on its own page. This information is now on my “<a href="https://jamesg.blog/cite">How to cite pages on my website</a>” page, published at /cite, which elaborates both on how to refer to my website and touches on how I think about linking to others’ sites in my own blog posts, too. The /cite page is intended to be a living document – one that may evolve over time.</p><p>I plan to roll out the widget on blog posts that are focused on technical topics for now. I don't think the information is particularly useful at this point on my more poetic writing.</p><h2 id="making-the-citation-preferences-widget-linkable"><strong>Making the citation preferences widget linkable</strong></h2><p>Of note, the <code>details</code> element that appears in the citation preferences widget on blog posts in relevant categories has an enclosed paragraph with the HTML ID <code>cite</code>. This means that I can link directly to the citation preferences widget on a given page, such as:</p><pre><code>https://jamesg.blog/2026/01/06/citation-preferences#cite</code></pre><p>The first enclosed paragraph in the <code>details</code> tag is given the ID <code>cite</code> so that the <code>details</code> will open by default when the link is opened. I may tinker with the design a little bit to highlight the opened details tag if it is directly linked to – maybe a border. This can be done, I think, with a combination of the <code>:target</code>, <code>[open]</code>, and <code>:has</code> CSS selectors.</p><p>On writing this, one subtle consequence of not rolling out the citation widget on all pages means that #cite cannot be predictably added to the end of any blog post URL. I could make the citation widget invisible unless <code>#cite</code> is in the page URL for blog categories where I don’t need to show the widget? I’ll need to think about this more.</p><h2 id="conclusion"><strong>Conclusion</strong></h2><p>By more clearly stating the way I prefer my blog to be cited, I hope I can give people a bit more confidence on how to refer to my blog in their own blog posts. I would also be delighted if more people started talking about the idea of citation preferences!</p><h2 id="further-reading"><strong>Further reading</strong></h2><ul><li>The <a href="https://indieweb.org/citation">IndieWeb wiki /citation page</a> has a collection of information about citing web pages, with links to many interesting adjacent topics.</li><li>The <a href="https://indieweb.org/display-guidelines">IndieWeb wiki /display-guidelines page</a> is related both to citation preferences and more generally how other sites should display content from another site.</li><li>A blog post I wrote last year on <a href="https://jamesg.blog/2025/01/20/website-acknowledgements" rel="noreferrer">website acknowledgements</a></li></ul>
<!--kg-card-begin: html-->
<p><a class="u-syndication" href="https://news.indieweb.org/en">Also posted on IndieNews</a></p>
<!--kg-card-end: html-->
The Case for Blogging in the Ruins - Kev Quirkhttps://kevquirk.com/blog/the-case-for-blogging-in-the-ruins/2026-01-06T12:28:00.000Z
<div class="link">
<h2>The Case for Blogging in the Ruins</h2>
<span>by Joan Westenberg</span>
<p>Joan makes the case that the modern web, dominated by platforms and algorithms, has stripped away depth, ownership, and genuine thought. Blogging, she argues, is a quiet act of resistance that lets us think clearly, write freely, and leave something real behind.</p>
<p><a class="button" target="_blank" href="https://www.joanwestenberg.com/the-case-for-blogging-in-the-ruins/">Read Post →</a></p>
<hr class="email-hidden">
</div>
<p>I’m not sure where I first heard about Joan and her <em>superb</em> writing, but I’ve been following her for around a year or so now, I think.</p>
<p>Anyway, I was catching up on my RSS feeds and came across this post from a few days ago. It’s fantastic, as it most of what Joan puts out.</p>
<blockquote>
<p>Start a blog. Start one because the practice of writing at length, for an audience you respect, about things that matter to you, is itself valuable. Start one because owning your own platform is a form of independence that becomes more important as centralized platforms become less trustworthy. Start one because the format shapes the thought, and this format is good for thinking.</p>
</blockquote>
<p>I couldn’t agree more.</p>
<div class="email-hidden">
<hr>
<p>Thanks for reading this post via RSS. RSS is great, and you're great for using it. ❤️</p>
<p>
You can <a href="mailto:72ja@qrk.one?subject=The Case for Blogging in the Ruins">reply to this post by email</a>, or <a href="https://kevquirk.com/blog/the-case-for-blogging-in-the-ruins/#comments">leave a comment</a>.
</p>
</div>
Pens, Inks, and Obsidian Bases - Robb Knight • Posts • Atom Feedhttps://rknight.me/blog/pens-inks-and-obsidian-bases/2026-01-05T20:55:44.000Z<p>I finally got around to trying out <a href="https://help.obsidian.md/bases">Obsidian Bases</a> this evening but I needed a relatively small dataset to try it with. So I grabbed my ink export from <a href="https://fpc.ink">fountain pen companion</a> (FPC) and converted that CSV to markdown files. This isn't relevant to using Bases but here's the abridged version of that code anyway:</p>
<pre class="language-js"><code class="language-js"><span class="token comment">// inks.js</span><br /><span class="token keyword">const</span> fs <span class="token operator">=</span> <span class="token function">require</span><span class="token punctuation">(</span><span class="token string">'fs'</span><span class="token punctuation">)</span><br /><br />fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span><span class="token string">'collected_inks.csv'</span><span class="token punctuation">,</span> <span class="token string">'utf-8'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">slice</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">line</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">const</span> data <span class="token operator">=</span> line<span class="token punctuation">.</span><span class="token function">split</span><span class="token punctuation">(</span><span class="token string">';'</span><span class="token punctuation">)</span><br /> <span class="token keyword">const</span> title <span class="token operator">=</span> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string"> </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><br /> <span class="token keyword">const</span> content <span class="token operator">=</span> <span class="token punctuation">[</span><br /> <span class="token string">'---'</span><span class="token punctuation">,</span><br /> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">brand: '</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">'</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span><br /> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">name: '</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">'</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span><br /> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">hex: '</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">'</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span><br /> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">type: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span><br /> <span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">purchased: </span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>data<span class="token punctuation">[</span><span class="token number">13</span><span class="token punctuation">]</span><span class="token interpolation-punctuation punctuation">}</span></span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span><br /> <span class="token string">'---'</span><br /> <span class="token punctuation">]</span><br /><br /> fs<span class="token punctuation">.</span><span class="token function">writeFileSync</span><span class="token punctuation">(</span><span class="token template-string"><span class="token template-punctuation string">`</span><span class="token string">./inks/</span><span class="token interpolation"><span class="token interpolation-punctuation punctuation">${</span>title<span class="token interpolation-punctuation punctuation">}</span></span><span class="token string">.md</span><span class="token template-punctuation string">`</span></span><span class="token punctuation">,</span> content<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token string">'\n'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span><br /><br /><span class="token comment">// Diamine Meadow.md</span><br /><span class="token operator">--</span><span class="token operator">-</span><br /><span class="token comment">// ...</span><br /><span class="token literal-property property">hex</span><span class="token operator">:</span> #59ac2b<br /><span class="token comment">// ...</span><br /><span class="token operator">--</span><span class="token operator">-</span></code></pre>
<p>Once I'd added the new files I created a new Base and added a filter to only show files in my <code>Inks</code> folder. FPC includes a hex code for each ink and ideally I wanted to show this color in the table view. If I could run Javascrupt on every change I would do something like this to change the colour of the text where <code>metadata-input-longtext</code> is the classname of the cell elements of the table:</p>
<pre class="language-js"><code class="language-js">Array<span class="token punctuation">.</span><span class="token function">from</span><span class="token punctuation">(</span>document<span class="token punctuation">.</span><span class="token function">getElementsByClassName</span><span class="token punctuation">(</span><span class="token string">'metadata-input-longtext'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span><span class="token parameter">el</span> <span class="token operator">=></span> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>el<span class="token punctuation">.</span>innerText<span class="token punctuation">.</span><span class="token function">startsWith</span><span class="token punctuation">(</span><span class="token string">'#'</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">{</span><br /> el<span class="token punctuation">.</span>style<span class="token punctuation">.</span>color <span class="token operator">=</span> el<span class="token punctuation">.</span>innerText<br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span><span class="token punctuation">)</span></code></pre>
<p>Sadly (or not), you can't do that in Obsidian. I tried using <a href="https://css-tricks.com/almanac/functions/a/attr/"><code>attr()</code></a> but that only works if the data attribute is on the element you want to style. I then saw in the docs that Bases also has <a href="https://help.obsidian.md/formulas">formulas</a> as well as an <a href="https://help.obsidian.md/bases/functions#%60html()%60"><code>html</code> function</a>. So I added a formula to my ink Base (Properties > Add Formula) and added a formula that uses the <code>html</code> function.</p>
<pre class="language-js"><code class="language-js"><span class="token function">html</span><span class="token punctuation">(</span><span class="token string">"<span style='height: 100%; aspect-ratio: 1/1; background:"</span> <span class="token operator">+</span> hex <span class="token operator">+</span> <span class="token string">"'></span>"</span><span class="token punctuation">)</span></code></pre>
<figure><img src="https://cdn.rknight.me/site/2026/obsidian-bases-with-hex-color-preview.jpg" alt="A table showing a list of inks and their properties. A column named color shows a preview of the hex code" /></figure>
<p>Next up will be doing the same for my pens and linking them to the inks that they currently have in them. Now I've tried it I can see how Bases could be really powerful on some more complicated data. Perhaps I'll move some of <a href="/collections">my collections</a> into Obsidian and sync it to my website.</p>
<hr />
<p>Some posts that helped me understand Bases better:</p>
<ul>
<li><a href="https://thewallflowerdigest.co.uk/life/blog/a-new-approach-to-tracking-reading-with-obsidian-bases/">A new approach to tracking reading with Obsidian Bases</a></li>
<li><a href="https://tylersticka.com/journal/obsidian-bases-star-ratings-and-automatic-covers/">Obsidian Bases: Star Ratings and Automatic Covers</a></li>
</ul>How You Read My Content (The Answers) - Kev Quirkhttps://kevquirk.com/blog/how-you-read-my-content-the-answers/2026-01-05T13:42:00.000Z
<p style="font-size: 1.2em;">Two days ago I published a simple survey asking how you read the content I put out on this site. Here's the results of that survey.</p>
<p>Originally I was going to leave the survey running for at least a week, but after less than 48 hours, I received an email from Zoho telling me I’d hit the monthly response limit of 500 responses. If I wanted more responses, I’d have to pay.</p>
<p>Nah. 500 responses is enough to give me a good indication on how people consume my content, so I was good with that. Also, 500 responses in less than 48 hours is bloody brilliant. Assuming only a small proportion of readers actually responded (as that’s usually the case with these things) that means there’s a healthy number of you reading my waffle, so thank you!</p>
<h2 id="the-results">The results</h2>
<p>The survey simply asked <em>“how do you read the content I put out on this site?”</em> and there were a handful of options for responses:</p>
<ul>
<li>RSS</li>
<li>Mastodon / Fediverse</li>
<li>Email</li>
<li>Occasionally visit the site</li>
<li>Something else</li>
</ul>
<p>If someone selected the last option, a text field would appear asking for more info. There were a few people who used this option, but all were covered by the other options. People just wanted to add some nuance, or leave a nice message. ❤</p>
<p>So I updated all the <em>something else</em> responses to be one of the other 4 options, and here’s the results:</p>
<p><img src="https://kevquirk.com/assets/images/blog/2026-01-05-how-you-read-my-content-the-answers/reading-type-pi-chart.webp" alt="Reading type pie chart" />
<em>A highly accurate pie chart</em></p>
<table>
<thead>
<tr>
<th>Option</th>
<th>Responses</th>
<th>%</th>
</tr>
</thead>
<tbody>
<tr>
<td>RSS</td>
<td>421</td>
<td>84.5%</td>
</tr>
<tr>
<td>Masto/Fedi</td>
<td>38</td>
<td>7.6%</td>
</tr>
<tr>
<td>Visitor</td>
<td>27</td>
<td>5.4%</td>
</tr>
<tr>
<td>Email</td>
<td>12</td>
<td>2.4%</td>
</tr>
</tbody>
</table>
<h2 id="what-this-tells-me">What this tells me?</h2>
<p>Well, quite a lot, actually. It tells me that there’s <em>loads</em> of you fine people reading the content on this site, which is very heart-warming. It also tells me that RSS is <em>by far</em> the main way people consume my content. Which is also fantastic, as <a href="https://kevquirk.com/blog/please-add-rss-support-to-your-site/">I think RSS is very important</a> and should always be a first class citizen when it comes to delivering content to people.</p>
<p>I was surprised at how small the number was for Mastodon, too. I have a fair number of followers over there (around 13,000 according to Fosstodon) so I was expecting that number to be a bigger slice of the pie.</p>
<p>Clearly people follow me there more for the hot takes than my waffle. 🙃</p>
<p>This was a fun little experiment, even if it did end more quickly than I would have liked. Thanks to all ~500 of you who responded, really appreciate it.</p>
<p>See, you don’t need analytics to get an idea of who’s reading your stuff and how.</p>
<div class="email-hidden">
<hr>
<p>Thanks for reading this post via RSS. RSS is great, and you're great for using it. ❤️</p>
<p>
You can <a href="mailto:72ja@qrk.one?subject=How You Read My Content (The Answers)">reply to this post by email</a>, or <a href="https://kevquirk.com/blog/how-you-read-my-content-the-answers/#comments">leave a comment</a>.
</p>
</div>
Software maintenance - James' Coffee Bloghttps://jamesg.blog/2026/01/05/software-maintenance/2026-01-05T13:10:42.000Z
<p><a href="https://jamesg.blog/2026/01/05/why-artemis-is-invite-only" rel="noreferrer">In my last blog post</a>, I noted:</p><blockquote>With regard to sustainability [of Artemis], there are several considerations: infrastructure and its associated costs, the time required to maintain the software, responding to user requests and inquiries, and more.</blockquote><p>This had me thinking about how to communicate what “the time required to maintain the software” means in more depth. I thought I could add some colour to what maintenance means in the context of Artemis, the calm web reader I maintain, by way of a few examples. I think of maintenance as work that doesn’t explicitly involve adding new functionality, rather keeping existing features going.</p><p>Below are some examples of software maintenance in the context of Artemis.</p><ul><li>The Artemis account deletion feature is not working. This is because the process takes longer than it did when I built the feature. It is likely I will need to create a few database indexes. This feature is essential to have, so it’s at the top of my priority list in terms of software maintenance. Of note, this is an example of maintaining code that worked at one scale but not at another.</li><li>Separately, as I have introduced new features over time, I have updated the account deletion feature so that all database tables are cleared on account deletion.</li><li>Occasionally users are logged out on mobile devices. This is a hard-to-debug problem because it happens irregularly, and only in specific contexts. The first thing I need to do is gather more information, but as I have only received one report of this being a problem it is presently low on my list of priorities.</li><li>A user’s feed lists all posts published on a given day under a heading in the form “Monday, January 1st”. When New Years Day came, I realised the dates in the list of posts in a user’s feed may go from January 1st at the top to December 31st as the next entry, without stating the years to which the dates correspond. I plan to add the year to the dates in the user’s feed headings when the year changes.</li><li>All account settings used to be on one page, but I reorganised them into several separate pages connected by a universal navigation so that it was easier to find each one.</li><li>Sometimes a web feed can’t be processed as expected. This is something I debug on a case-by-case basis – the reasons for a feed not being processed can vary widely.</li><li>At one point, when I introduced a new feature, I was informed that logging in with one’s domain name stopped working. I fixed the issue, then realised it could have been avoided by creating a better abstraction in a certain part of the project codebase where the same code is – inefficiently so – repeated almost but not quite exactly.</li></ul><p>Maintenance comes in many forms – whether fixing things that no longer work properly with time (as is the case with the account deletion feature), identifying edge cases (as is the case with showing years alongside dates in a user’s feed at the beginning of a new year), keeping features in sync, and more. </p><p>In addition, maintenance tasks can demand varying amounts of time – a bug may be easily fixed on account of being relatively obvious to identify and address, or take a substantial portion of time to first debug, then plan a fix for, then finally make the requisite fix.</p><p>The urgency of maintenance tasks varies, too – some tasks need to be completed at the earliest convenience, others can wait until time allows.</p><p>Software doesn’t exist in the background, running on for ever and ever. Indeed, there have been weeks when Artemis has run quietly in the background without any effort required from me. But there are other weeks where I get a bug report or notice something isn’t quite working as expected or see a small way in which something can be improved which prompt me to plan, code, test, and release a change. This is what maintenance means to me in the context of Artemis.</p><p>Some maintenance tasks can be tedious, some stressful, whereas many others are learning opportunities – a time to learn of a new edge case to consider when coding, for example, or of connecting the dots between multiple parts of a project to build a better mental image of how things fit together.</p><p>All in all, there is something amazing about being able to use something you make. But, just as a painting hung in a gallery is in its condition because of all of the work done by staff to preserve it, so too is any given piece of software in its condition because of the work done to maintain it.</p>
Looking Back at the Best Inventions of 2001 - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=644572026-01-05T12:34:15.000Z<p>While looking down the back of the Internet for something or other, I stumbled across <a href="https://content.time.com/time/specials/packages/completelist/0,29569,1936165,00.html">Time Magazine's Best Inventions of 2001</a>.</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2025/11/Best-Inventions-of-2001-TIME.webp" alt="Six futuristic inventions." width="1161" height="463" class="aligncenter size-full wp-image-64459"/>
<p>It has been a quarter of a century since 2001 (!!) so that's a good excuse to look back at what stood the test of time. The article states:</p>
<blockquote><p>Inventions come in all shapes and sizes. Some are as simple as purple catsup. Others push the limits of quantum physics. The real measure of an invention is not just how well it works or how impressively it is engineered, <strong>but how it changes our lives</strong>.</p></blockquote>
<p>I don't think I've ever seen purple ketchup in the UK, but I'm prepared to believe it is life changing for some. What about the rest? Here's what people at the turn of the century thought would have an impact on our era.</p>
<h2 id="ginger"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#ginger">Ginger</a></h2>
<p>Ginger? The name tickled something at the back of my brain. Oh! Yeah! <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936361,00.html">Project Ginger</a>!</p>
<blockquote><p>After the Harvard Business School Press advanced $250,000 for a book about It—a top-secret project under development by one of the most accomplished inventors in the U.S.—reams of newsprint were devoted to speculation about what It might be. The recipient of the advance, author Steve Kemper, gushed in his book proposal that It—code-named Ginger—would revolutionize personal transportation, urban design and our daily lives. Apple Computer ceo Steve Jobs said It could be bigger than the PC.</p></blockquote>
<p>It was the Segway.</p>
<p>Now, look, I've enjoyed every time I've ridden a Segway. They're great for tourist exploration of a city (where licenced) and even for a bit of off-roading. But I've <em>never</em> seen a commuter on one. I remember seeing airport police using them to cruise round an airport. But other than that…</p>
<p>Ginger / Segway was the <em>ultimate</em> in hype exceeding reality. The Segway has had next to no impact on people's lives - other than the <a href="https://www.bbc.co.uk/news/uk-england-leeds-11416654">owner's ironic death</a>. Electric bikes are everywhere - but none of them are self-balancing.</p>
<h2 id="nuvaring-birth-control"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#nuvaring-birth-control">Nuvaring Birth Control</a></h2>
<p>The <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936238_1936267,00.html">Nuvaring</a> is a hormonal birth control. Unlike the pill, it is used monthly. Unlike implants, it doesn't need to be inserted by a trained professional.</p>
<p>So, how did it do? Pretty well! It is still in use and <a href="https://cks.nice.org.uk/topics/contraception-combined-hormonal-methods/management/combined-contraceptive-vaginal-ring/">regularly prescribed</a> - there haven't been any major issues with it.</p>
<p>The <a href="https://digital.nhs.uk/data-and-information/publications/statistical/sexual-and-reproductive-health-services/2021-22/methods-of-contraception">UK produces lots of statistics about birth control methods</a>. It seems that people are moving away from product like Nuvaring:</p>
<blockquote><p>Over the last ten years, LARC [long acting reversible contraceptives] uptake has been increasing and uptake of user dependent methods has been decreasing.</p></blockquote>
<h2 id="wind-up-cellphone-disposable-cellphone"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#wind-up-cellphone-disposable-cellphone">Wind Up Cellphone / Disposable Cellphone</a></h2>
<p>I indistinctively love both these ideas. There were a plethora of wind-up products back in the day. The <a href="https://www.bbc.co.uk/news/technology-28316975">wind-up radio <em>was</em> transformative</a> and truly helped change the world. The <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936254_1936627,00.html">wind-up cellphone</a> flopped. Phones became more efficient and batteries became more powerful.</p>
<p>The <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936254_1936629,00.html">disposable phone</a> is also an idea out of place. Originally designed for travellers who could pick up a temporary phone on their holidays. Cheap travel SIMs almost immediately obsoleted it.</p>
<h2 id="digital-satellite-radio"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#digital-satellite-radio">Digital Satellite Radio</a></h2>
<p>AM and FM are <em>so</em> yesterday!</p>
<blockquote><p>Two rival companies are betting that drivers are sufficiently fed up with bad reception, tired playlists and irritating ads to fork out around $10 a month (plus up to $1,000 for a receiver) for dozens of stations</p></blockquote>
<p>Thus was launched <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936380,00.html">XM and Sirius's Digital Satellite Radio</a>. By 2008 <a href="https://en.wikipedia.org/wiki/SiriusXM">the companies had merged</a>. While still operating in North America, it is <a href="https://en.wikipedia.org/wiki/Satellite_radio">extinct everywhere else</a>.</p>
<p>Terrestrial Digital Radio (via DAB) outlasted DSR.</p>
<h2 id="heat-generating-jacket"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#heat-generating-jacket">Heat-Generating Jacket</a></h2>
<p>What's this? Something which actually made it!</p>
<blockquote><p>Designed for extreme cold, the North Face MET5 jacket can keep you warm all by itself, thanks to a network of microscopic, waterproof heating elements woven into the fabric.</p></blockquote>
<p><a href="https://amzn.to/498fZ9y">You can pick these up from £30</a>! They're USB rechargeable and, so I'm told, toasty warm.</p>
<h2 id="ford-think-car"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#ford-think-car">Ford Think Car</a></h2>
<p>Are tiny cars the future?</p>
<blockquote><p>Slow, pricey and impractical, electric cars for years have had a bad rap. Ford could start to change all that with its bubble-shaped City car, which hit the streets of Los Angeles, New York City and London this year. Running on 18 NiCad batteries, the City tops out at 65 m.p.h. but can travel only 55 miles between charges. Ford thinks it's the perfect commuter car—as long as you don't miss your exit.</p>
<p>Availability: Leases for $199 a month</p></blockquote>
<p>Ford is comically absent from the future it created. But there are now a dozen different "city cars" which run on batteries. Some are little more than glorified quadricycles, others are full cars - albeit with limited ranges.</p>
<p>The $200 monthly lease is about £250 in today's money. And, yes, you can get a cheap lease for that. The market is still dominated by fossil-fuel cars, of course, and electrics tend to be large and expensive. But the Think Car's legacy lives on!</p>
<h2 id="and-the-rest"><a href="https://shkspr.mobi/blog/2026/01/looking-back-at-the-best-inventions-of-2001/#and-the-rest">And the rest</a></h2>
<p>OK, some of the inventions made a real difference - most notably the <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936238_1936258,00.html">artificial heart</a> and <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936238_1936293,00.html">liver</a>. While they might seem mundane now, <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936250_1936615,00.html">natural colour light bulbs</a> were a big deal back in the day.</p>
<p>And, of course, we all use an <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936254_1936619,00.html">automatic mashed potato machine</a> as part of our daily lives. Right?</p>
<p>But most of the inventions are the sort of nonsense like <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936382,00.html">jetpacks</a>, <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936255_1936640,00.html">office robots</a>, and <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936349,00.html">fuel cells</a>.</p>
<p>There are glimmers of <em>almost</em> in there. The aforementioned fuel cell was attached to a bike - nowadays battery-powered bikes are ubiquitous. Similarly, the <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936358,00.html">hydrogen scooter</a> is now electrically powered.</p>
<p>Some of the inventions, like the <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936310,00.html">Gateshead Millennium Bridge</a> are still around, although there don't appear to be many bridges like it. Sadly, most metropolises are still waiting for their <a href="https://content.time.com/time/specials/packages/article/0,28804,1936165_1936240_1936378,00.html">self guided buses</a>.</p>
<p>Inventing the future is difficult. Working out which inventions will stand the test of time is close to impossible.</p>
Why Artemis is invite-only - James' Coffee Bloghttps://jamesg.blog/2026/01/05/why-artemis-is-invite-only/2026-01-05T12:21:47.000Z
<p>When someone goes to the Artemis sign up page, a message is presented asking users to ask me for an invite code. While Artemis has been public for almost a year now, the software is still invite-only. I occasionally share the invite code in blog posts, but, despite that, I still receive many emails for an invite, per the instruction on the sign up page to email me for access.</p><p>There are three main reasons why Artemis is invite-only. The first, and most important, is that by asking people for an invite code I can ensure that the service remains sustainable, both technically and personally. Artemis is a hobby project. I use it every day to follow my favourite websites, and have been doing so for over a year. With that in mind, my goal is not to build something that grows: my goal is to build something that I can use and that others can use, too, should they be interested.</p><p>With regard to sustainability, there are several concerns: infrastructure and its associated costs, the time required to maintain the software, responding to user requests and inquiries, and more.</p><p>The more people who use the service, the more I need to think about storage, compute, and such. Indeed, Artemis doesn’t take up too much storage or compute time, but this is largely because of both my intent to collect only essential data, and the engineering required to keep things efficient. Such engineering has taken considerable effort as I have balanced the desire to <a href="https://jamesg.blog/2025/12/15/cleaning-the-artemis-database">offer more advanced features with the increasing computation required to do so</a>.</p><p>Artemis is offered for free because it is possible for me to do so, but, again, this is only due to the amount of time spent figuring out how to keep the service lean.</p><p>Indeed, the question of sustainability is often on my mind as someone running a service, especially as a hobbyist. While I have occasionally thought of what it would look like to do more marketing for Artemis, I realise that, at least right now, I am happy the way things are. I am much happier with Artemis being a working tool for me and a few others, and being something that sets an example of what “calm” software could look like, than trying to grow it into something more. If anything, I'd rather spend the time I have for Artemis on fixing bugs and looking to remove old, likely-unused features.</p><p>Second, Artemis is invite-only because the invite gate gives me a little pulse on how many people are signing up. I don’t actively track how many people are signed up, beyond occasionally checking in the course of maintenance or out of occasional curiosity. But, asking for an invite means I can see how many people might create an account at a given point in time (not everyone who asks for an invite code will sign up, but I would guess most who go to the effort of sending an email to request access will at least try the software). </p><p>Registration is not the same as active users. Indeed, I don’t know how many people use the service actively, for there is not sufficient activity for the service to feel under any particular strain (again, this having been the result of engineering, maintenance, and monitoring the service over time, all of which require time). But this pulse – roughly how many people sign up at a given point in time – is nice. I hand-write every email, usually ending with something like “Enjoy the software :)”</p><p>Third, by limiting the service to be invite only, I can reduce the chance someone signs up as I roll out a new feature or plan work. Indeed, in times of maintenance I have chosen not to invite people for a few days, such that I can be more confident someone has a good experience. There always seem to be bugs or rough edges of the software that haven’t been tested in a while – or are no longer maintained – but it is significant to me that I can limit registration in times when a user might be more likely to run into an issue.</p>
Designing an A-Z navigation web component - James' Coffee Bloghttps://jamesg.blog/2026/01/05/a-z-navigation-web-component/2026-01-05T11:50:22.000Z
<p>Artemis, the calm web reader I maintain, has an Authors page that lists all of the websites to which you are subscribed. The list is presented in alphabetical order, with a heading for each letter in the alphabet to aid in navigation. There is a search feature, too.</p><p>I follow a lot of blogs, which means that the list is long. It’s hard to find a particular entry without typing and using the search feature. I wondered: are there another methods of navigation that would be useful? I then started to think about the A-Z navigation component in the iOS Contacts app, which shows a sidebar with all the letters from A-Z. You can tap on a letter or scroll through the letters to get to a specific part of the contact list.</p><p>I decided to make a web component of this feature, which is <a href="https://playground.jamesg.blog/contact-bar.html">available in my playground</a>. I called the component <code><contact-bar></code>. Feel free to use, copy, and remix, this component.</p><p>After building the component, I added it to the aforementioned Authors page in Artemis with custom styling. The component looks like this:</p><img alt="A list of websites I follow, with a sticky list of letters in the right navigation." class="kg-image" loading="lazy" src="https://editor.jamesg.blog/content/images/2026/01/atoz-component.png" srcset="https://editor.jamesg.blog/content/images/size/w600/2026/01/atoz-component.png 600w, https://editor.jamesg.blog/content/images/2026/01/atoz-component.png 700w"/><p>With this component, users can tap on a letter to navigate to that subheading on the page. The component sticks with the user as they scroll, so it is constantly visible. <em>Note: Only letters A-T are presented as the above screenshot was taken with the mobile preview option in developer tools at a smaller resolution. The full A-Z list is presented on my iPhone in testing. Although, it is likely I will need to make changes to the component so that it works with smaller screens.</em></p><p>To make this component work, each letter heading – A, B, C, etc. – has a HTML id equal to the capital letter for that letter. This allows <code>#A</code> to be used to link to the heading for the letter A, and so on. Then, the web component creates a list of all letters from A-Z, as well as including any additionally specified characters (i.e. <code>@</code>).</p><p>With that said, not all letters between A-Z may have a corresponding heading – a user may only have subscribed to a dozen or so feeds, whose first letters collectively do not cover each heading from A-Z. To make the UI consistent, predictable, and thus more intuitive, the letters from A to Z are always listed. But, if a corresponding heading is not on the page, the letter links to the closest letter. </p><p>Suppose I subscribe to “Adam’s Blog” and “Carly’s Blog” but no blog whose name starts with B. The letter B would link to its closest existing heading that precedes it. In this case, that would be the A heading. If “Carly’s Blog” was the last blog in the list, every other letter would link to C. If there was also a “Thomas’ Blog”, the letters closest to C in alphabetical order would link to C, and the letters closest to T would link to T. Thus, G would link to C, and O would link to T, since G is closer to C than T and O is closer to T than C. The source code for this is in the <a href="https://playground.jamesg.blog/contact-bar.html" rel="noreferrer">web component code.</a></p><p>In implementing this web component, I wonder if I could achieve a similar “scrolling” effect as the iOS Contact app, where you can scroll within the A-Z list to quickly navigate the page. I spent an hour or two working on this and had something that sort-of-worked in Firefox developer tools’ mobile view if I recall, but the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/touchmove_event">touchmove</a> event on which my implementation depends – which emits an event when a touch moves on the screen, such as a finger moving up and down while pressing the screen – is not supported in iOS Safari. </p><p>With that said, I found that having the A-Z hyperlinks was a good-enough solution. Being able to tap on a letter between A-Z that is constantly visible on the screen vastly improves the speed with which I can go through the list of authors to which I am subscribed in Artemis – a list that most likely contains over a hundred entries now.</p><p>If you see opportunities for improving the web component, do let me know!</p>