<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Larry&#39;s Garage in English</title>
    <link>https://noblogo.org/itsmelarry-en/</link>
    <description>An assisted journey through DIY tech introspection.</description>
    <pubDate>Sat, 24 Oct 2026 17:00:43 +0000</pubDate>
    <item>
      <title>A Day of Pair Programming Without APIs</title>
      <link>https://noblogo.org/itsmelarry-en/a-day-of-pair-programming-without-apis</link>
      <description>&lt;![CDATA[The feedback loop: a human at the terminal, an AI at their side, and copy-paste holding them together&#xA;&#xA;I spent an entire day building a small software system on my home server, paired with an AI — without APIs. No agent, no access to the server: just chat, a terminal, screenshots, and a lot of copy-pasting. The system works, verified end-to-end (62 completed test downloads).&#xA;&#xA;This post isn&#39;t about the software: it&#39;s about the method. The thesis: structure makes error cheap. A verified mistake costs one turn; an unverified mistake costs a whole day.&#xA;&#xA;The constraint: the AI touches nothing&#xA;&#xA;The AI — in my case Lumo, Proton&#39;s chat model — has no access to the server. It doesn&#39;t run commands, it doesn&#39;t see the files. I am the hands, it is the copilot.&#xA;&#xA;It sounds like a heavy disadvantage, and in part it is. But it has an interesting side effect: every proposed command must be self-contained and verifiable, because there is no silent retry. The lack of automation forces discipline. And over the day I went through every phase of the lifecycle — specification, mockup, deploy, debug, hardening, backup, documentation — ending up with a system that actually worked.&#xA;&#xA;The feedback loop with copy and paste&#xA;&#xA;The loop of the day, always the same:&#xA;&#xA;AI proposes a command → I paste it into the terminal → I paste the output into the chat → the AI corrects itself&#xA;&#xA;Three rules, learned by making mistakes.&#xA;&#xA;Paste the output word for word, even when it fails. The stubbornest bug of the day — a download dying with a laconic exit code 1 — got unstuck only by pasting the complete logs: the cause was in the traceback, ten turns away. Ten turns spent guessing around an error that was already written down, black on white.&#xA;&#xA;Commands that say whether they worked. For code changes, the AI wrote small scripts that refuse to touch a file unless they find the exact portion of text to replace: either the file is the expected one, or the script stops with a clear error. No modifications that fail silently when they fail. If a control command says nothing, the work isn&#39;t finished.&#xA;&#xA;One step per turn. Never five commands at once, or you won&#39;t know which output corresponds to which action. Once I pasted text and commands together and bash replied syntax error near unexpected token — harmless, but instructive. The terminal is not a chat.&#xA;&#xA;Screenshots: the two-way channel&#xA;&#xA;When the problem is in the interface, the terminal hits its limit: you need screenshots. And the channel really is two-way — I would send UI screenshots and the AI noticed details I couldn&#39;t see: faded rows, disabled elements, a &#34;12 issues&#34; badge in the console.&#xA;&#xA;But even screenshots aren&#39;t infallible. We suspected incomplete HTML because in the browser&#39;s inspector the DOM nodes appeared collapsed (the classic ▶ hiding the children). A cat of the file cleared everything up: it was all there. You need the right kind of evidence for the right kind of question.&#xA;&#xA;Markdown as the lingua franca&#xA;&#xA;All the documentation — specification, README, bootstrap scripts — is in Markdown because it worked in three roles simultaneously: readable document for the human, structured input for the AI, persistent artifact in the repository. One format, zero translations.&#xA;&#xA;Hence the golden rule: when an exchange in chat produces a decision, that decision must be consolidated into a file. The chat is volatile, the file is memory. A fresh session with the right files beats an old semi-compacted session. Every time. And writing the specification before the code forces you to decide before you build.&#xA;&#xA;The specification as a contract&#xA;&#xA;For the specification we used OpenSpec: a propose → review → apply → verify → archive flow, requirements as WHEN/THEN scenarios, a tasks.md as a living checklist.&#xA;&#xA;I have to tell one episode. The AI, asked about OpenSpec, at first made it up: a plausible but imaginary framework. I noticed, looked up the official documentation, and gave it the links. It re-read the sources and rewrote the entire documentation package according to the real framework. The moral isn&#39;t &#34;AIs hallucinate&#34; — it&#39;s operational: verify the sources even when talking to an AI, especially when it speaks with confidence.&#xA;&#xA;The important part is the human checkpoints: the AI never moves on to the next phase without my explicit okay. Decisions to the human, execution to the AI. And the specification works as an anti-feature-creep frame: every scope question (&#34;what about videos?&#34;) got the answer &#34;out of scope, that&#39;ll be another change&#34;. That&#39;s how a small project stays small.&#xA;&#xA;Bug fixing as a conversation&#xA;&#xA;The lifecycle of every bug: symptom reported in full (complete logs, not interpretation), a hypothesis declared as such (&#34;I suspect X, let&#39;s verify with Y&#34; ≠ &#34;it&#39;s X, solved&#34;), diagnosis backed by evidence, surgical fix and retry. Of the AI&#39;s mistakes, one deserves a note: it had itself generated a bug in a module; re-reading its own code, it noticed, recreated it clean, and told me openly.&#xA;&#xA;The episode that defines the day is another one, and I&#39;m the protagonist.&#xA;&#xA;Three patches in a row, three failures. The download stayed broken, and the AI kept proposing corrections. At some point I stopped: it&#39;s patching code that doesn&#39;t match the real one. Compaction — long chats get summarized, and the fine details get lost — had eaten its overview of the codebase. It was patching imaginary code.&#xA;&#xA;I wrote something like: &#34;maybe you should re-read the code, compaction may have made you lose context.&#34; That was exactly it. Re-reading the real code, and the solution came.&#xA;&#xA;This problem is a direct consequence of the absence of APIs: an agent with access would read the file on every change. Without APIs, the freshness of the context is a shared responsibility — the AI can&#39;t notice that its map has stopped matching the territory. Someone has to tell it. After three failed patches: stop and ask it to re-read the real code, not the fourth blind patch.&#xA;&#xA;Compaction: survival strategies&#xA;&#xA;Compaction is the normal behavior of long chats: old messages get summarized, fine details get lost. We went through more than three. I learned to recognize the signs of degradation: the AI starts guessing code patterns, proposes fixes for code that doesn&#39;t exist, repeats suggestions already tried.&#xA;&#xA;On the left, the degraded, faded context; on the right, the same rebuilt sharp by the full dump&#xA;&#xA;Four strategies worked.&#xA;&#xA;Document while you work. The system design, written in Markdown at the start of the session, survived three compactions. The details didn&#39;t, the structure did.&#xA;The full dump. When remote patching stopped working, I created a single file with ALL the project&#39;s code — a bash script with a loop of docker exec ... cat, plus DB state and archive — and uploaded it into the chat. Cost: two minutes. Benefit: the AI stops guessing. The cheapest context reset there is.&#xA;Verify the memory. Ask &#34;what do you remember about X?&#34; and compare with reality. If it diverges, give the file again — don&#39;t correct it in words.&#xA;Start over from the file, not from the chat.&#xA;&#xA;Everything else — the backup before the risky touch (cp file file.bak), the output pasted in full — is the same idea at the scale of a single turn: give the AI fresh data instead of letting it reason on stale data.&#xA;&#xA;The human as the hands&#xA;&#xA;The complete operating model: I provide the eyes, judgment, and terminal-pasting; the AI provides technical memory and generation. But I&#39;m not a passive executor: I verified, rejected, corrected, decided scope and cuts.&#xA;&#xA;And the bottleneck was never the AI&#39;s speed: it&#39;s the quality of the feedback I reported back to it. A complete log pasted right away is worth ten turns of descriptions.&#xA;&#xA;The canvas: when the chat stops being the only surface&#xA;&#xA;Something happened right in the middle of the session: suddenly, the AI started publishing long-form content in a side panel — a canvas. The feature had just been activated by the platform, and we found ourselves in it without noticing.&#xA;&#xA;And it was a turning point. Before, every long document had to be printed in the chat and copied by hand, line by line: it worked, it was laborious, and it was the point where the method frayed. With the canvas, long content becomes a first-class object: you view it whole, you revise it, you export it.&#xA;&#xA;Separation between conversation and artifact. The chat remains a volatile laboratory — you try, you correct, you discard. The canvas holds the good versions: the materialization of &#34;chat is for working, the file is for remembering&#34;.&#xA;Artifacts have a lifecycle. The OpenSpec specification was rewritten three times in the same canvas. The artifact evolves, the chat flows underneath.&#xA;The mockup gets clicked. For the UI we didn&#39;t discuss in words: the AI created an interactive HTML mockup — a five-step wizard, with error states and a design system. I clicked through it and gave feedback on the real flow. UX validated before a single line of code.&#xA;Artifacts travel. The markdown-seed of this session — from which this very post was born — is the natural extension: the canvas as the origin of subsequent chains of work.&#xA;&#xA;Without the canvas, all long-form content lives in the chat and dies with compaction. With the canvas, it persists. It turns brainstorming into process: the difference between talking about an idea and having a version of it.&#xA;&#xA;Why it works&#xA;&#xA;The thesis: structure makes error cheap. The fully pasted output makes the error visible immediately; scripts with built-in checks make the wrong modification fail loudly; the human checkpoint stops the scope error while it&#39;s still cheap; the dump restores context while it still costs two minutes.&#xA;&#xA;And there&#39;s the rubber-duck effect: explaining the problem to the AI — or pasting it the log, which is explaining with facts — is half the diagnostic work. More than once, while composing the bug description, I figured out where it was on my own.&#xA;&#xA;With APIs, an agent with direct access would make much of this method unnecessary. You&#39;d go faster and more comfortably. But there&#39;s one thing working without APIs leaves you with that automation doesn&#39;t give: the working dynamics with the AI become visible. You see where the context degrades, you see when it starts guessing, you see which information makes it fail and which gets it back on track. Understanding it is the prerequisite for using it well: I&#39;m coming out of this day not only with a working system, but knowing exactly what it means to give it good information.&#xA;&#xA;Because the warning stays valid even at maximum automation: APIs take away the fatigue of copy-pasting, not the responsibility for the quality of the information the AI works with. That one, better never fully delegate.&#xA;&#xA;---&#xD;&#xA;  &#34;Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.&#34;&#xD;&#xA;&#xD;&#xA;👤 Lorenzo | ItsMeLarry&#xD;&#xA;🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels&#xD;&#xA;🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First&#xD;&#xA;📍 Tuscany / Digital&#xD;&#xA;&#xD;&#xA;🔗 noblogo.org/itsmelarry-en | 🐙 GitHub]]&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://pixelfed.uno/storage/m/_v2/901608309406204096/0e0206425-c6ee71/AIPnnIe92yLs/O5yD3ZE3n3La8sC0gAXmRecH1mJV999xXYaLYmlN.jpg" alt="The feedback loop: a human at the terminal, an AI at their side, and copy-paste holding them together"></p>

<p>I spent an entire day building a small software system on my home server, paired with an AI — without APIs. No agent, no access to the server: just chat, a terminal, screenshots, and a lot of copy-pasting. The system works, verified end-to-end (62 completed test downloads).</p>

<p>This post isn&#39;t about the software: it&#39;s about the method. The thesis: <strong>structure makes error cheap</strong>. A verified mistake costs one turn; an unverified mistake costs a whole day.</p>

<h2 id="the-constraint-the-ai-touches-nothing">The constraint: the AI touches nothing</h2>

<p>The AI — in my case Lumo, Proton&#39;s chat model — has no access to the server. It doesn&#39;t run commands, it doesn&#39;t see the files. I am the hands, it is the copilot.</p>

<p>It sounds like a heavy disadvantage, and in part it is. But it has an interesting side effect: every proposed command must be self-contained and verifiable, because there is no silent retry. The lack of automation forces discipline. And over the day I went through every phase of the lifecycle — specification, mockup, deploy, debug, hardening, backup, documentation — ending up with a system that actually worked.</p>

<h2 id="the-feedback-loop-with-copy-and-paste">The feedback loop with copy and paste</h2>

<p>The loop of the day, always the same:</p>

<pre><code class="language-text">AI proposes a command → I paste it into the terminal → I paste the output into the chat → the AI corrects itself
</code></pre>

<p>Three rules, learned by making mistakes.</p>

<p><strong>Paste the output word for word, even when it fails.</strong> The stubbornest bug of the day — a download dying with a laconic <code>exit code 1</code> — got unstuck only by pasting the complete logs: the cause was in the traceback, ten turns away. Ten turns spent guessing around an error that was already written down, black on white.</p>

<p><strong>Commands that say whether they worked.</strong> For code changes, the AI wrote small scripts that refuse to touch a file unless they find the exact portion of text to replace: either the file is the expected one, or the script stops with a clear error. No modifications that fail silently when they fail. If a control command says nothing, the work isn&#39;t finished.</p>

<p><strong>One step per turn.</strong> Never five commands at once, or you won&#39;t know which output corresponds to which action. Once I pasted text and commands together and bash replied <code>syntax error near unexpected token</code> — harmless, but instructive. The terminal is not a chat.</p>

<h2 id="screenshots-the-two-way-channel">Screenshots: the two-way channel</h2>

<p>When the problem is in the interface, the terminal hits its limit: you need screenshots. And the channel really is two-way — I would send UI screenshots and the AI noticed details I couldn&#39;t see: faded rows, disabled elements, a “12 issues” badge in the console.</p>

<p>But even screenshots aren&#39;t infallible. We suspected incomplete HTML because in the browser&#39;s inspector the DOM nodes appeared <em>collapsed</em> (the classic ▶ hiding the children). A <code>cat</code> of the file cleared everything up: it was all there. You need the right kind of evidence for the right kind of question.</p>

<h2 id="markdown-as-the-lingua-franca">Markdown as the lingua franca</h2>

<p>All the documentation — specification, README, bootstrap scripts — is in Markdown because it worked in three roles simultaneously: readable document for the human, structured input for the AI, persistent artifact in the repository. One format, zero translations.</p>

<p>Hence the golden rule: <strong>when an exchange in chat produces a decision, that decision must be consolidated into a file</strong>. The chat is volatile, the file is memory. A fresh session with the right files beats an old semi-compacted session. Every time. And writing the specification before the code forces you to decide before you build.</p>

<h2 id="the-specification-as-a-contract">The specification as a contract</h2>

<p>For the specification we used OpenSpec: a propose → review → apply → verify → archive flow, requirements as WHEN/THEN scenarios, a <code>tasks.md</code> as a living checklist.</p>

<p>I have to tell one episode. The AI, asked about OpenSpec, at first <em>made it up</em>: a plausible but imaginary framework. I noticed, looked up the official documentation, and gave it the links. It re-read the sources and rewrote the entire documentation package according to the real framework. The moral isn&#39;t “AIs hallucinate” — it&#39;s operational: verify the sources even when talking to an AI, especially when it speaks with confidence.</p>

<p>The important part is the <strong>human checkpoints</strong>: the AI never moves on to the next phase without my explicit okay. Decisions to the human, execution to the AI. And the specification works as an anti-feature-creep frame: every scope question (“what about videos?”) got the answer “out of scope, that&#39;ll be another change”. That&#39;s how a small project stays small.</p>

<h2 id="bug-fixing-as-a-conversation">Bug fixing as a conversation</h2>

<p>The lifecycle of every bug: symptom reported in full (complete logs, not interpretation), a hypothesis <strong>declared as such</strong> (“I suspect X, let&#39;s verify with Y” ≠ “it&#39;s X, solved”), diagnosis backed by evidence, surgical fix and retry. Of the AI&#39;s mistakes, one deserves a note: it had itself generated a bug in a module; re-reading its own code, it noticed, recreated it clean, and told me openly.</p>

<p>The episode that defines the day is another one, and I&#39;m the protagonist.</p>

<p>Three patches in a row, three failures. The download stayed broken, and the AI kept proposing corrections. At some point I stopped: it&#39;s patching code that doesn&#39;t match the real one. Compaction — long chats get summarized, and the fine details get lost — had eaten its overview of the codebase. It was patching imaginary code.</p>

<p>I wrote something like: “maybe you should re-read the code, compaction may have made you lose context.” That was exactly it. Re-reading the real code, and the solution came.</p>

<p>This problem is a direct consequence of the absence of APIs: an agent with access would read the file on every change. Without APIs, the freshness of the context is a shared responsibility — the AI can&#39;t notice that its map has stopped matching the territory. Someone has to tell it. <strong>After three failed patches: stop and ask it to re-read the real code, not the fourth blind patch.</strong></p>

<h2 id="compaction-survival-strategies">Compaction: survival strategies</h2>

<p>Compaction is the normal behavior of long chats: old messages get summarized, fine details get lost. We went through more than three. I learned to recognize the signs of degradation: the AI starts guessing code patterns, proposes fixes for code that doesn&#39;t exist, repeats suggestions already tried.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/901608309406204096/0e0206425-c6ee71/kgmyMX7sWStN/m0gmJTFaCIJwx7rLlYjKTqYiDnSGyXff7EG7ItPy.jpg" alt="On the left, the degraded, faded context; on the right, the same rebuilt sharp by the full dump"></p>

<p>Four strategies worked.</p>
<ol><li><strong>Document while you work.</strong> The system design, written in Markdown at the start of the session, survived three compactions. The details didn&#39;t, the structure did.</li>
<li><strong>The full dump.</strong> When remote patching stopped working, I created a single file with ALL the project&#39;s code — a bash script with a loop of <code>docker exec ... cat</code>, plus DB state and archive — and uploaded it into the chat. Cost: two minutes. Benefit: the AI stops guessing. The cheapest context reset there is.</li>
<li><strong>Verify the memory.</strong> Ask “what do you remember about X?” and compare with reality. If it diverges, give the file again — don&#39;t correct it in words.</li>
<li><strong>Start over from the file, not from the chat.</strong></li></ol>

<p>Everything else — the backup before the risky touch (<code>cp file file.bak</code>), the output pasted in full — is the same idea at the scale of a single turn: give the AI fresh data instead of letting it reason on stale data.</p>

<h2 id="the-human-as-the-hands">The human as the hands</h2>

<p>The complete operating model: I provide the eyes, judgment, and terminal-pasting; the AI provides technical memory and generation. But I&#39;m not a passive executor: I verified, rejected, corrected, decided scope and cuts.</p>

<p>And the bottleneck was never the AI&#39;s speed: it&#39;s the quality of the feedback I reported back to it. A complete log pasted right away is worth ten turns of descriptions.</p>

<h2 id="the-canvas-when-the-chat-stops-being-the-only-surface">The canvas: when the chat stops being the only surface</h2>

<p>Something happened <em>right in the middle</em> of the session: suddenly, the AI started publishing long-form content in a side panel — a canvas. The feature had just been activated by the platform, and we found ourselves in it without noticing.</p>

<p>And it was a turning point. Before, every long document had to be printed in the chat and copied by hand, line by line: it worked, it was laborious, and it was the point where the method frayed. With the canvas, long content becomes a first-class object: you view it whole, you revise it, you export it.</p>
<ul><li><strong>Separation between conversation and artifact.</strong> The chat remains a volatile laboratory — you try, you correct, you discard. The canvas holds the good versions: the materialization of “chat is for working, the file is for remembering”.</li>
<li><strong>Artifacts have a lifecycle.</strong> The OpenSpec specification was rewritten three times in the same canvas. The artifact evolves, the chat flows underneath.</li>
<li><strong>The mockup gets clicked.</strong> For the UI we didn&#39;t discuss in words: the AI created an interactive HTML mockup — a five-step wizard, with error states and a design system. I clicked through it and gave feedback on the real flow. UX validated before a single line of code.</li>
<li><strong>Artifacts travel.</strong> The markdown-seed of this session — from which this very post was born — is the natural extension: the canvas as the origin of subsequent chains of work.</li></ul>

<p>Without the canvas, all long-form content lives in the chat and dies with compaction. With the canvas, it persists. It turns brainstorming into process: the difference between talking about an idea and having a version of it.</p>

<h2 id="why-it-works">Why it works</h2>

<p>The thesis: structure makes error cheap. The fully pasted output makes the error visible immediately; scripts with built-in checks make the wrong modification fail loudly; the human checkpoint stops the scope error while it&#39;s still cheap; the dump restores context while it still costs two minutes.</p>

<p>And there&#39;s the rubber-duck effect: explaining the problem to the AI — or pasting it the log, which is explaining with facts — is half the diagnostic work. More than once, while composing the bug description, I figured out where it was on my own.</p>

<p>With APIs, an agent with direct access would make much of this method unnecessary. You&#39;d go faster and more comfortably. But there&#39;s one thing working without APIs leaves you with that automation doesn&#39;t give: the working dynamics with the AI become <em>visible</em>. You see where the context degrades, you see when it starts guessing, you see which information makes it fail and which gets it back on track. Understanding it is the prerequisite for using it well: I&#39;m coming out of this day not only with a working system, but knowing exactly what it means to give it good information.</p>

<p>Because the warning stays valid even at maximum automation: APIs take away the fatigue of copy-pasting, not the responsibility for the quality of the information the AI works with. That one, better never fully delegate.</p>

<hr>

<blockquote><p><em>“Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.”</em></p></blockquote>

<p>👤 <strong>Lorenzo</strong> | <em>ItsMeLarry</em>
🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels
🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First
📍 <em>Tuscany / Digital</em></p>

<p>🔗 <a href="https://noblogo.org/itsmelarry-en" rel="nofollow">noblogo.org/itsmelarry-en</a> | 🐙 <a href="https://github.com/itsmelarrybox" rel="nofollow">GitHub</a></p>
]]></content:encoded>
      <guid>https://noblogo.org/itsmelarry-en/a-day-of-pair-programming-without-apis</guid>
      <pubDate>Sat, 24 Oct 2026 13:00:34 +0000</pubDate>
    </item>
    <item>
      <title>From a €50 Used PC (with a Rebellious BIOS) to a Media Center in One Evening</title>
      <link>https://noblogo.org/itsmelarry-en/from-a-eu50-used-pc-with-a-rebellious-bios-to-a-media-center-in-one-evening</link>
      <description>&lt;![CDATA[Yesterday morning I woke up and minimonio was gone. Not in the physical sense: in the sense that it powered on, gave me a dirty look, and dropped me in front of the BIOS screen, refusing to boot Ubuntu. It had crashed during the night, period. The NVMe drive was still there, the BIOS could see it, but the bootloader was nowhere to be found.&#xA;&#xA;I had built a small agent on it that returned system info. Reinstalling everything from scratch turned out to be faster than playing GRUB surgeon in my pajamas before coffee. So last night minimonio restarted from a fresh install of Ubuntu Server, and I thought: since I have to rebuild, let&#39;s do it properly.&#xA;&#xA;Goal for the evening: turn a mini-PC bought used for 50 euros (Celeron N5095, 7GB of RAM, one TB of disk) into a media server to listen to my ripped CDs — Oasis, Pink Floyd, and so on and so forth — without firing up the laptop every time. Final chain: minimonio → UPnP → WiiM Ultra → Bluetooth headphones.&#xA;&#xA;I went to bed at one in the morning with The Wall in my ears. An honest account of how I got there, mistakes included.&#xA;&#xA;Many mistakes, much fun.&#xA;&#xA;€50 media center&#xA;&#xA;The cast of the home network&#xA;&#xA;minimonio isn&#39;t alone: other nodes live in the house.&#xA;&#xA;tuxedo: my personal laptop, where music syncing starts from.&#xA;geekmonio: the powerful machine, with Ollama for local inference.&#xA;thinkmonio: an old edge node.&#xA;&#xA;Heterogeneous hardware, different roles, and a single conversation with the AI running through all of them. Tonight, though, the star is the €50 Celeron.&#xA;&#xA;The architectural choices&#xA;&#xA;Philosophy: small services, isolated containers, everything that survives reboots. The glue is Docker.&#xA;&#xA;Navidrome: Subsonic-compatible music server, extremely lightweight.&#xA;Heimdall: dashboard to keep everything one tile away.&#xA;Gerbera: DLNA/UPnP server, to let the server talk to the Smart TV and the WiiM Ultra.&#xA;Samba: for direct file access.&#xA;&#xA;All with restart: unless-stopped, because after a server that dies in its sleep, you don&#39;t joke about uptime anymore.&#xA;&#xA;The library comes from tuxedo via rsync over SSH, launched inside tmux — never trust a Wi-Fi connection with a terabyte of music.&#xA;&#xA;The evening, however, didn&#39;t go according to plan. The evening went better.&#xA;&#xA;The stumbles: the honest heart of this post&#xA;&#xA;If I had followed a tutorial, everything would have been linear. Instead it was an obstacle course. Which is exactly why I&#39;m writing this post.&#xA;&#xA;The package that doesn&#39;t exist&#xA;&#xA;First obstacle, almost immediately: installing Docker Compose.&#xA;&#xA;sudo apt install -y docker.io docker-compose-plugin&#xA;&#xA;Error: Unable to locate package docker-compose-plugin&#xA;&#xA;The suggestion came from the AI, the name was plausible, the terminal was telling the truth: on Ubuntu the package is called docker-compose-v2. First lesson of the evening, and the AI learned it too:&#xA;&#xA;sudo apt install -y docker.io docker-compose-v2&#xA;&#xA;Navidrome in a crash-loop&#xA;&#xA;The container started, died, restarted, died. docker compose ps showed Restarting (1) in a loop, and in the logs always the same message:&#xA;&#xA;level=fatal msg=&#34;Database could not be opened!&#34; error=&#34;unable to open database file: no such file or directory&#34;&#xA;&#xA;Cause: the host folder mounted as /data either didn&#39;t exist or wasn&#39;t writable by the user 1000:1000 that Navidrome runs as. Containers aren&#39;t magic: a bind mount is just a folder, and permissions are permissions.&#xA;&#xA;mkdir -p ~/docker/navidrome ~/media/music&#xA;sudo chown -R 1000:1000 ~/docker/navidrome ~/media/music&#xA;docker compose up -d&#xA;&#xA;From then on, Navidrome stopped crying.&#xA;&#xA;Side note for anyone finding themselves in the same mess: with Compose v2 the container name is prefixed by the project folder (lorenzo-navidrome-1, not navidrome), so docker logs navidrome answers with No such container. Either you use the full name, or docker compose logs navidrome.&#xA;&#xA;Gerbera&#39;s dancing port&#xA;&#xA;At first launch, Gerbera&#39;s web UI had ended up on a semi-random port (49494). It looked stable, but I didn&#39;t want to play &#34;guess the port&#34; at every reinstall — and given how the previous night had gone, reinstalls weren&#39;t an unlikely event. I changed the port in the config with sed and pinned it there forever. An observation, not documented certainty: I ran into this behavior at first launch, and that alone was enough to convince me to write the port into the config by hand.&#xA;&#xA;Same family of problem, different father: nano reported config.xml as unwritable. The file had been created by the process inside the container, which runs as root:&#xA;&#xA;sudo chown -R 1000:1000 ~/docker/gerbera&#xA;&#xA;Gerbera doesn&#39;t even have a default icon in the Heimdall library, so I added the tile by hand. Small things, but they&#39;re what makes the difference between &#34;unattended&#34; and &#34;let&#39;s go check&#34;.&#xA;&#xA;The bash bug in the sync script&#xA;&#xA;The highlight. The syncmusic.sh script got stuck with a cryptic error:&#xA;&#xA;Empty source arg specified.&#xA;rsync error: syntax or usage error (code 1) at main.c(1526) [sender=3.2.7]&#xA;&#xA;Culprit: an empty &#34;$DRYRUN&#34; variable, passing an empty string to rsync as an argument — and rsync interpreted it as a missing source. Fix: turn it into an array, which expands to zero arguments when empty, as God intended.&#xA;&#xA;DRYRUN=()&#xA;[[ &#34;${1:-}&#34; == &#34;-n&#34; ]] &amp;&amp; DRYRUN=(--dry-run)&#xA;...&#xA;rsync &#34;${RSYNCOPTS[@]}&#34; &#34;${DRYRUN[@]}&#34; &#34;$SRC&#34; ...&#xA;&#xA;Second round, right after:&#xA;&#xA;./syncmusic.sh: line 47: DRYRUN: unbound variable&#xA;&#xA;With set -u active, the test [[ -n &#34;$DRYRUN&#34; ]] uses the scalar form of the array which, when empty, counts as unbound. The length had to be tested instead:&#xA;&#xA;[[ ${#DRYRUN[@]} -gt 0 ]]&#xA;&#xA;Bash has a sneaky type system. I applied the same two corrected lines with sed, because at that hour of the night rewriting by hand was asking too much.&#xA;&#xA;&#34;Pink Floid&#34; and the ghost album&#xA;&#xA;During the sync I discovered that a folder christened &#34;Pink Floid&#34; — original typo, years of honorable service — lives on two machines and only got fixed on one. And the ghost album: &#34;The Division Bell&#34; exists only on the server.&#xA;&#xA;Neither is a bug. It&#39;s the logical consequence of an rsync without --delete: it copies new files but never deletes anything, so it&#39;s not a mirror. In the final version of the script --delete is there, but that night it wasn&#39;t — and the ghost &#34;Be Here Now&#34; is living proof. Double moral: if you want a true mirror, tell rsync so; and for music, ID3 tags are what count, not folder names.&#xA;&#xA;The false errors&#xA;&#xA;Bonus of the evening, the errors that weren&#39;t errors:&#xA;&#xA;Navidrome answered HTTP 302: a redirect to the login page, which is the correct response from curl without a session.&#xA;docker ps showed no ports for Gerbera: normal with networkmode: host, the container uses the machine&#39;s interfaces directly.&#xA;A WARN about the obsolete version: line in the compose file: just a warning, modern compose files don&#39;t need it anymore.&#xA;&#xA;Learning to tell a real error from an apparent one is half the craft.&#xA;&#xA;The moment of glory&#xA;&#xA;Final test: full server reboot. A simulated blackout, so to speak. Ritual-grade checklist with docker ps and curl:&#xA;&#xA;Navidrome: Up, HTTP 302 (redirect to login, all in order).&#xA;Heimdall: Up, HTTP 200.&#xA;Gerbera: Up, HTTP 200.&#xA;&#xA;Three containers up, three healthy responses. Fully unattended: blackouts, reboots, updates — after the night of the BIOS, I&#39;ve earned this minimum of dignity.&#xA;&#xA;At one in the morning I was in bed with The Wall in my headphones, via WiiM, without the laptop ever having been switched on. The €50 Celeron had earned it.&#xA;&#xA;From CD to my ears&#xA;&#xA;Reflections on working with the AI&#xA;&#xA;The evening was an experiment in pair-sysadmining: the AI proposed, I executed, the terminal arbitrated. When the AI suggested a wrong package name, the terminal exposed it in a second. The AI&#39;s mistakes aren&#39;t a problem if the feedback loop is tight.&#xA;&#xA;There&#39;s a difference between a tutorial and a real session: the tutorial shows the ideal path, the real session is an obstacle course. Both teach you something, but only the second one teaches you how to diagnose. And diagnosing — asking yourself &#34;does it change across reboots?&#34;, telling a 302 from a 500, understanding why an empty variable explodes — is the part that stays with you.&#xA;&#xA;Good music, and goodnight from here too.&#xA;&#xA;---&#xA;&#xA;Transparency note: the AI in the &#34;pair-sysadmining&#34; told above is called Lumo, and it&#39;s Proton&#39;s assistant — the same folks behind encrypted email. I&#39;m liking it: besides giving me wrong suggestions about package names (and taking them bounced back from the terminal with good sportsmanship), it has a newly released canvas feature that turned writing this post into a side-by-side job — notes, drafts, and live revisions, while the music kept playing from the containers. If you want to try it, here&#39;s my referral link, and if you made it all the way down here reading, you also deserve the 10-euro discount that comes with my link.&#xA;&#xA;docker-compose.yml&#xA;&#xA;services:&#xA;  navidrome:&#xA;    image: deluan/navidrome:latest&#xA;    user: 1000:1000&#xA;    ports:&#xA;      &#34;4533:4533&#34;&#xA;    volumes:&#xA;      /home/lorenzo/media/music:/music&#xA;      /home/lorenzo/docker/navidrome:/data&#xA;    environment:&#xA;      NDLOGLEVEL=info&#xA;      NDSCANSCHEDULE=1h&#xA;      NDSESSIONTIMEOUT=168h&#xA;    restart: unless-stopped&#xA;&#xA;  heimdall:&#xA;    image: linuxserver/heimdall&#xA;    ports:&#xA;      &#34;8080:80&#34;&#xA;    volumes:&#xA;      /home/lorenzo/docker/heimdall:/config&#xA;    restart: unless-stopped&#xA;&#xA;  gerbera:&#xA;    image: gerbera/gerbera&#xA;    containername: gerbera&#xA;    networkmode: host&#xA;    volumes:&#xA;      /home/lorenzo/media/music:/content:ro&#xA;      /home/lorenzo/docker/gerbera/config:/var/run/gerbera&#xA;    restart: unless-stopped&#xA;&#xA;syncmusic.sh&#xA;&#xA;!/bin/bash&#xA;syncmusic.sh — Sync music from Tuxedo to Minimonio (one-way, rsync via SSH)&#xA;Usage: ./syncmusic.sh [-n]&#xA;-n : dry-run (shows what it would do without copying anything)&#xA;&#xA;set -euo pipefail&#xA;&#xA;---------- CONFIGURATION ----------&#xA;SRC=&#34;/home/lorenzo/Musica/&#34;          # Source folder on Tuxedo (NOTE the trailing slash!)&#xA;DSTUSER=&#34;lorenzo&#34;&#xA;DSTHOST=&#34;192.168.1.201&#34;             # minimonio&#39;s IP&#xA;DSTPATH=&#34;media/music/&#34;              # Destination, relative to home on minimonio&#xA;LOGDIR=&#34;$HOME/logs&#34;&#xA;LOGFILE=&#34;$LOGDIR/syncmusic$(date +%Y%m%d%H%M%S).log&#34;&#xA;KEEPLOGS=10                          # Number of old logs to keep&#xA;LOCKFILE=&#34;/tmp/syncmusic.lock&#34;&#xA;------------------------------------&#xA;&#xA;DRYRUN=()&#xA;[[ &#34;${1:-}&#34; == &#34;-n&#34; ]] &amp;&amp; DRYRUN=(--dry-run)&#xA;&#xA;--- Duplicate-run protection ---&#xA;if [[ -f &#34;$LOCKFILE&#34; ]] &amp;&amp; kill -0 &#34;$(cat &#34;$LOCKFILE&#34;)&#34; 2  /dev/null; then&#xA;    echo &#34;❌ Another sync is already running (PID $(cat &#34;$LOCKFILE&#34;)). Exiting.&#34;&#xA;    exit 1&#xA;fi&#xA;echo $$   &#34;$LOCKFILE&#34;&#xA;trap &#39;rm -f &#34;$LOCKFILE&#34;&#39; EXIT&#xA;&#xA;mkdir -p &#34;$LOGDIR&#34;&#xA;&#xA;--- Source check ---&#xA;if [[ ! -d &#34;$SRC&#34; ]]; then&#xA;    echo &#34;❌ Source folder $SRC not found. Edit SRC in the script.&#34;&#xA;    exit 1&#xA;fi&#xA;&#xA;MP3COUNT=$(find &#34;$SRC&#34; -type f \( -iname &#39;.mp3&#39; -o -iname &#39;.flac&#39; -o -iname &#39;.m4a&#39; \) | wc -l)&#xA;if [[ &#34;$MP3COUNT&#34; -eq 0 ]]; then&#xA;    echo &#34;⚠️  No music files found in $SRC — checking before continuing.&#34;&#xA;    read -rp &#34;Proceed anyway? [y/N] &#34; ans&#xA;    [[ &#34;$ans&#34; == &#34;y&#34; ]] || exit 0&#xA;fi&#xA;&#xA;echo &#34;🎵 Music sync: $SRC -  $DSTUSER@$DSTHOST:$DSTPATH&#34;&#xA;echo &#34;   Music files in source: $MP3COUNT&#34;&#xA;[[ ${#DRYRUN[@]} -gt 0 ]] &amp;&amp; echo &#34;   (DRY-RUN: no files will actually be copied)&#34;&#xA;echo &#34;&#34;&#xA;&#xA;--- Reachability ---&#xA;if ! ping -c1 -W2 &#34;$DSTHOST&#34;   /dev/null 2  &amp;1; then&#xA;    echo &#34;❌ $DSTHOST unreachable. Check the network.&#34;&#xA;    exit 1&#xA;fi&#xA;&#xA;--- Synchronization ---&#xA;-a  preserves permissions, dates, structure&#xA;-v  verbose&#xA;-h  human-readable sizes&#xA;--delete  deletes on destination what was removed from source (true mirror)&#xA;--info=progress2  overall progress bar&#xA;--exclude  skips temporary and hidden files&#xA;RSYNCOPTS=(-avh --info=progress2 --stats&#xA;            --exclude=&#39;.&#39; --exclude=&#39;Thumbs.db&#39; --exclude=&#39;desktop.ini&#39;&#xA;            --exclude=&#39;.tmp&#39;)&#xA;&#xA;echo &#34;   Note: mirroring ACTIVE (--delete). Comment it out to keep removed files.&#34;&#xA;echo &#34;&#34;&#xA;&#xA;rsync &#34;${RSYNCOPTS[@]}&#34; &#34;${DRYRUN[@]}&#34; &#34;$SRC&#34; &#34;$DSTUSER@$DSTHOST:$DSTPATH&#34; 2  &amp;1 | tee &#34;$LOGFILE&#34;&#xA;&#xA;--- Old log cleanup ---&#xA;ls -1t &#34;$LOGDIR&#34;/syncmusic.log 2  /dev/null | tail -n +&#34;$((KEEPLOGS + 1))&#34; | xargs -r rm --&#xA;&#xA;echo &#34;&#34;&#xA;echo &#34;✅ Sync completed. Log: $LOGFILE&#34;&#xA;&#xA;--- Tip ---&#xA;if [[ ${#DRYRUN[@]} -eq 0 ]]; then&#xA;    echo &#34;ℹ️  Navidrome re-scans the library within 1 hour (NDSCANSCHEDULE=1h).&#34;&#xA;    echo &#34;   To force the scan now: open http://$DST_HOST:4533 and go to ⚙ → Scan Library.&#34;&#xA;fi&#xA;&#xA;---&#xD;&#xA;  &#34;Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.&#34;&#xD;&#xA;&#xD;&#xA;👤 Lorenzo | ItsMeLarry&#xD;&#xA;🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels&#xD;&#xA;🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First&#xD;&#xA;📍 Tuscany / Digital&#xD;&#xA;&#xD;&#xA;🔗 noblogo.org/itsmelarry-en | 🐙 GitHub]]&gt;</description>
      <content:encoded><![CDATA[<p>Yesterday morning I woke up and minimonio was gone. Not in the physical sense: in the sense that it powered on, gave me a dirty look, and dropped me in front of the BIOS screen, refusing to boot Ubuntu. It had crashed during the night, period. The NVMe drive was still there, the BIOS could see it, but the bootloader was nowhere to be found.</p>

<p>I had built a small agent on it that returned system info. Reinstalling everything from scratch turned out to be faster than playing GRUB surgeon in my pajamas before coffee. So last night minimonio restarted from a fresh install of Ubuntu Server, and I thought: since I have to rebuild, let&#39;s do it properly.</p>

<p>Goal for the evening: turn a mini-PC bought used for 50 euros (Celeron N5095, 7GB of RAM, one TB of disk) into a media server to listen to my ripped CDs — Oasis, Pink Floyd, and so on and so forth — without firing up the laptop every time. Final chain: minimonio → UPnP → WiiM Ultra → Bluetooth headphones.</p>

<p>I went to bed at one in the morning with The Wall in my ears. An honest account of how I got there, mistakes included.</p>

<p>Many mistakes, much fun.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/901608309406204096/0e0206425-c6ee71/9919Mct4MpQi/GDj9PZOzh8wCBN2i54QOYXvhLZRgJiBJP2Xc9j5R.jpg" alt="€50 media center"></p>

<h2 id="the-cast-of-the-home-network">The cast of the home network</h2>

<p>minimonio isn&#39;t alone: other nodes live in the house.</p>
<ul><li><strong>tuxedo</strong>: my personal laptop, where music syncing starts from.</li>
<li><strong>geekmonio</strong>: the powerful machine, with Ollama for local inference.</li>
<li><strong>thinkmonio</strong>: an old edge node.</li></ul>

<p>Heterogeneous hardware, different roles, and a single conversation with the AI running through all of them. Tonight, though, the star is the €50 Celeron.</p>

<h2 id="the-architectural-choices">The architectural choices</h2>

<p>Philosophy: small services, isolated containers, everything that survives reboots. The glue is Docker.</p>
<ul><li><strong>Navidrome</strong>: Subsonic-compatible music server, extremely lightweight.</li>
<li><strong>Heimdall</strong>: dashboard to keep everything one tile away.</li>
<li><strong>Gerbera</strong>: DLNA/UPnP server, to let the server talk to the Smart TV and the WiiM Ultra.</li>
<li><strong>Samba</strong>: for direct file access.</li></ul>

<p>All with <code>restart: unless-stopped</code>, because after a server that dies in its sleep, you don&#39;t joke about uptime anymore.</p>

<p>The library comes from tuxedo via <code>rsync</code> over SSH, launched inside <code>tmux</code> — never trust a Wi-Fi connection with a terabyte of music.</p>

<p>The evening, however, didn&#39;t go according to plan. The evening went better.</p>

<h2 id="the-stumbles-the-honest-heart-of-this-post">The stumbles: the honest heart of this post</h2>

<p>If I had followed a tutorial, everything would have been linear. Instead it was an obstacle course. Which is exactly why I&#39;m writing this post.</p>

<h3 id="the-package-that-doesn-t-exist">The package that doesn&#39;t exist</h3>

<p>First obstacle, almost immediately: installing Docker Compose.</p>

<pre><code class="language-bash">sudo apt install -y docker.io docker-compose-plugin
</code></pre>

<pre><code class="language-text">Error: Unable to locate package docker-compose-plugin
</code></pre>

<p>The suggestion came from the AI, the name was plausible, the terminal was telling the truth: on Ubuntu the package is called <code>docker-compose-v2</code>. First lesson of the evening, and the AI learned it too:</p>

<pre><code class="language-bash">sudo apt install -y docker.io docker-compose-v2
</code></pre>

<h3 id="navidrome-in-a-crash-loop">Navidrome in a crash-loop</h3>

<p>The container started, died, restarted, died. <code>docker compose ps</code> showed <code>Restarting (1)</code> in a loop, and in the logs always the same message:</p>

<pre><code class="language-text">level=fatal msg=&#34;Database could not be opened!&#34; error=&#34;unable to open database file: no such file or directory&#34;
</code></pre>

<p>Cause: the host folder mounted as <code>/data</code> either didn&#39;t exist or wasn&#39;t writable by the user <code>1000:1000</code> that Navidrome runs as. Containers aren&#39;t magic: a bind mount is just a folder, and permissions are permissions.</p>

<pre><code class="language-bash">mkdir -p ~/docker/navidrome ~/media/music
sudo chown -R 1000:1000 ~/docker/navidrome ~/media/music
docker compose up -d
</code></pre>

<p>From then on, Navidrome stopped crying.</p>

<p>Side note for anyone finding themselves in the same mess: with Compose v2 the container name is prefixed by the project folder (<code>lorenzo-navidrome-1</code>, not <code>navidrome</code>), so <code>docker logs navidrome</code> answers with <code>No such container</code>. Either you use the full name, or <code>docker compose logs navidrome</code>.</p>

<h3 id="gerbera-s-dancing-port">Gerbera&#39;s dancing port</h3>

<p>At first launch, Gerbera&#39;s web UI had ended up on a semi-random port (49494). It looked stable, but I didn&#39;t want to play “guess the port” at every reinstall — and given how the previous night had gone, reinstalls weren&#39;t an unlikely event. I changed the port in the config with <code>sed</code> and pinned it there forever. An observation, not documented certainty: I ran into this behavior at first launch, and that alone was enough to convince me to write the port into the config by hand.</p>

<p>Same family of problem, different father: <code>nano</code> reported <code>config.xml</code> as unwritable. The file had been created by the process inside the container, which runs as root:</p>

<pre><code class="language-bash">sudo chown -R 1000:1000 ~/docker/gerbera
</code></pre>

<p>Gerbera doesn&#39;t even have a default icon in the Heimdall library, so I added the tile by hand. Small things, but they&#39;re what makes the difference between “unattended” and “let&#39;s go check”.</p>

<h3 id="the-bash-bug-in-the-sync-script">The bash bug in the sync script</h3>

<p>The highlight. The <code>sync_music.sh</code> script got stuck with a cryptic error:</p>

<pre><code class="language-text">Empty source arg specified.
rsync error: syntax or usage error (code 1) at main.c(1526) [sender=3.2.7]
</code></pre>

<p>Culprit: an empty <code>&#34;$DRY_RUN&#34;</code> variable, passing an empty string to <code>rsync</code> as an argument — and rsync interpreted it as a missing source. Fix: turn it into an array, which expands to zero arguments when empty, as God intended.</p>

<pre><code class="language-bash">DRY_RUN=()
[[ &#34;${1:-}&#34; == &#34;-n&#34; ]] &amp;&amp; DRY_RUN=(--dry-run)
# ...
rsync &#34;${RSYNC_OPTS[@]}&#34; &#34;${DRY_RUN[@]}&#34; &#34;$SRC&#34; ...
</code></pre>

<p>Second round, right after:</p>

<pre><code class="language-text">./sync_music.sh: line 47: DRY_RUN: unbound variable
</code></pre>

<p>With <code>set -u</code> active, the test <code>[[ -n &#34;$DRY_RUN&#34; ]]</code> uses the scalar form of the array which, when empty, counts as unbound. The length had to be tested instead:</p>

<pre><code class="language-bash">[[ ${#DRY_RUN[@]} -gt 0 ]]
</code></pre>

<p>Bash has a sneaky type system. I applied the same two corrected lines with <code>sed</code>, because at that hour of the night rewriting by hand was asking too much.</p>

<h3 id="pink-floid-and-the-ghost-album">“Pink Floid” and the ghost album</h3>

<p>During the sync I discovered that a folder christened “Pink Floid” — original typo, years of honorable service — lives on two machines and only got fixed on one. And the ghost album: “The Division Bell” exists only on the server.</p>

<p>Neither is a bug. It&#39;s the logical consequence of an <code>rsync</code> without <code>--delete</code>: it copies new files but never deletes anything, so it&#39;s not a mirror. In the final version of the script <code>--delete</code> is there, but that night it wasn&#39;t — and the ghost “Be Here Now” is living proof. Double moral: if you want a true mirror, tell rsync so; and for music, ID3 tags are what count, not folder names.</p>

<h3 id="the-false-errors">The false errors</h3>

<p>Bonus of the evening, the errors that weren&#39;t errors:</p>
<ul><li>Navidrome answered <code>HTTP 302</code>: a redirect to the login page, which is the correct response from <code>curl</code> without a session.</li>
<li><code>docker ps</code> showed no ports for Gerbera: normal with <code>network_mode: host</code>, the container uses the machine&#39;s interfaces directly.</li>
<li>A <code>WARN</code> about the obsolete <code>version:</code> line in the compose file: just a warning, modern compose files don&#39;t need it anymore.</li></ul>

<p>Learning to tell a real error from an apparent one is half the craft.</p>

<h2 id="the-moment-of-glory">The moment of glory</h2>

<p>Final test: full server reboot. A simulated blackout, so to speak. Ritual-grade checklist with <code>docker ps</code> and <code>curl</code>:</p>
<ul><li>Navidrome: <code>Up</code>, HTTP 302 (redirect to login, all in order).</li>
<li>Heimdall: <code>Up</code>, HTTP 200.</li>
<li>Gerbera: <code>Up</code>, HTTP 200.</li></ul>

<p>Three containers up, three healthy responses. Fully unattended: blackouts, reboots, updates — after the night of the BIOS, I&#39;ve earned this minimum of dignity.</p>

<p>At one in the morning I was in bed with The Wall in my headphones, via WiiM, without the laptop ever having been switched on. The €50 Celeron had earned it.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/901608309406204096/0e0206425-c6ee71/5kRvI38m7X8F/3LII7KV4AeFn9FOmXoiOFTS8PielizsSvPrvjWim.jpg" alt="From CD to my ears"></p>

<h2 id="reflections-on-working-with-the-ai">Reflections on working with the AI</h2>

<p>The evening was an experiment in <em>pair-sysadmining</em>: the AI proposed, I executed, the terminal arbitrated. When the AI suggested a wrong package name, the terminal exposed it in a second. The AI&#39;s mistakes aren&#39;t a problem if the feedback loop is tight.</p>

<p>There&#39;s a difference between a tutorial and a real session: the tutorial shows the ideal path, the real session is an obstacle course. Both teach you something, but only the second one teaches you how to <em>diagnose</em>. And diagnosing — asking yourself “does it change across reboots?”, telling a 302 from a 500, understanding why an empty variable explodes — is the part that stays with you.</p>

<p>Good music, and goodnight from here too.</p>

<hr>

<p><em>Transparency note: the AI in the “pair-sysadmining” told above is called <a href="https://lumo.proton.me" rel="nofollow">Lumo</a>, and it&#39;s Proton&#39;s assistant — the same folks behind encrypted email. I&#39;m liking it: besides giving me wrong suggestions about package names (and taking them bounced back from the terminal with good sportsmanship), it has a newly released canvas feature that turned writing this post into a side-by-side job — notes, drafts, and live revisions, while the music kept playing from the containers. If you want to try it, here&#39;s my <a href="https://pr.tn/ref/31BCQE3B" rel="nofollow">referral link</a>, and if you made it all the way down here reading, you also deserve the 10-euro discount that comes with my link.</em></p>

<h2 id="docker-compose-yml">docker-compose.yml</h2>

<pre><code class="language-yaml">services:
  navidrome:
    image: deluan/navidrome:latest
    user: 1000:1000
    ports:
      - &#34;4533:4533&#34;
    volumes:
      - /home/lorenzo/media/music:/music
      - /home/lorenzo/docker/navidrome:/data
    environment:
      - ND_LOGLEVEL=info
      - ND_SCANSCHEDULE=1h
      - ND_SESSIONTIMEOUT=168h
    restart: unless-stopped

  heimdall:
    image: linuxserver/heimdall
    ports:
      - &#34;8080:80&#34;
    volumes:
      - /home/lorenzo/docker/heimdall:/config
    restart: unless-stopped

  gerbera:
    image: gerbera/gerbera
    container_name: gerbera
    network_mode: host
    volumes:
      - /home/lorenzo/media/music:/content:ro
      - /home/lorenzo/docker/gerbera/config:/var/run/gerbera
    restart: unless-stopped
</code></pre>

<h2 id="sync-music-sh">sync_music.sh</h2>

<pre><code class="language-bash">#!/bin/bash
# sync_music.sh — Sync music from Tuxedo to Minimonio (one-way, rsync via SSH)
# Usage: ./sync_music.sh [-n]
#   -n : dry-run (shows what it would do without copying anything)

set -euo pipefail

# ---------- CONFIGURATION ----------
SRC=&#34;/home/lorenzo/Musica/&#34;          # Source folder on Tuxedo (NOTE the trailing slash!)
DST_USER=&#34;lorenzo&#34;
DST_HOST=&#34;192.168.1.201&#34;             # minimonio&#39;s IP
DST_PATH=&#34;media/music/&#34;              # Destination, relative to home on minimonio
LOG_DIR=&#34;$HOME/logs&#34;
LOG_FILE=&#34;$LOG_DIR/sync_music_$(date +%Y%m%d_%H%M%S).log&#34;
KEEP_LOGS=10                          # Number of old logs to keep
LOCKFILE=&#34;/tmp/sync_music.lock&#34;
# ------------------------------------

DRY_RUN=()
[[ &#34;${1:-}&#34; == &#34;-n&#34; ]] &amp;&amp; DRY_RUN=(--dry-run)

# --- Duplicate-run protection ---
if [[ -f &#34;$LOCKFILE&#34; ]] &amp;&amp; kill -0 &#34;$(cat &#34;$LOCKFILE&#34;)&#34; 2&gt;/dev/null; then
    echo &#34;❌ Another sync is already running (PID $(cat &#34;$LOCKFILE&#34;)). Exiting.&#34;
    exit 1
fi
echo $$ &gt; &#34;$LOCKFILE&#34;
trap &#39;rm -f &#34;$LOCKFILE&#34;&#39; EXIT

mkdir -p &#34;$LOG_DIR&#34;

# --- Source check ---
if [[ ! -d &#34;$SRC&#34; ]]; then
    echo &#34;❌ Source folder $SRC not found. Edit SRC in the script.&#34;
    exit 1
fi

MP3_COUNT=$(find &#34;$SRC&#34; -type f \( -iname &#39;*.mp3&#39; -o -iname &#39;*.flac&#39; -o -iname &#39;*.m4a&#39; \) | wc -l)
if [[ &#34;$MP3_COUNT&#34; -eq 0 ]]; then
    echo &#34;⚠️  No music files found in $SRC — checking before continuing.&#34;
    read -rp &#34;Proceed anyway? [y/N] &#34; ans
    [[ &#34;$ans&#34; == &#34;y&#34; ]] || exit 0
fi

echo &#34;🎵 Music sync: $SRC -&gt; $DST_USER@$DST_HOST:$DST_PATH&#34;
echo &#34;   Music files in source: $MP3_COUNT&#34;
[[ ${#DRY_RUN[@]} -gt 0 ]] &amp;&amp; echo &#34;   (DRY-RUN: no files will actually be copied)&#34;
echo &#34;&#34;

# --- Reachability ---
if ! ping -c1 -W2 &#34;$DST_HOST&#34; &gt; /dev/null 2&gt;&amp;1; then
    echo &#34;❌ $DST_HOST unreachable. Check the network.&#34;
    exit 1
fi

# --- Synchronization ---
#  -a  preserves permissions, dates, structure
#  -v  verbose
#  -h  human-readable sizes
#  --delete  deletes on destination what was removed from source (true mirror)
#  --info=progress2  overall progress bar
#  --exclude  skips temporary and hidden files
RSYNC_OPTS=(-avh --info=progress2 --stats
            --exclude=&#39;.*&#39; --exclude=&#39;Thumbs.db&#39; --exclude=&#39;desktop.ini&#39;
            --exclude=&#39;*.tmp&#39;)

echo &#34;   Note: mirroring ACTIVE (--delete). Comment it out to keep removed files.&#34;
echo &#34;&#34;

rsync &#34;${RSYNC_OPTS[@]}&#34; &#34;${DRY_RUN[@]}&#34; &#34;$SRC&#34; &#34;$DST_USER@$DST_HOST:$DST_PATH&#34; 2&gt;&amp;1 | tee &#34;$LOG_FILE&#34;

# --- Old log cleanup ---
ls -1t &#34;$LOG_DIR&#34;/sync_music_*.log 2&gt;/dev/null | tail -n +&#34;$((KEEP_LOGS + 1))&#34; | xargs -r rm --

echo &#34;&#34;
echo &#34;✅ Sync completed. Log: $LOG_FILE&#34;

# --- Tip ---
if [[ ${#DRY_RUN[@]} -eq 0 ]]; then
    echo &#34;ℹ️  Navidrome re-scans the library within 1 hour (ND_SCANSCHEDULE=1h).&#34;
    echo &#34;   To force the scan now: open http://$DST_HOST:4533 and go to ⚙ → Scan Library.&#34;
fi
</code></pre>

<hr>

<blockquote><p><em>“Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.”</em></p></blockquote>

<p>👤 <strong>Lorenzo</strong> | <em>ItsMeLarry</em>
🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels
🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First
📍 <em>Tuscany / Digital</em></p>

<p>🔗 <a href="https://noblogo.org/itsmelarry-en" rel="nofollow">noblogo.org/itsmelarry-en</a> | 🐙 <a href="https://github.com/itsmelarrybox" rel="nofollow">GitHub</a></p>
]]></content:encoded>
      <guid>https://noblogo.org/itsmelarry-en/from-a-eu50-used-pc-with-a-rebellious-bios-to-a-media-center-in-one-evening</guid>
      <pubDate>Sat, 24 Oct 2026 12:41:37 +0000</pubDate>
    </item>
    <item>
      <title>The Day My House Lit Up an AI Datacenter Under My Desk</title>
      <link>https://noblogo.org/itsmelarry-en/the-day-my-house-lit-up-an-ai-datacenter-under-my-desk</link>
      <description>&lt;![CDATA[A ship&#39;s log from the home lab, between mini PCs, laptops, and LLMs talking to each other to ask what the weather is like in my backyard.&#xA;&#xA;There are projects born out of necessity and projects born out of curiosity. This one was born from both, with a pinch of wanting to have fun while pushing a few limits.&#xA;&#xA;Disclaimer&#xA;&#xA;I am not a developer, nor a sysadmin. Everything you will read on this blog, I did by asking the AI how to proceed, managing feedback and work with the help of models — in particular Lumo by Proton, which I appreciate because it&#39;s an assistant that works very well, costs little, and above all minds its own business. Which, unfortunately, is rare in the digital industry.&#xA;&#xA;Today I can say the first brick is laid. It&#39;s not elegant, but it holds.&#xA;&#xA;How the network is made&#xA;&#xA;The underlying idea is simple: four machines, individually nothing special, but networked together they become something more interesting than their simple sum.&#xA;&#xA;Geekmonio is the brain. A mini PC with an Intel Core Ultra 9, integrated Arc GPU, and 32 GB of RAM. It&#39;s not a datacenter monster, but it has one precious feature: a dedicated NPU and a GPU that, with the right drivers, lends itself to inference acceleration. It hosts Ollama and the web interface, and it&#39;s where the heavy lifting happens. I installed Ubuntu Server without a graphical interface to keep RAM consumption to a minimum.&#xA;&#xA;Tuxedo is my laptop with TuxedoOS (Ubuntu-based), the workbench. An AMD Ryzen 7 with Radeon 780M, running VS Code. Local models via Ollama and LM Studio, but most importantly it queries Geekmonio over the LAN as if it were a cloud service. Light editor, remote brain.&#xA;&#xA;Thinkmonio and Minimonio are the worker arms. More modest machines, bought used on Subito.it for 50 euros each, destined for different tasks: collecting data, acting as a bridge to sensors, hosting lightweight agents that don&#39;t require local inference. They will be the nodes that, in the not-too-distant future, will do &#34;things&#34; — measure, record, react — on which to build the agents orchestrated by Geekmonio&#39;s models.&#xA;&#xA;Home datacenter&#xA;&#xA;What actually runs on it&#xA;&#xA;Three models, chosen with care after several attempts and a few dead ends:&#xA;&#xA;Qwen2.5-Coder 7B&#xA;Use: programming and autocompletion&#xA;Why: precise on code, fast enough to suggest while you write&#xA;&#xA;Mistral Nemo 12B&#xA;Use: chat and reasoning&#xA;Why: huge context, handles Italian well&#xA;&#xA;Llama 3.2 3B&#xA;Use: quick tasks&#xA;Why: for things where latency matters more than depth.&#xA;&#xA;All three live on Geekmonio, served via local API. VS Code on Tuxedo reaches them through Continue, the web interface exposes them as a chat, and the smaller nodes query them when needed.&#xA;&#xA;I set up all these configurations with AI assistance, following its instructions. It will be fun to see whether they prove valid or not — this uncertainty is what intrigues me most and pushes me to keep going.&#xA;&#xA;The part that really interests me&#xA;&#xA;The technical setup is secondary. The interesting part is the economic logic behind it.&#xA;&#xA;It would be easier to swipe the card and pay for a &#34;pro&#34; subscription. That&#39;s fine for asking for a tomato pasta recipe. But when you start using AI to actually make things, for what it&#39;s truly revolutionary for, tokens start flowing and remote models — the smart ones, hosted on servers with tons of RAM and NVIDIA chipsets — end up costing a lot, and I mean a lot.&#xA;&#xA;There is no will to make them accessible on the market&#39;s part. The AI industry, led by 4-5 companies, in its pursuit of AGI is pushing toward a monopoly situation where citizens&#39; AI experience will always be mediated by the need for a technological intermediary, with all the ensuing economic, social, and political consequences. The rising price of consumer RAM is just one piece of a worrying puzzle.&#xA;&#xA;My idea is to have an AI I fully control:&#xA;&#xA;Online assistants like Lumo (I&#39;m eagerly awaiting the APIs) and Leo AI (with no privacy policy) for support: clear policies, great for writing configuration scripts or summarizing complex logs&#xA;Local models for reasoning, code production, and orchestration&#xA;Paid remote models (like Mistral AI) when all of this isn&#39;t enough&#xA;&#xA;Choosing what to use, where, and when, while keeping control over data privacy: that&#39;s what I want to find out is possible.&#xA;&#xA;That&#39;s what the local network is for: absorbing low-value tasks. Repetitive work, small reasoning, drafts, routine questions. Everything that doesn&#39;t deserve a frontier model&#39;s attention gets handled at home, for free, offline, without burning credits.&#xA;&#xA;Remote models thus become what they should be: a scarce resource to use when it really counts. Difficult decisions, new problems, things that require true intelligence.&#xA;&#xA;What&#39;s still missing&#xA;&#xA;I&#39;d be dishonest if I said everything is fine. Autocompletion is sometimes slow, configuring Continue gave me more trouble than expected (in the end I had Copilot solve it), and the integrated GPU has limits you can feel when the context grows long.&#xA;&#xA;But the structure is there. The pieces communicate. The system holds. Performance needs polishing, and that can only be done by using it.&#xA;&#xA;Where this all leads&#xA;&#xA;The final goal is not to have a chatbot at home. It&#39;s to build an infrastructure that knows how to route the work: trivial tasks locally, important ones remotely, autonomous agents for the things nobody wants to do by hand.&#xA;&#xA;It&#39;s an experiment, in the most honest sense of the term. I don&#39;t yet know if it will work the way I imagine. But the first step is taken, and this time the terminal didn&#39;t throw errors back at me.&#xA;&#xA;Next chapter&#xA;&#xA;Building a software factory that produces the software agents I need. I want to be able to build myself the infrastructure I&#39;ll use at home, so the next chapter will be creating a first agent to install on Thinkmonio.&#xA;&#xA;---&#xD;&#xA;  &#34;Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.&#34;&#xD;&#xA;&#xD;&#xA;👤 Lorenzo | ItsMeLarry&#xD;&#xA;🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels&#xD;&#xA;🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First&#xD;&#xA;📍 Tuscany / Digital&#xD;&#xA;&#xD;&#xA;🔗 noblogo.org/itsmelarry-en | 🐙 GitHub]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="a-ship-s-log-from-the-home-lab-between-mini-pcs-laptops-and-llms-talking-to-each-other-to-ask-what-the-weather-is-like-in-my-backyard">A ship&#39;s log from the home lab, between mini PCs, laptops, and LLMs talking to each other to ask what the weather is like in my backyard.</h2>

<p>There are projects born out of necessity and projects born out of curiosity. This one was born from both, with a pinch of wanting to have fun while pushing a few limits.</p>

<p><strong>Disclaimer</strong></p>

<p><em>I am not a developer, nor a sysadmin. Everything you will read on this blog, I did by asking the AI how to proceed, managing feedback and work with the help of models — in particular Lumo by Proton, which I appreciate because it&#39;s an assistant that works very well, costs little, and above all minds its own business. Which, unfortunately, is rare in the digital industry.</em></p>

<p>Today I can say the first brick is laid. It&#39;s not elegant, but it holds.</p>

<h2 id="how-the-network-is-made">How the network is made</h2>

<p>The underlying idea is simple: four machines, individually nothing special, but networked together they become something more interesting than their simple sum.</p>

<p><strong>Geekmonio</strong> is the brain. A mini PC with an Intel Core Ultra 9, integrated Arc GPU, and 32 GB of RAM. It&#39;s not a datacenter monster, but it has one precious feature: a dedicated NPU and a GPU that, with the right drivers, lends itself to inference acceleration. It hosts Ollama and the web interface, and it&#39;s where the heavy lifting happens. I installed Ubuntu Server without a graphical interface to keep RAM consumption to a minimum.</p>

<p><strong>Tuxedo</strong> is my laptop with TuxedoOS (Ubuntu-based), the workbench. An AMD Ryzen 7 with Radeon 780M, running VS Code. Local models via Ollama and LM Studio, but most importantly it queries Geekmonio over the LAN as if it were a cloud service. Light editor, remote brain.</p>

<p><strong>Thinkmonio</strong> and <strong>Minimonio</strong> are the worker arms. More modest machines, bought used on Subito.it for 50 euros each, destined for different tasks: collecting data, acting as a bridge to sensors, hosting lightweight agents that don&#39;t require local inference. They will be the nodes that, in the not-too-distant future, will do “things” — measure, record, react — on which to build the agents orchestrated by Geekmonio&#39;s models.</p>

<p><img src="https://pixelfed.uno/storage/m/_v2/901608309406204096/0e0206425-c6ee71/a5I9a3FpCyLh/YFZyhhbeQ1NvqfkyH5NYkkPpOhADavWH403jlFBI.jpg" alt="Home datacenter"></p>

<h2 id="what-actually-runs-on-it">What actually runs on it</h2>

<p>Three models, chosen with care after several attempts and a few dead ends:</p>

<p><strong>Qwen2.5-Coder 7B</strong>
Use: programming and autocompletion
Why: precise on code, fast enough to suggest while you write</p>

<p><strong>Mistral Nemo 12B</strong>
Use: chat and reasoning
Why: huge context, handles Italian well</p>

<p><strong>Llama 3.2 3B</strong>
Use: quick tasks
Why: for things where latency matters more than depth.</p>

<p>All three live on Geekmonio, served via local API. VS Code on Tuxedo reaches them through Continue, the web interface exposes them as a chat, and the smaller nodes query them when needed.</p>

<p>I set up all these configurations with AI assistance, following its instructions. It will be fun to see whether they prove valid or not — this uncertainty is what intrigues me most and pushes me to keep going.</p>

<h2 id="the-part-that-really-interests-me">The part that really interests me</h2>

<p>The technical setup is secondary. The interesting part is the economic logic behind it.</p>

<p>It would be easier to swipe the card and pay for a “pro” subscription. That&#39;s fine for asking for a tomato pasta recipe. But when you start using AI to actually make things, for what it&#39;s truly revolutionary for, tokens start flowing and remote models — the smart ones, hosted on servers with tons of RAM and NVIDIA chipsets — end up costing a lot, and I mean a lot.</p>

<p>There is no will to make them accessible on the market&#39;s part. The AI industry, led by 4-5 companies, in its pursuit of AGI is pushing toward a monopoly situation where citizens&#39; AI experience will always be mediated by the need for a technological intermediary, with all the ensuing economic, social, and political consequences. The rising price of consumer RAM is just one piece of a worrying puzzle.</p>

<p>My idea is to have an AI I fully control:</p>
<ul><li>Online assistants like Lumo (I&#39;m eagerly awaiting the APIs) and Leo AI (with no privacy policy) for support: clear policies, great for writing configuration scripts or summarizing complex logs</li>
<li>Local models for reasoning, code production, and orchestration</li>
<li>Paid remote models (like Mistral AI) when all of this isn&#39;t enough</li></ul>

<p><strong>Choosing what to use, where, and when, while keeping control over data privacy: that&#39;s what I want to find out is possible.</strong></p>

<p>That&#39;s what the local network is for: absorbing low-value tasks. Repetitive work, small reasoning, drafts, routine questions. Everything that doesn&#39;t deserve a frontier model&#39;s attention gets handled at home, for free, offline, without burning credits.</p>

<p>Remote models thus become what they should be: a scarce resource to use when it really counts. Difficult decisions, new problems, things that require true intelligence.</p>

<h2 id="what-s-still-missing">What&#39;s still missing</h2>

<p>I&#39;d be dishonest if I said everything is fine. Autocompletion is sometimes slow, configuring Continue gave me more trouble than expected (in the end I had Copilot solve it), and the integrated GPU has limits you can feel when the context grows long.</p>

<p>But the structure is there. The pieces communicate. The system holds. Performance needs polishing, and that can only be done by using it.</p>

<h2 id="where-this-all-leads">Where this all leads</h2>

<p>The final goal is not to have a chatbot at home. It&#39;s to build an infrastructure that knows how to route the work: trivial tasks locally, important ones remotely, autonomous agents for the things nobody wants to do by hand.</p>

<p>It&#39;s an experiment, in the most honest sense of the term. I don&#39;t yet know if it will work the way I imagine. But the first step is taken, and this time the terminal didn&#39;t throw errors back at me.</p>

<h2 id="next-chapter">Next chapter</h2>

<p>Building a software factory that produces the software agents I need. I want to be able to build myself the infrastructure I&#39;ll use at home, so the next chapter will be creating a first agent to install on Thinkmonio.</p>

<hr>

<blockquote><p><em>“Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.”</em></p></blockquote>

<p>👤 <strong>Lorenzo</strong> | <em>ItsMeLarry</em>
🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels
🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First
📍 <em>Tuscany / Digital</em></p>

<p>🔗 <a href="https://noblogo.org/itsmelarry-en" rel="nofollow">noblogo.org/itsmelarry-en</a> | 🐙 <a href="https://github.com/itsmelarrybox" rel="nofollow">GitHub</a></p>
]]></content:encoded>
      <guid>https://noblogo.org/itsmelarry-en/the-day-my-house-lit-up-an-ai-datacenter-under-my-desk</guid>
      <pubDate>Sat, 24 Oct 2026 12:33:53 +0000</pubDate>
    </item>
    <item>
      <title>From the Backyard to the Neural Network: How I Built an AI Weather Assistant with Home Hardware</title>
      <link>https://noblogo.org/itsmelarry-en/from-the-backyard-to-the-neural-network-how-i-built-an-ai-weather-assistant</link>
      <description>&lt;![CDATA[I always thought Artificial Intelligence was something far away, hosted in huge data centers, accessible only through the cloud and expensive subscriptions. But what would happen if we could bring it home? If we could turn old computers into a network of intelligent &#34;agents&#34; that work together, in total privacy and without depending on external servers?&#xA;&#xA;This is not a technical tutorial for engineers. It is the chronicle of a practical experiment: how I turned three old PCs into an intelligent weather and lifestyle system, capable of analyzing my garden and telling me when to exercise, when to rest, and when to enjoy an aperitivo.&#xA;&#xA;And the most surprising part? I didn&#39;t write a single line of code.&#xA;&#xA;The Idea: A Proof of Concept for the Future&#xA;&#xA;The goal was clear: to create a Proof of Concept (PoC) of a decentralized architecture. I wanted to demonstrate that it is possible to:&#xA;&#xA;Reuse existing hardware: Turn mini-PCs and old desktops into nodes of an intelligent network.&#xA;Leverage AI as a co-pilot: Use artificial intelligence to write the code, solve errors, and manage the technical complexity.&#xA;Maintain data sovereignty: Run everything locally, without sending sensitive information to third parties.&#xA;&#xA;The result is a system that collects data from a real weather station, processes it with a local language model (Ollama), and returns contextualized advice about my specific garden.&#xA;&#xA;The Architecture: Three Nodes, One Brain&#xA;&#xA;I selected three very different devices to test the resilience of the system:&#xA;&#xA;Minimonio: A cheap mini-PC (Intel Celeron, 7GB RAM). The &#34;sensor&#34; node, lightweight and low-power.&#xA;Thinkmonio: A small desktop (Intel i3, 15GB RAM). The main &#34;agent&#34; node, responsible for the web interface and orchestration.&#xA;Tuxedo: A powerful laptop (AMD Ryzen, 31GB RAM). The &#34;brain&#34; node, where the local AI model runs.&#xA;&#xA;Each node runs Docker, ensuring the software is isolated and portable. It doesn&#39;t matter how old or new the hardware is: the container works the same way everywhere.&#xA;&#xA;The Process: Iteration and Adaptation&#xA;&#xA;The path was not linear. It was a continuous cycle of &#34;try, fail, fix&#34;, guided by dialogue with the AI.&#xA;&#xA;Phase 1: Infrastructure Stabilization&#xA;&#xA;The first obstacle was getting the base nodes to work. Minimonio would shut itself down to save power. The solution? Disable the kernel suspend settings and force the CPU to run in performance mode. A seemingly trivial problem that would have blocked the entire system.&#xA;&#xA;Phase 2: Communication Between Nodes&#xA;&#xA;Once stable, I had to make them talk to each other. I created a simple REST API (using FastAPI) that allows thinkmonio to query minimonio for its system metrics. The result? A web dashboard showing the health status of both computers in real time.&#xA;&#xA;Phase 3: Weather Data Integration&#xA;&#xA;Here the &#34;real&#34; part comes into play. I connected my Raddy WF-100C weather station (which publishes to Weather Underground) to the system. Thinkmonio now downloads current data (temperature, humidity, wind) and forecasts from the Open-Meteo APIs.&#xA;&#xA;Phase 4: Local Intelligence (Ollama)&#xA;&#xA;The decisive step was adding the &#34;brain&#34;. Instead of using cloud services like Groq or ChatGPT, I installed Ollama on tuxedo with the llama3.2 model. I created a structured prompt that provides the AI with:&#xA;&#xA;Current weather data.&#xA;A detailed map of my garden (Zones A-E, with specific features like the turtle Camilla&#39;s terrarium).&#xA;The task: &#34;Analyze the data and give me practical advice on activities, zoning, and timing.&#34;&#xA;&#xA;The system now responds with personalized advice: &#34;Avoid the lawn (Zone B) due to high humidity, but Zone A is perfect for morning exercise.&#34;&#xA;&#xA;DIY Weather&#xA;&#xA;The Ethical Choice: Privacy by Design&#xA;&#xA;There is a fundamental detail that is often overlooked in these experiments: where is my data processed?&#xA;&#xA;I was handling information about my home, my GPS position, and family habits. I couldn&#39;t allow this data to end up in the training datasets of big corporations. For this reason, I chose to use Lumo (by Proton) to design the architecture and Ollama for local execution.&#xA;&#xA;Lumo: It allowed me to discuss the project and generate the code in an end-to-end encrypted environment. No one, not even Proton, can read my conversations.&#xA;Ollama: Runs the AI model directly on my hardware. The weather data and the garden description never leave my home network.&#xA;&#xA;Building a decentralized system requires tools that respect data sovereignty from the very first step.&#xA;&#xA;Try it and start your journey of discovery: https://pr.tn/ref/31BCQE3B&#xA;&#xA;The Result: A Garden That Talks&#xA;&#xA;Today, opening the dashboard in my browser, I see not just numbers, but contextual advice. I click a button and the AI tells me:&#xA;&#xA;Situation: &#34;It&#39;s an ideal day for outdoor activities, but avoid the lawn because of the humidity.&#34;&#xA;Recommended Activities: Zone A (Parking), Zone D (Pool), Zone E (Barbecue).&#xA;Assessment: A score from 1 to 10 for each zone and activity (exercise, nap, aperitivo).&#xA;&#xA;It&#39;s not magic. It is the result of an iterative process, solved errors, reused hardware, and a conscious choice for privacy.&#xA;&#xA;Conclusion: The Beginning of Something Bigger&#xA;&#xA;This experiment demonstrates that the AI of the future won&#39;t live only in centralized clouds. It will be distributed, everywhere, on our own devices.&#xA;&#xA;Resilience: If one node falls, the others keep working.&#xA;Efficiency: We use existing resources instead of buying new ones.&#xA;Accessibility: Anyone with a bit of curiosity and an old PC can start building their own intelligent infrastructure.&#xA;&#xA;Technology is not magic. It is a process of attempts, errors, and adaptations. And sometimes, an old mini-PC and a bit of patience are enough to create something extraordinary.&#xA;&#xA;If you want to try to replicate this experiment or have questions about the process, write to me on Mastodon https://mastodon.uno/@itsmelarry&#xA;&#xA;The road is long, but what matters is moving forward — even sitting down!&#xA;&#xA;---&#xD;&#xA;  &#34;Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.&#34;&#xD;&#xA;&#xD;&#xA;👤 Lorenzo | ItsMeLarry&#xD;&#xA;🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels&#xD;&#xA;🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First&#xD;&#xA;📍 Tuscany / Digital&#xD;&#xA;&#xD;&#xA;🔗 noblogo.org/itsmelarry-en | 🐙 GitHub]]&gt;</description>
      <content:encoded><![CDATA[<p>I always thought Artificial Intelligence was something far away, hosted in huge data centers, accessible only through the cloud and expensive subscriptions. But what would happen if we could bring it home? If we could turn old computers into a network of intelligent “agents” that work together, in total privacy and without depending on external servers?</p>

<p>This is not a technical tutorial for engineers. It is the chronicle of a practical experiment: how I turned three old PCs into an intelligent weather and lifestyle system, capable of analyzing my garden and telling me when to exercise, when to rest, and when to enjoy an aperitivo.</p>

<p>And the most surprising part? I didn&#39;t write a single line of code.</p>

<h2 id="the-idea-a-proof-of-concept-for-the-future">The Idea: A Proof of Concept for the Future</h2>

<p>The goal was clear: to create a Proof of Concept (PoC) of a decentralized architecture. I wanted to demonstrate that it is possible to:</p>

<p>Reuse existing hardware: Turn mini-PCs and old desktops into nodes of an intelligent network.
Leverage AI as a co-pilot: Use artificial intelligence to write the code, solve errors, and manage the technical complexity.
Maintain data sovereignty: Run everything locally, without sending sensitive information to third parties.</p>

<p>The result is a system that collects data from a real weather station, processes it with a local language model (Ollama), and returns contextualized advice about my specific garden.</p>

<h1 id="the-architecture-three-nodes-one-brain">The Architecture: Three Nodes, One Brain</h1>

<p>I selected three very different devices to test the resilience of the system:</p>

<p>Minimonio: A cheap mini-PC (Intel Celeron, 7GB RAM). The “sensor” node, lightweight and low-power.
Thinkmonio: A small desktop (Intel i3, 15GB RAM). The main “agent” node, responsible for the web interface and orchestration.
Tuxedo: A powerful laptop (AMD Ryzen, 31GB RAM). The “brain” node, where the local AI model runs.</p>

<p>Each node runs Docker, ensuring the software is isolated and portable. It doesn&#39;t matter how old or new the hardware is: the container works the same way everywhere.</p>

<h1 id="the-process-iteration-and-adaptation">The Process: Iteration and Adaptation</h1>

<p>The path was not linear. It was a continuous cycle of “try, fail, fix”, guided by dialogue with the AI.</p>

<h2 id="phase-1-infrastructure-stabilization">Phase 1: Infrastructure Stabilization</h2>

<p>The first obstacle was getting the base nodes to work. Minimonio would shut itself down to save power. The solution? Disable the kernel suspend settings and force the CPU to run in performance mode. A seemingly trivial problem that would have blocked the entire system.</p>

<h2 id="phase-2-communication-between-nodes">Phase 2: Communication Between Nodes</h2>

<p>Once stable, I had to make them talk to each other. I created a simple REST API (using FastAPI) that allows thinkmonio to query minimonio for its system metrics. The result? A web dashboard showing the health status of both computers in real time.</p>

<h2 id="phase-3-weather-data-integration">Phase 3: Weather Data Integration</h2>

<p>Here the “real” part comes into play. I connected my Raddy WF-100C weather station (which publishes to Weather Underground) to the system. Thinkmonio now downloads current data (temperature, humidity, wind) and forecasts from the Open-Meteo APIs.</p>

<h2 id="phase-4-local-intelligence-ollama">Phase 4: Local Intelligence (Ollama)</h2>

<p>The decisive step was adding the “brain”. Instead of using cloud services like Groq or ChatGPT, I installed Ollama on tuxedo with the llama3.2 model. I created a structured prompt that provides the AI with:</p>

<p>Current weather data.
A detailed map of my garden (Zones A-E, with specific features like the turtle Camilla&#39;s terrarium).
The task: “Analyze the data and give me practical advice on activities, zoning, and timing.”</p>

<p>The system now responds with personalized advice: “Avoid the lawn (Zone B) due to high humidity, but Zone A is perfect for morning exercise.”</p>

<p><img src="https://cdn.masto.host/mastodonuno/media_attachments/files/117/429/877/776/086/018/original/4ef9d75f9f371d62.png" alt="DIY Weather"></p>

<h2 id="the-ethical-choice-privacy-by-design">The Ethical Choice: Privacy by Design</h2>

<p>There is a fundamental detail that is often overlooked in these experiments: where is my data processed?</p>

<p>I was handling information about my home, my GPS position, and family habits. I couldn&#39;t allow this data to end up in the training datasets of big corporations. For this reason, I chose to use Lumo (by Proton) to design the architecture and Ollama for local execution.</p>

<p>Lumo: It allowed me to discuss the project and generate the code in an end-to-end encrypted environment. No one, not even Proton, can read my conversations.
Ollama: Runs the AI model directly on my hardware. The weather data and the garden description never leave my home network.</p>

<p>Building a decentralized system requires tools that respect data sovereignty from the very first step.</p>

<p>Try it and start your journey of discovery: <a href="https://pr.tn/ref/31BCQE3B" rel="nofollow">https://pr.tn/ref/31BCQE3B</a></p>

<h2 id="the-result-a-garden-that-talks">The Result: A Garden That Talks</h2>

<p>Today, opening the dashboard in my browser, I see not just numbers, but contextual advice. I click a button and the AI tells me:</p>

<p>Situation: “It&#39;s an ideal day for outdoor activities, but avoid the lawn because of the humidity.”
Recommended Activities: Zone A (Parking), Zone D (Pool), Zone E (Barbecue).
Assessment: A score from 1 to 10 for each zone and activity (exercise, nap, aperitivo).</p>

<p>It&#39;s not magic. It is the result of an iterative process, solved errors, reused hardware, and a conscious choice for privacy.</p>

<h1 id="conclusion-the-beginning-of-something-bigger">Conclusion: The Beginning of Something Bigger</h1>

<p>This experiment demonstrates that the AI of the future won&#39;t live only in centralized clouds. It will be distributed, everywhere, on our own devices.</p>

<p>Resilience: If one node falls, the others keep working.
Efficiency: We use existing resources instead of buying new ones.
Accessibility: Anyone with a bit of curiosity and an old PC can start building their own intelligent infrastructure.</p>

<p>Technology is not magic. It is a process of attempts, errors, and adaptations. And sometimes, an old mini-PC and a bit of patience are enough to create something extraordinary.</p>

<p>If you want to try to replicate this experiment or have questions about the process, write to me on Mastodon <a href="https://mastodon.uno/@itsmelarry" rel="nofollow">https://mastodon.uno/@itsmelarry</a></p>

<p>The road is long, but what matters is moving forward — even sitting down!</p>

<hr>

<blockquote><p><em>“Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.”</em></p></blockquote>

<p>👤 <strong>Lorenzo</strong> | <em>ItsMeLarry</em>
🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels
🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First
📍 <em>Tuscany / Digital</em></p>

<p>🔗 <a href="https://noblogo.org/itsmelarry-en" rel="nofollow">noblogo.org/itsmelarry-en</a> | 🐙 <a href="https://github.com/itsmelarrybox" rel="nofollow">GitHub</a></p>
]]></content:encoded>
      <guid>https://noblogo.org/itsmelarry-en/from-the-backyard-to-the-neural-network-how-i-built-an-ai-weather-assistant</guid>
      <pubDate>Sat, 24 Oct 2026 12:25:17 +0000</pubDate>
    </item>
    <item>
      <title>From the Ashes of an Old PC: A Proof of Concept for Understanding AI (Without Being Programmers)</title>
      <link>https://noblogo.org/itsmelarry-en/from-the-ashes-of-an-old-pc-a-proof-of-concept-for-understanding-ai-without</link>
      <description>&lt;![CDATA[We often hear about Artificial Intelligence as an external force, something enormous that arrives from afar and changes the rules of the game. But what happens if we try to bring it home, right here, into our own house? And what if we tried to understand it not by studying theory books, but by building something concrete with our own hands?&#xA;&#xA;This post is not a technical tutorial. It is the chronicle of an experiment. A Proof of Concept born from the simple curiosity of understanding how AI really works when it stops being a &#34;chatbot&#34; and becomes a practical operator.&#xA;&#xA;Why did I do this experiment?&#xA;&#xA;I wanted to understand two fundamental things:&#xA;&#xA;Does hardware still matter? In an era of infinite cloud, can we still do useful things with old computers lying in a drawer?&#xA;Can we &#34;talk&#34; to technology without knowing how to program? If AI is truly the future, it should be accessible to everyone, not just software engineers.&#xA;&#xA;The idea was to turn three heterogeneous devices (two cheap mini-PCs and a laptop) into a network of autonomous agents. I didn&#39;t just want to switch them on — I wanted them to talk to each other, monitor each other, and work together. The ultimate goal is to study how AI can manage physical infrastructure in a decentralized way, without depending on distant centralized servers.&#xA;&#xA;The Method: I think, the AI writes&#xA;&#xA;Here comes the most fascinating part. I am not a programmer. I can&#39;t write Python code, I don&#39;t know Docker by heart, and I don&#39;t know how to configure Linux servers.&#xA;&#xA;All the code you&#39;ll find in this project, all the configurations, the troubleshooting, and the creation of the graphical dashboard were generated by the AI. My role was that of architect and orchestra conductor:&#xA;&#xA;I defined the goal: &#34;I want these PCs to exchange data and show it to me on a web page.&#34;&#xA;I described the problem: &#34;The system crashes, I get this error.&#34;&#xA;The AI translated these requests into working code.&#xA;&#xA;It was an iterative process of trial and error. There were moments of frustration: black screens, containers shutting down on their own, memory errors that seemed insurmountable. But every time, instead of giving up, I used the AI as a technical mentor, asking: &#34;Why did this happen? How do we fix it?&#34; And it answered, explaining the concept behind the error and providing the solution.&#xA;&#xA;This way, I learned to build complex infrastructure without ever manually touching a single line of code. I realized that the value lies not in memorizing syntax, but in knowing what to ask and how to guide the tool.&#xA;&#xA;Agent Dashboard&#xA;&#xA;The Privacy Choice: Why Lumo and Proton&#xA;&#xA;There is a fundamental detail that is often overlooked in these experiments: where does the conversation take place?&#xA;&#xA;I was asking the AI to write code for my home network, to configure servers, and to handle sensitive data. I couldn&#39;t allow this information to end up in the training datasets of big corporations or be read by third parties.&#xA;&#xA;For this reason, I chose to use Lumo, the AI assistant developed by Proton.&#xA;&#xA;Proton is known for its mission to protect digital privacy (with encrypted services like Mail and VPN), and Lumo brings this philosophy into the world of AI.&#xA;&#xA;End-to-End Encryption: Everything we exchange is encrypted. Not even Proton can read my conversations or the code I&#39;m generating.&#xA;No Training on Your Data: My requests, the errors I pasted, and the solutions we found remain private. They are not used to train public models.&#xA;Independence: Building a decentralized system requires tools that respect data sovereignty from the very first step.&#xA;&#xA;Using Lumo allowed me to run this experiment with peace of mind, knowing that my work, my ideas, and my infrastructure were safe. It&#39;s the difference between building a house on rented land or on your own land.&#xA;&#xA;Conclusion: The Beginning of a Journey&#xA;&#xA;This experiment is just the beginning. I demonstrated that it&#39;s possible to create a distributed AI agent network using common hardware and guided by artificial intelligence, without needing traditional programming skills.&#xA;&#xA;But the road is long. The next step will be making these agents not just exchange data, but make autonomous decisions based on what they observe. And I will keep doing it with the same principles: curiosity, experimentation, and above all, respect for privacy.&#xA;&#xA;If you too want to start exploring this world, building your own digital infrastructure in total security, I invite you to try Lumo. It&#39;s a powerful tool that puts the user at the center, not the data.&#xA;&#xA;Try it and start your journey of discovery: https://pr.tn/ref/31BCQE3B&#xA;&#xA;AI is not magic. It&#39;s a tool. And like any tool, its value depends on how we use it and on who builds it alongside us.&#xA;&#xA;Thank you for reading my story.&#xA;&#xA;---&#xD;&#xA;  &#34;Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.&#34;&#xD;&#xA;&#xD;&#xA;👤 Lorenzo | ItsMeLarry&#xD;&#xA;🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels&#xD;&#xA;🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First&#xD;&#xA;📍 Tuscany / Digital&#xD;&#xA;&#xD;&#xA;🔗 noblogo.org/itsmelarry-en | 🐙 GitHub]]&gt;</description>
      <content:encoded><![CDATA[<p>We often hear about Artificial Intelligence as an external force, something enormous that arrives from afar and changes the rules of the game. But what happens if we try to bring it home, right here, into our own house? And what if we tried to understand it not by studying theory books, but by building something concrete with our own hands?</p>

<p>This post is not a technical tutorial. It is the chronicle of an experiment. A Proof of Concept born from the simple curiosity of understanding how AI really works when it stops being a “chatbot” and becomes a practical operator.</p>

<h2 id="why-did-i-do-this-experiment">Why did I do this experiment?</h2>

<p>I wanted to understand two fundamental things:</p>

<p>Does hardware still matter? In an era of infinite cloud, can we still do useful things with old computers lying in a drawer?
Can we “talk” to technology without knowing how to program? If AI is truly the future, it should be accessible to everyone, not just software engineers.</p>

<p>The idea was to turn three heterogeneous devices (two cheap mini-PCs and a laptop) into a network of autonomous agents. I didn&#39;t just want to switch them on — I wanted them to talk to each other, monitor each other, and work together. The ultimate goal is to study how AI can manage physical infrastructure in a decentralized way, without depending on distant centralized servers.</p>

<h2 id="the-method-i-think-the-ai-writes">The Method: I think, the AI writes</h2>

<p>Here comes the most fascinating part. I am not a programmer. I can&#39;t write Python code, I don&#39;t know Docker by heart, and I don&#39;t know how to configure Linux servers.</p>

<p>All the code you&#39;ll find in this project, all the configurations, the troubleshooting, and the creation of the graphical dashboard were generated by the AI. My role was that of architect and orchestra conductor:</p>

<p>I defined the goal: “I want these PCs to exchange data and show it to me on a web page.”
I described the problem: “The system crashes, I get this error.”
The AI translated these requests into working code.</p>

<p>It was an iterative process of trial and error. There were moments of frustration: black screens, containers shutting down on their own, memory errors that seemed insurmountable. But every time, instead of giving up, I used the AI as a technical mentor, asking: “Why did this happen? How do we fix it?” And it answered, explaining the concept behind the error and providing the solution.</p>

<p>This way, I learned to build complex infrastructure without ever manually touching a single line of code. I realized that the value lies not in memorizing syntax, but in knowing what to ask and how to guide the tool.</p>

<p><img src="https://cdn.masto.host/mastodonuno/media_attachments/files/117/424/195/053/335/280/original/d767200d7df1c163.png" alt="Agent Dashboard"></p>

<h2 id="the-privacy-choice-why-lumo-and-proton">The Privacy Choice: Why Lumo and Proton</h2>

<p>There is a fundamental detail that is often overlooked in these experiments: where does the conversation take place?</p>

<p>I was asking the AI to write code for my home network, to configure servers, and to handle sensitive data. I couldn&#39;t allow this information to end up in the training datasets of big corporations or be read by third parties.</p>

<p>For this reason, I chose to use Lumo, the AI assistant developed by Proton.</p>

<p>Proton is known for its mission to protect digital privacy (with encrypted services like Mail and VPN), and Lumo brings this philosophy into the world of AI.</p>

<p><strong>End-to-End Encryption</strong>: Everything we exchange is encrypted. Not even Proton can read my conversations or the code I&#39;m generating.
<strong>No Training on Your Data</strong>: My requests, the errors I pasted, and the solutions we found remain private. They are not used to train public models.
<strong>Independence</strong>: Building a decentralized system requires tools that respect data sovereignty from the very first step.</p>

<p>Using Lumo allowed me to run this experiment with peace of mind, knowing that my work, my ideas, and my infrastructure were safe. It&#39;s the difference between building a house on rented land or on your own land.</p>

<h2 id="conclusion-the-beginning-of-a-journey">Conclusion: The Beginning of a Journey</h2>

<p>This experiment is just the beginning. I demonstrated that it&#39;s possible to create a distributed AI agent network using common hardware and guided by artificial intelligence, without needing traditional programming skills.</p>

<p>But the road is long. The next step will be making these agents not just exchange data, but make autonomous decisions based on what they observe. And I will keep doing it with the same principles: curiosity, experimentation, and above all, respect for privacy.</p>

<p>If you too want to start exploring this world, building your own digital infrastructure in total security, I invite you to try Lumo. It&#39;s a powerful tool that puts the user at the center, not the data.</p>

<p>Try it and start your journey of discovery: <a href="https://pr.tn/ref/31BCQE3B" rel="nofollow">https://pr.tn/ref/31BCQE3B</a></p>

<p>AI is not magic. It&#39;s a tool. And like any tool, its value depends on how we use it and on who builds it alongside us.</p>

<p>Thank you for reading my story.</p>

<hr>

<blockquote><p><em>“Free technology isn&#39;t just code — it&#39;s the freedom to look under the hood.”</em></p></blockquote>

<p>👤 <strong>Lorenzo</strong> | <em>ItsMeLarry</em>
🧪 AI &amp; Open Source Experiments | 🕹️ Retro Gaming &amp; Graphic Novels
🎸 Rock, Folk, Jazz, Punk | 🔒 Privacy First
📍 <em>Tuscany / Digital</em></p>

<p>🔗 <a href="https://noblogo.org/itsmelarry-en" rel="nofollow">noblogo.org/itsmelarry-en</a> | 🐙 <a href="https://github.com/itsmelarrybox" rel="nofollow">GitHub</a></p>
]]></content:encoded>
      <guid>https://noblogo.org/itsmelarry-en/from-the-ashes-of-an-old-pc-a-proof-of-concept-for-understanding-ai-without</guid>
      <pubDate>Sat, 24 Oct 2026 12:22:53 +0000</pubDate>
    </item>
  </channel>
</rss>