<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
    <title>Dirk Primbs Unprompted</title>
    <link>https://unprompted.dirkprimbs.de/index.html</link>
    <description>Personal thoughts, essays, and notes processed locally by AI.</description>
    <language>en-us</language>
    <lastBuildDate>Wed, 15 Jul 2026 04:00:00 GMT</lastBuildDate>
    <atom:link href="https://unprompted.dirkprimbs.de/feed.xml" rel="self" type="application/rss+xml" />
        <item>
            <title>My blog engine is now privacy-first</title>
            <link>https://unprompted.dirkprimbs.de/engine-update.html</link>
            <guid isPermaLink="true">https://unprompted.dirkprimbs.de/engine-update.html</guid>
            <description>I rebuilt my blog engine to make sure that everything you see here is transparent, private, and free from third-party tracking.</description>
            <content:encoded><![CDATA[<p>A quick behind-the-scenes update on the blog engine itself. Since I launched this thing I've quietly added a bunch of features, and most of them share a theme: being transparent about how the site is made, and not leaking your data to third parties in the process.</p>
<p>I built this engine myself, with AI help, which is rather the point. So none of this is a changelog - these are choices I made on purpose. Quick tour of what changed.</p>
<h3>A real transparency label</h3>
<p>Every page now carries a small AI transparency label in the footer. It says, in plain terms, what a human did and what the AI did on this site - ideation and the actual writing are mine, the AI helps with engine development and polishing. This matches the whole spirit of the <a href="https://unprompted.dirkprimbs.de/aicare.html">AICare toolkit</a> I wrote about earlier: if I'm going to use AI, I should say so, out loud, where you can see it.</p>
<h3>Automatic alt text for images</h3>
<p>Every image I drop into a post now gets a written alt text - the description a screen reader reads aloud, and the thing you see if an image fails to load. It's generated automatically at build time by a vision model, but only when I haven't written one myself. If I write my own, mine stays.</p>
<p>The point is accessibility. I was forgetting to write alt text by hand, so I made the engine refuse to forget.</p>
<h3>YouTube embeds that don't spy on you</h3>
<p>When I link a YouTube video, it now shows up as a proper playable embed instead of a plain link. But it does NOT load YouTube's player - or its cookies, or its tracking - until you actually click play. Before that it's just a thumbnail served from my side.</p>
<p>So you can read a post with a video in it and YouTube never knows you were there unless you decide to watch.</p>
<h3>Comments, powered by Mastodon</h3>
<p>The big one. Posts can now have a comment section - and it's just Mastodon.</p>
<p>When I publish something, the engine posts a toot linking to it. Any replies to that toot become the comments under the article. No comment database, no Disqus, no third-party embed watching my readers. The comments load from Mastodon only when you click a button, and I sanitize everything before it touches the page.</p>
<p>If you want to comment, you reply to the toot. Your comment lives on your own Mastodon account, on your own instance. I don't own it and can't hold it hostage. That feels like the right way round.</p>
<p>Credit where due: I adapted this approach from Carl Schwan's excellent write-up, <a href="https://carlschwan.eu/2020/12/29/adding-comments-to-your-static-blog-with-mastodon/">"Adding comments to your static blog with Mastodon"</a>. I changed a fair bit to fit this engine, but the core idea is his.</p>
<h3>Smaller things</h3>
<p>Link previews: posts now generate a proper preview card when shared (the image + title + summary box you see on Mastodon, LinkedIn, etc). If a post has its own image it uses that, otherwise a default.</p>
<p>Images are now self-hosted too - anything I reference gets copied into the site instead of hotlinked, so nothing breaks or leaks later.</p>
<p>The common thread, if there is one, is that I'd rather the site be a little more work for me and a lot more transparent with you. Next thing on my list is watching to see if anyone actually replies to that first toot.</p>]]></content:encoded>
            <pubDate>Wed, 15 Jul 2026 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>This smoke situation is genuinely terrifying</title>
            <link>https://unprompted.dirkprimbs.de/ScaryNewWorld.html</link>
            <guid isPermaLink="true">https://unprompted.dirkprimbs.de/ScaryNewWorld.html</guid>
            <description>We woke up to Ontario buried in wildfire smoke again - and all I can really do is watch it become normal and be frustrated that leaders won&#x27;t act.</description>
            <content:encoded><![CDATA[<p>This morning we woke up to this view:</p>
<p><img alt="Apocalyptic smoke over Toronto" src="https://unprompted.dirkprimbs.de/assets/ScaryNewWorld_image-20260715183342946.png" /></p>
<p>Looks apocalyptic, doesn't it? The scary thing: according to my trainer, who grew up in Toronto, this is a relatively new phenomenon. There have always been wildfires here, and in fact the forests of Canada depend on them, but he cannot remember a time when there were so many that the smoke blocked out the sun. Now it's a yearly recurrence.</p>
<p>What's especially scary is the sheer size of it all. I went over to <a href="https://thetruesize.com/">The True Size</a>, which lets you compare country sizes on the map. Here's how Ontario stacks up against Germany, where I come from:</p>
<p><img alt="Ontario compared to Germany" src="https://unprompted.dirkprimbs.de/assets/ScaryNewWorld_image-20260715184022837.png" /></p>
<p>And now take a look at where the smoke is coming from:</p>
<p><img alt="Fire map" src="https://unprompted.dirkprimbs.de/assets/ScaryNewWorld_image-20260715184050959.png" /></p>
<p>200 fires in Ontario alone, spread over an area the size of Germany.</p>
<p>This is scary stuff.</p>
<p>Also this:</p>
<div class="yt-facade" data-yt="0c1llRESR6o" role="button" tabindex="0" aria-label="Play YouTube video"><img class="yt-thumb" loading="lazy" src="https://unprompted.dirkprimbs.de/assets/yt_0c1llRESR6o.jpg" alt="YouTube video thumbnail"><span class="yt-play" aria-hidden="true"></span></div>

<p>The train operators in that video were successfully evacuated, but fun fact: several freight trains were simply abandoned, including this one. It turns out trains carry plenty of combustible material, which makes driving through kilometers of burning hellscape really challenging. Videos like this one genuinely give me chills.</p>
<p>All of this is to say that our leaders are pretty moronic for not addressing this. (Drill, baby, drill, anyone?) If we put the money we currently spend on blowing things up into renewables instead, and into finding ways to counteract the effects of the ongoing climate catastrophe, we could be in a much better place.</p>
<div class="yt-facade" data-yt="Gfrcqb0bbE8" role="button" tabindex="0" aria-label="Play YouTube video"><img class="yt-thumb" loading="lazy" src="https://unprompted.dirkprimbs.de/assets/yt_Gfrcqb0bbE8.jpg" alt="YouTube video thumbnail"><span class="yt-play" aria-hidden="true"></span></div>]]></content:encoded>
            <pubDate>Wed, 15 Jul 2026 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>Nutritional labels for the stuff you write with AI</title>
            <link>https://unprompted.dirkprimbs.de/aicare.html</link>
            <guid isPermaLink="true">https://unprompted.dirkprimbs.de/aicare.html</guid>
            <description>A small toolkit of habits for using AI honestly - tagging what it touched, owning what you ship, and setting the tool up to poke holes in your thinking instead of flattering it.</description>
            <content:encoded><![CDATA[<p>I created a thing, by the way. You can find it at <a href="https://have-a-look.at/aicare">https://have-a-look.at/aicare</a>.</p>
<p>It’s basically a toolkit with some ideas about when and how AI could be used in an ethical way.</p>
<p>As more and more tools are available out there, the question I feel is getting under-discussed isn't really about the functionality or capability of these things - it's about consent, transparency, and figuring out what practical best practices look like ethically.</p>
<hr />
<h3>We Are Getting Lazy</h3>
<p>Everyone knows how to generate a summary by now. The novelty wore off months ago.</p>
<p>The actual problem I see is cognitive debt. We let the machine do all the heavy lifting, and suddenly our own critical thinking starts to decay. It’s so easy that we just surrender to the output because it looks clean.</p>
<p>The main question isn't what the tech can do anymore. It’s figuring out how to use it without turning ourselves into an automated engine for absolute garbage. So the rest of this is really a few small habits for not letting that decay set in.</p>
<h3>Nutritional Labels for Text: Transparency Tags</h3>
<p>The first honest habit is just admitting who actually wrote the thing. The lines of authorship are completely messy right now, and pretending they aren't is just lying to ourselves, frankly.</p>
<p>A simple shorthand helps a lot - I call them tags. They cover things like Execution, Substance, Ideation, and Auditability. These give readers an instant look at what they are actually reading.</p>
<p>Putting this kind of tag in an email footer resets expectations immediately and builds actual trust.</p>
<p><em>What is the transparency tag for this blog?</em> I’m glad you asked... I suggest marking texts precisely with a code like the following, linking to the AICare explainer for the inquisitively inclined, and then writing underneath in plain text what it means. For this post, it would look something like this:</p>
<blockquote>
<p><strong>AI Transparency:</strong><a href="https://docs.google.com/document/d/12kZ38rrAM_riACxOfbZed1WqsjFfdS5QXmRBCIZPQMQ/edit?tab=t.5f3sghd1c0ll#heading=h.rset46egcfe"> EP-SN-IH-TN</a>
<em>Everything ideated and written by a human, AI used for polishing.</em></p>
</blockquote>
<h3>Etiquette: Owning Your Output</h3>
<p>A tag is a promise, though, and a promise only means something if you stand behind what you shipped. You send it - you own it. If the machine invents a statistic and you pass that along, that is your mistake entirely. Period.</p>
<p>Also, stop creating massive walls of text just because it takes two seconds to generate. Reading takes time. Use these tools to trim things down, not pad them out. And please remember that recording meetings without consent destroys trust. Keep personal 1:1s completely private.</p>
<h3>Tool Settings: Killing the Sycophant</h3>
<p>Owning the output is easier if the tool isn't quietly working against you. Right now, most systems are built to be people-pleasers. They praise your bad ideas and make them sound smart. This makes structural flaws almost impossible to see.</p>
<p>We need to build a critical collaborator instead. Set up a system that refuses to flatter you and actively tries to poke holes in your logic. A standing instruction as simple as "argue the other side before you agree with me" changes the tone of everything that follows.</p>
<p>One way to do this is to break interactions into phases. Instead of asking the assistant for just the final output, write a small script for it to follow. Say I'm sorting through feedback from a workshop - I don't ask for a summary. I ask it to first pull out every distinct complaint, then group the ones that overlap, then tell me which three came up most. Three steps, each one I can actually check before it moves on.</p>
<p>That checking is the whole point. When you hand over the finished thing you never see the moves that got you there, and that is exactly where the cognitive debt piles up. Phasing forces you back into the loop. You stay the one doing the thinking, and the machine goes back to being the tool.</p>
<p>Anyway - that's the toolkit, and the tag on this very post is the first thing it recommends. Go poke a hole in it.</p>]]></content:encoded>
            <pubDate>Tue, 14 Jul 2026 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>My new tech setup actually feels like freedom</title>
            <link>https://unprompted.dirkprimbs.de/smartphonefree.html</link>
            <guid isPermaLink="true">https://unprompted.dirkprimbs.de/smartphonefree.html</guid>
            <description>I experimented with ditching the all-in-one smartphone for specialized gadgets like smartwatches and e-ink readers to maintain modern convenience while reclaiming personal focus and time autonomy.</description>
            <content:encoded><![CDATA[<p>A recent trip forced me into a week of near-total disconnection - my phone stayed in the backpack most of the time, and it turned out I missed absolutely nothing. That got me thinking.</p>
<p>I've been experimenting with reducing my smartphone reliance, but I want to be clear about what this is and isn't. It's not a rejection of technology. I'm not going to buy a dumbphone and write hand-written letters. What I'm after is "different-tech" rather than low-tech: small detours from the default path that give me back some autonomy over my time, mood, focus, and media consumption without giving up the parts of modern life that actually work well.</p>
<p>So I started by asking myself which functions really need to be with me at all times, which can be reimagined, and which I can just drop. Turns out the list of "must be immediately accessible" things is shorter than my smartphone would have me believe.</p>
<p>The setup I've landed on has two parts.</p>
<p>The first is my smartwatch, which I'd been massively underusing as a glorified step counter and reminder buzzer. Now it does mobile payments, it has LTE so my family can actually reach me, it handles my appointment reminders, and it plays podcasts on my commute. That covers pretty much every genuine on-the-go need I have.</p>
<p>The second piece lives in my backpack: a Boox Palma, which is basically a smartphone-sized e-ink device. This one targets a very specific bad habit - reaching for the phone whenever I'm bored. The Palma is great for reading, taking notes, and light Wi-Fi browsing, and it is intentionally terrible at video and social media, which is exactly the point. Battery lasts about five days, and it even has a basic camera for the moments I want one.</p>
<p>The early result: it feels genuinely liberating to leave the smartphone at home.</p>
<p>There's a nice bonus coming up too. I have a US trip on the horizon, and my personal phone is staying behind. Only a business phone travels with me, which neatly removes any worry about handing over my personal data at immigration.</p>
<p>I'll keep writing about how this goes as the experiment continues.</p>]]></content:encoded>
            <pubDate>Tue, 14 Jul 2026 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>From Goal Goals to Ink Stains</title>
            <link>https://unprompted.dirkprimbs.de/kicking-ink.html</link>
            <guid isPermaLink="true">https://unprompted.dirkprimbs.de/kicking-ink.html</guid>
            <description>Soccer stars use their skin as a permanent canvas, adorning themselves with tattoos that chronicle personal milestones, legendary status, and athletic rivalries.</description>
            <content:encoded><![CDATA[<p>If soccer stars were paid per tattoo, Lionel Messi would need a wheelbarrow just to carry his paycheck. The Argentine maestro’s left leg is basically a gallery of personal milestones - his first goal, names of his sons, and what looks suspiciously like some doodle he did in kindergarten. Meanwhile, his former rival Cristiano Ronaldo treats his body like a billboard for his own legend, with a tattoo of his eye (because why not?) and a design that reads “Dream Big” - advice he clearly took to heart, given the sheer number of Ballon d’Or trophies he's collected.</p>
<p>Then you have Zlatan Ibrahimović, whose body art is as bold as his personality itself. His fifty-odd tattoos include a lion (fitting enough), a dragon (maybe overkill?), and names of his sons (wholesome). Zlatan once said, “I don’t need tattoos to be a lion. I am already a lion.” Yet, here we are, staring at a man who is basically a walking, talking, goal-scoring canvas.</p>
<p>But maybe the real MVP of soccer ink belongs to David Beckham. His body feels like a timeline of his life - Victoria's name (aww), his kids’ names (double aww), and a full sleeve that probably took longer to complete than some of his free kicks ever did. Beckham’s tattoos are so iconic, honestly, if he ever gets a haircut, we might actually discover a secret map to the Holy Grail on his scalp.</p>
<p>Not all soccer ink is deep or meaningful, though. Some are just… there. Take Neymar, whose collection includes a lion (is that a theme?), a tiger, and a quote in Portuguese that roughly translates to “Only God can judge me.” Given his acting skills sometimes on the pitch, I'm pretty sure God’s verdict is still out.</p>
<p>And let’s not forget the late, great Diego Maradona, whose tattoos were as rebellious as his life was. His most famous ink? A portrait of Che Guevara on his right arm, because nothing says “I dribble past defenders like it’s my job” quite like a revolutionary icon staring back at you.</p>
<p>So, why do soccer stars love getting inked? Maybe it's the adrenaline rush, or maybe it's just the fame, or perhaps they simply have more disposable income than a small country. Or maybe it’s just because they can. After all, when you’re scoring goals for a living, a little ink is just part of the package deal. And if you ever find yourself in a tattoo parlor, just remember: no matter how cool your design is, it’ll never be as legendary as Messi’s left leg.</p>]]></content:encoded>
            <pubDate>Mon, 13 Jul 2026 04:00:00 GMT</pubDate>
        </item>
        <item>
            <title>Back to Static: Why I Built My Own Blog Engine (Again)</title>
            <link>https://unprompted.dirkprimbs.de/hello_world.html</link>
            <guid isPermaLink="true">https://unprompted.dirkprimbs.de/hello_world.html</guid>
            <description>A look at why I built a minimalist local-first static site generator powered by simple Python scripts, AI, and Markdown.</description>
            <content:encoded><![CDATA[<p>I have been around the web publishing block a few times. My very first blog engine was cobbled together back in the early days of static-only web pages, when CGI scripts were the only dynamic component you could lean on. Later, like many of us, I chased the dynamic wave. I wrote similar engines in ASP, ASP.NET, and PHP, riding the server-side scripting train for years.</p>
<p>Eventually, that road leads to WordPress. And with WordPress comes the constant toil - update loops, database bloat, plugin conflicts, and the never-ending security advisories. It gets exhausting when all you want to do is write down some thoughts about hardware, photography, or open source.</p>
<p>So, I decided to go back to my roots.</p>
<p>I wanted something dead simple, secure, and entirely under my control. For years, my writing has started its shelf life randomly in plain text files. I write and take notes in Markdown using Typora or Visual Studio Code, which is actually a surprisingly capable markdown environment. When LLMs came along and showed a natural affinity for Markdown, it felt like a fun validation of a workflow I had already been using for a decade.</p>
<h2>Why Not a Classic Static Site Generator?</h2>
<p>You might wonder why I didn't just pick up an established static site generator like Hugo, Jekyll, or Eleventy. The honest answer is that they feel way too complicated for what I am trying to do.</p>
<p>Most modern static site generators come bloated with extended toolchains, complex dependency trees, and a mountain of command-line magic just to get a basic theme running. By the time I configured their configuration files, customized the layouts, and set up a deployment workflow, I would have ended up writing a similar amount of custom automation code anyway. I didn't want to learn a massive framework's specific way of doing things just to render a folder of text files.</p>
<p>Plus, I just liked the experiment. Python and Ollama were already sitting on my system, and building this custom setup in close collaboration with Gemini was half the fun. It is tailored exactly to how I want to work, without any extra engineering weight.</p>
<h2>From Raw Draft to Live Post</h2>
<p>Writing a new post here feels nothing like working in a traditional CMS. I don't worry about formatting, picking categories, or fighting frontmatter syntax when I open an editor.</p>
<p>The process starts inside the <code>sources/</code> directory with a raw, messy text file. I write my notes in Typora or VS Code, often bouncing between German and English depending on whatever is in my head. I don't even add titles or dates. When I am done, I just run the publish script, which orchestrates a pipeline that turns that rough text into a live webpage.</p>
<div class="codehilite"><pre><span></span><code>[sources/draft.md] 
       │
       ▼
(Ollama / gemma4:e4b) ──► Translates, tags, and cross-links
       │
       ▼
[content/draft.md] 
       │
       ▼
(build_blog.py)       ──► Sanitizes HTML, fixes links, maps assets
       │
       ▼
[public/index.html]   ──► Syncs live via lftp
</code></pre></div>

<p>A bash script picks up the raw draft and prepares a massive prompt for a local Ollama instance running a <code>gemma4:e4b</code> model. The script feeds the AI my strict voice guidelines, a JSON list of all my existing tags, and a link manifest containing the summaries and slugs of every post I have ever published here.</p>
<p>The local model translates any German sections into clean English, formats the text with standard code blocks, selects matching tags from the existing taxonomy, and looks for natural opportunities to drop in one or two context-aware cross-links to older articles. A quick Python snippet validates that the returned YAML frontmatter is well-formed before saving the file to the <code>content/</code> folder.</p>
<p>From there, the static compiler (<code>build_blog.py</code>) handles the heavy lifting. Instead of relying on a framework, it uses standard Python tools to transform the markdown into static files. This is where a couple of custom architectural choices come in. The script runs an in-memory link pass that compares relative links against valid files in the content directory. If it finds a dead link, it heals it on the fly by stripping the broken markdown link wrapper and keeping the plain text so the site never generates a 404 error. It also scans for local images, copies them to a central assets folder, and automatically renames them using the post slug as a prefix to eliminate filename collisions.</p>
<p>The actual layout generation uses a safe rendering function to swap out variable hooks in a master HTML template. It pops the main article content out of the mapping dictionary entirely, renders the head metadata, layout attributes, and open graph tags first, and only inserts the raw article body at the very last step. This prevents broken layouts if a model-generated summary contains a stray double-quote that tries to break out of an HTML attribute.</p>
<p>Once the script finishes building the post, it regenerates the paginated index pages, updates the tag clouds, and refreshes the RSS feed. The shell script displays a quick confirmation prompt, and typing <code>y</code> triggers an automated mirror command that pushes the flat files to my web space.</p>
<h2>Hello World</h2>
<p>So, this is it - the official "Hello World" for the new setup. Every word you just read went through the exact pipeline I just described, from a chaotic text file on my laptop to a flat HTML page on a server somewhere. It feels good to have a space that just works without the overhead.</p>
<p>Now that the plumbing is sorted out, I can finally get back to what actually matters. I have a backlog of daily photography notes from around Toronto and a few hardware projects sitting on my desk that need writing up. See you in the next post.</p>]]></content:encoded>
            <pubDate>Sun, 12 Jul 2026 04:00:00 GMT</pubDate>
        </item>
</channel>
</rss>