<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Artur Rios Lab</title><link>https://artur-rios.github.io/personal-lab/</link><description>Recent content on Artur Rios Lab</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Wed, 21 Oct 2026 21:00:00 +0000</lastBuildDate><atom:link href="https://artur-rios.github.io/personal-lab/index.xml" rel="self" type="application/rss+xml"/><item><title>How to Use PlantUML With Markdown</title><link>https://artur-rios.github.io/personal-lab/tutorials/plantuml-with-markdown/</link><pubDate>Wed, 21 Oct 2026 21:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/tutorials/plantuml-with-markdown/</guid><description>&lt;p&gt;&lt;a href="https://plantuml.com/"&gt;PlantUML&lt;/a&gt; draws diagrams from text. Instead of&#10;dragging boxes around an editor, you write &lt;code&gt;Customer -&amp;gt; Shop: Place order&lt;/code&gt;&#10;and PlantUML lays out the sequence diagram for you. Markdown is where most&#10;documentation lives. Put the two together and the diagram&amp;rsquo;s source sits in&#10;the same file as the text that explains it: it is reviewed in the same pull&#10;request, searched with the same tools, and never drifts away from the&#10;document because someone lost the original drawing.&lt;/p&gt;</description></item><item><title>String Similarity: Levenshtein, Jaro and Jaro–Winkler</title><link>https://artur-rios.github.io/personal-lab/fundamentals/string-similarity/</link><pubDate>Wed, 21 Oct 2026 20:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/string-similarity/</guid><description>&lt;p&gt;Two strings are equal or they are not, and for a computer that is the end of&#10;it: &lt;code&gt;&amp;quot;Smith&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;Smyth&amp;quot;&lt;/code&gt; differ, and so do &lt;code&gt;&amp;quot;recieve&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;receive&amp;quot;&lt;/code&gt;. For&#10;the person who typed them, though, they are almost the same, and a lot of&#10;software has to act on that &amp;ldquo;almost&amp;rdquo;. A spell checker has to find the word&#10;that was meant. A search box has to forgive a typo. A company merging two&#10;customer lists has to notice that &amp;ldquo;Jon Smyth, 12 Main St&amp;rdquo; and &amp;ldquo;John Smith,&#10;12 Main Street&amp;rdquo; are probably the same person. A &lt;strong&gt;string similarity measure&lt;/strong&gt;&#10;puts a number on how close two strings are, so a program can make those calls.&lt;/p&gt;</description></item><item><title>How I Develop APIs</title><link>https://artur-rios.github.io/personal-lab/dotnet/how-i-develop-apis/</link><pubDate>Wed, 21 Oct 2026 19:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/how-i-develop-apis/</guid><description>&lt;p&gt;Every backend I build is an ASP.NET Core API, and they all look alike on&#10;purpose. When the structure is the same everywhere, I never have to remember&#10;where a thing lives, a new feature is a list of files to add rather than a&#10;design decision, and a test that fails points at one small piece of code.&lt;/p&gt;&#10;&lt;p&gt;This page describes that shape, using&#10;&lt;a href="https://artur-rios.github.io/heimdall-api/"&gt;Heimdall&lt;/a&gt; as the example&#10;throughout. Heimdall is my identity management API: people, applications,&#10;logins, two-factor authentication and permissions, for several client systems&#10;at once, each in its own scope. It is the largest API I have, so every pattern&#10;here has been tested against a real use case rather than a toy one. All code&#10;on this page is taken from it, trimmed only where noted.&lt;/p&gt;</description></item><item><title>Common Windows Issues and How I Fix Them</title><link>https://artur-rios.github.io/personal-lab/windows/common-windows-issues/</link><pubDate>Wed, 21 Oct 2026 19:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/windows/common-windows-issues/</guid><description>&lt;p&gt;This page is a reference rather than an article: problems I have hit on&#10;Windows more than once, with the fix written down so I do not have to search&#10;for it again. Each entry says what the problem looks like, what is going on&#10;underneath, and the steps that solve it. The file locations below were checked&#10;on Windows 11 Pro on 21 October 2026.&lt;/p&gt;&#10;&lt;h2 id="blank-or-outdated-icons-rebuilding-the-icon-cache"&gt;Blank or outdated icons: rebuilding the icon cache&lt;a class="heading-anchor" href="#blank-or-outdated-icons-rebuilding-the-icon-cache" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;What it looks like.&lt;/strong&gt; Explorer, the desktop or the taskbar shows a blank&#10;white icon, a generic one, or the old icon of an application that has since&#10;been updated.&lt;/p&gt;</description></item><item><title>The Conventions I Follow</title><link>https://artur-rios.github.io/personal-lab/engineering/my-conventions/</link><pubDate>Wed, 21 Oct 2026 18:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/engineering/my-conventions/</guid><description>&lt;p&gt;A convention is a decision made once. Without them, every new repository,&#10;class and commit reopens the same small questions: what to call it, where to&#10;put it, how to phrase it. None of those questions is hard, but answering them&#10;again every time is slow, and answering them differently every time leaves a&#10;codebase that reads like it was written by several people who never met.&lt;/p&gt;&#10;&lt;p&gt;This page collects the conventions I follow in my own projects. Where a style&#10;guide already covers something, I follow it; the&#10;&lt;a href="https://google.github.io/styleguide/"&gt;Google Style Guides&lt;/a&gt; are my default&#10;reference for the languages they cover. What is written here is either what&#10;those guides leave open, or a choice I have made on top of them.&lt;/p&gt;</description></item><item><title>Deploying With Yggdrasil</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-deploys/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-deploys/</guid><description>&lt;p&gt;&lt;a href="https://github.com/artur-rios/yggdrasil"&gt;Yggdrasil&lt;/a&gt; is the deploy manager I&#10;built for my server. It does one job: take an application from a GitHub&#10;repository to a healthy container in the right environment, and back to the&#10;previous version if the new one does not come up. This part follows a change&#10;from a pull request to production.&lt;/p&gt;&#10;&lt;h2 id="one-catalog"&gt;One catalog&lt;a class="heading-anchor" href="#one-catalog" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Everything yggdrasil knows comes from one file, &lt;code&gt;catalog.yaml&lt;/code&gt;, in three&#10;layers:&lt;/p&gt;</description></item><item><title>Documentation Sites</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-documentation-sites/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-documentation-sites/</guid><description>&lt;p&gt;Every project with users gets a documentation site: what it is, how to install&#10;and use it, and its reference. Heimdall&amp;rsquo;s documentation is one, and so is the&#10;documentation of my .NET libraries. They are all built the same way.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Concern&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Choice&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Generator&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hugo, extended edition&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Theme&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Docsy, as a Hugo module&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GitHub Pages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Deploys&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GitHub Actions&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DNS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cloudflare, optional&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="why-hugo"&gt;Why Hugo&lt;a class="heading-anchor" href="#why-hugo" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Hugo is a single binary that builds thousands of pages in about a second, and&#10;documentation is Markdown in a folder, next to the code it describes, reviewed&#10;in the same pull requests. Docsy is a documentation theme from Google with&#10;navigation, search and versioned sections built in.&lt;/p&gt;</description></item><item><title>How I Host My Projects</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-overview/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-overview/</guid><description>&lt;p&gt;Every project eventually has to run somewhere, and deciding where for each one&#10;separately is how a hobby turns into a pile of accounts, bills and half-&#10;remembered setups. So I decided once, by kind of project, and every new project&#10;inherits the answer. This series describes that setup, as it runs today.&lt;/p&gt;&#10;&lt;h2 id="the-decision-table"&gt;The decision table&lt;a class="heading-anchor" href="#the-decision-table" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;I&amp;rsquo;m building&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Stack&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Hosting&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A marketing or product page&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Next.js with shadcn/ui&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Vercel, behind Cloudflare&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A static portfolio or brochure site&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Astro, or a Next.js static export&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cloudflare Pages or GitHub Pages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Technical documentation&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hugo with the Docsy theme&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GitHub Pages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;An interactive web app&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Flutter, built for the web&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;My server: Docker, Traefik, yggdrasil&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A backend API&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;ASP.NET Core&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;My server: Docker, Traefik, yggdrasil&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;A reusable package&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;NuGet, or the language&amp;rsquo;s own format&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nuget.org and GitHub Packages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="the-rule-behind-it"&gt;The rule behind it&lt;a class="heading-anchor" href="#the-rule-behind-it" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;&lt;strong&gt;Anything with a running backend is self-hosted; everything else is not.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Landing Pages</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-landing-pages/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-landing-pages/</guid><description>&lt;p&gt;A landing page sells something: a hero section, a grid of features, pricing,&#10;a contact or waiting-list form. It has to look polished, load fast everywhere,&#10;and occasionally do something dynamic, such as accept a form. That last part is&#10;why landing pages are not plain &lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-static-sites/"&gt;static sites&lt;/a&gt;.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Concern&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Choice&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Framework&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Next.js, with the App Router&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;UI&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;shadcn/ui and Tailwind CSS&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Vercel, on the free tier&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;DNS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cloudflare&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Deploys&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Vercel&amp;rsquo;s Git integration&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="building-one"&gt;Building one&lt;a class="heading-anchor" href="#building-one" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;div class="code"&gt;&#10; &lt;div class="code__bar"&gt;&#10; &lt;span&gt;bash&lt;/span&gt;&#10; &lt;button class="code__copy" type="button" data-nuno-copy aria-label="Copy code to clipboard"&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx create-next-app@latest my-landing --ts --tailwind --app --eslint&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; my-landing&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx shadcn@latest init&#10;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npx shadcn@latest add button card input navigation-menu&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;p&gt;shadcn/ui is not a component library installed as a dependency: it copies each&#10;component&amp;rsquo;s source into the project, built on Radix and Tailwind, so every&#10;component can be changed like my own code.&lt;/p&gt;</description></item><item><title>Libraries</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-libraries/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-libraries/</guid><description>&lt;p&gt;Code that more than one project needs becomes a package. Mine are .NET&#10;libraries, published as NuGet packages to two places: &lt;strong&gt;nuget.org&lt;/strong&gt;, where&#10;anyone finds them, and &lt;strong&gt;GitHub Packages&lt;/strong&gt;, next to their source.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Concern&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Choice&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Package format&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;NuGet, or the language&amp;rsquo;s own format elsewhere&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Primary feed&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nuget.org&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Secondary feed&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GitHub Packages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Publishing&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;GitHub Actions, on a version tag&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Versioning&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Semantic versioning&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="package-metadata"&gt;Package metadata&lt;a class="heading-anchor" href="#package-metadata" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The project file describes the package, so &lt;code&gt;dotnet pack&lt;/code&gt; produces a complete&#10;&lt;code&gt;.nupkg&lt;/code&gt; with its symbols alongside:&lt;/p&gt;</description></item><item><title>Sizing the Server</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-sizing/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-sizing/</guid><description>&lt;p&gt;Before an application goes on &lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-server/"&gt;the server&lt;/a&gt;,&#10;it should be clear that it fits. This is the model I size the server with: one&#10;figure per service for what it needs, a formula that adds headroom, and the&#10;signals that say the model has stopped being true.&lt;/p&gt;&#10;&lt;p&gt;The figures are &lt;strong&gt;starting estimates&lt;/strong&gt; for a small production load, a few&#10;requests a second on each API, not measurements. After a week of real traffic,&#10;Grafana&amp;rsquo;s numbers replace them.&lt;/p&gt;</description></item><item><title>Static Sites</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-static-sites/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-static-sites/</guid><description>&lt;p&gt;A static site is rendered to HTML, CSS and JavaScript when it is built, and&#10;served as files from then on: portfolios, brochure sites, event pages and small&#10;blogs. With no code running on a server, it can be hosted for free on a CDN and&#10;will never go down for want of a patch.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Concern&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Choice&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Generator&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Astro for content-first sites, or Next.js with a static export&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Styling&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Tailwind CSS&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hosting&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Cloudflare Pages, or GitHub Pages&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Deploys&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The host&amp;rsquo;s Git integration, or GitHub Actions&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;Its neighbours in this series draw the line: a page that needs a form or a&#10;server function is a &lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-landing-pages/"&gt;landing page&lt;/a&gt;,&#10;on Vercel, and reference documentation is a&#10;&lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-documentation-sites/"&gt;documentation site&lt;/a&gt;,&#10;in Hugo.&lt;/p&gt;</description></item><item><title>The Platform: Traefik, Monitoring and the Console</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-platform/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-platform/</guid><description>&lt;p&gt;On top of &lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-server/"&gt;the server&lt;/a&gt; runs one&#10;Compose project, &lt;code&gt;yggdrasil&lt;/code&gt;, that every application shares: the reverse proxy,&#10;the monitoring, and a status API with its console. It is started once per host,&#10;and serves every environment on that host.&lt;/p&gt;&#10;&lt;div class="code"&gt;&#10; &lt;div class="code__bar"&gt;&#10; &lt;span&gt;bash&lt;/span&gt;&#10; &lt;button class="code__copy" type="button" data-nuno-copy aria-label="Copy code to clipboard"&gt;Copy&lt;/button&gt;&#10; &lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;scripts/platform.sh up&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Component&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Version&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Job&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Traefik&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;v3.6&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Routes every request, terminates TLS&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Docker socket proxies&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;1.13.1&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Give Traefik, Alloy and the status API read-only access to Docker&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Status API&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;.NET 10&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Health, version and deploy time of every application&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Console&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Flutter&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Shows the status API, on the web, Windows and Android&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Prometheus&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;v3.5&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Metrics, kept 30 days&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Loki&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;3.5&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Logs, kept 31 days&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Alloy&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;v1.10&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ships every container&amp;rsquo;s logs to Loki&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Grafana&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;12.1&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Dashboards over Prometheus and Loki&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Jenkins&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;LTS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Deploys, covered in &lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-deploys/"&gt;Deploying With Yggdrasil&lt;/a&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="traefik-and-one-wildcard-certificate"&gt;Traefik and one wildcard certificate&lt;a class="heading-anchor" href="#traefik-and-one-wildcard-certificate" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Traefik is the only container that publishes ports, 80 and 443, and port 80&#10;does nothing but redirect to 443. It watches Docker for containers that opt in&#10;with labels, so a new application is routed the moment it starts, without&#10;touching Traefik&amp;rsquo;s configuration.&lt;/p&gt;</description></item><item><title>The Server</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-server/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-server/</guid><description>&lt;p&gt;Everything self-hosted runs on one machine: the platform, the deploy server,&#10;and every application in three environments. This part covers the machine&#10;itself and what is installed on it directly, outside any container.&lt;/p&gt;&#10;&lt;h2 id="the-machine"&gt;The machine&lt;a class="heading-anchor" href="#the-machine" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Resource&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Spec&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Provider&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hostinger VPS&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;vCPU&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;4 cores&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;RAM&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;16 GB&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Disk&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;200 GB NVMe&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Bandwidth&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;16 TB a month&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;OS&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Ubuntu LTS&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;One machine is a single point of failure, and I accept that knowingly: these&#10;are my own projects, an outage costs me an evening, and one well-understood&#10;server is easier to keep healthy than three. Whether everything fits on it is&#10;the subject of &lt;a href="https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-sizing/"&gt;Sizing the Server&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Web APIs</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-web-apis/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-web-apis/</guid><description>&lt;p&gt;My backends are ASP.NET Core APIs, and every one of them meets the platform the&#10;same way. Heimdall&amp;rsquo;s API is the example throughout; Fortuna&amp;rsquo;s follows the same&#10;shape.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Concern&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Choice&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Framework&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;ASP.NET Core on .NET 10&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Image&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Multi-stage: the SDK to build, the ASP.NET runtime to run&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Database&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;The host&amp;rsquo;s PostgreSQL, one database per environment&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Configuration&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Environment variables, from yggdrasil&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Health&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/healthcheck&lt;/code&gt;, probed by Docker, yggdrasil and the status API&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Metrics&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;OpenTelemetry&amp;rsquo;s Prometheus exporter, on port 9464&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Logs&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Standard output, shipped to Loki&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Checks&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Tests and a Docker build in GitHub Actions&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="the-image"&gt;The image&lt;a class="heading-anchor" href="#the-image" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The Dockerfile has two stages. The first restores and publishes with the .NET&#10;10 SDK, copying the project files before the sources so a source-only change&#10;reuses the cached restore. The second copies the output onto the much smaller&#10;ASP.NET runtime image, and runs it as the image&amp;rsquo;s own non-root user:&lt;/p&gt;</description></item><item><title>Web Apps</title><link>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-web-apps/</link><pubDate>Wed, 21 Oct 2026 17:55:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/infrastructure/infrastructure-web-apps/</guid><description>&lt;p&gt;My interactive front ends are Flutter apps, and on the web they are a set of&#10;static files: HTML, JavaScript and WebAssembly. So the container that runs one&#10;is just a web server, small and stateless. Heimdall&amp;rsquo;s web app is the example.&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Concern&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;Choice&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Framework&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Flutter, built for the web&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Build stage&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Debian with a Flutter SDK pinned by version and checksum&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Runtime&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;nginx, unprivileged, with a read-only file system&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Settings&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Compiled in at build time, once per environment&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;API&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Its own origin&amp;rsquo;s &lt;code&gt;/api/&lt;/code&gt;, routed to the API by Traefik&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Health&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;/healthz&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Checks&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Analysis and tests, and generated code checked in GitHub Actions&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;h2 id="the-image"&gt;The image&lt;a class="heading-anchor" href="#the-image" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The build stage installs Flutter itself, rather than starting from a community&#10;Flutter image, so the exact SDK version is pinned and its download is checked&#10;against a SHA-256 checksum. It builds as a non-root user, and fetches packages&#10;with &lt;code&gt;--enforce-lockfile&lt;/code&gt;, so the build uses exactly the versions the&#10;repository was tested with:&lt;/p&gt;</description></item><item><title>How I Start a Project From Scratch</title><link>https://artur-rios.github.io/personal-lab/engineering/starting-a-project-from-scratch/</link><pubDate>Wed, 21 Oct 2026 17:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/engineering/starting-a-project-from-scratch/</guid><description>&lt;p&gt;Every project on this site starts the same way. Not with code, but with a&#10;document, because the cheapest place to find a mistake is in a sentence, before&#10;anything has been built on top of it. This is the roadmap I follow, from the&#10;first idea to a system that is ready to use:&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;Create a brainstorm document for the project, with ideas about its nature,&#10;its implementation and the technologies to use.&lt;/li&gt;&#10;&lt;li&gt;Refine the brainstorm into four initial documents: Project Overview,&#10;Technology Stack, Workflow and Business Rules.&lt;/li&gt;&#10;&lt;li&gt;Formalise them into a Vision Document, a System Requirements Document and a&#10;Use Case Specification Document.&lt;/li&gt;&#10;&lt;li&gt;Review the documents, improve them, and review them again until they match&#10;what the project is meant to be.&lt;/li&gt;&#10;&lt;li&gt;Create GitHub issues for the initial scaffold and infrastructure.&lt;/li&gt;&#10;&lt;li&gt;Create a GitHub issue for each use case, linked to a GitHub Project and to an&#10;MVP milestone.&lt;/li&gt;&#10;&lt;li&gt;Implement the initial scaffold and infrastructure.&lt;/li&gt;&#10;&lt;li&gt;Implement one use case after another, including unit and functional tests.&lt;/li&gt;&#10;&lt;li&gt;For each use case, run the tests and fix until all of them pass, and only&#10;then move on to the next one.&lt;/li&gt;&#10;&lt;li&gt;Run a final test of the full functionality and fix any issue found,&#10;repeating until the system is ready.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;The ten steps fall into four phases:&lt;/p&gt;</description></item><item><title>Craft: A Programming Language</title><link>https://artur-rios.github.io/personal-lab/brainstorms/craft/</link><pubDate>Wed, 21 Oct 2026 17:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/brainstorms/craft/</guid><description>&lt;p&gt;A modern programming language that supports the most used paradigms, and has all the features you need to write elegant solutions.&lt;/p&gt;&#10;&lt;h2 id="features"&gt;Features&lt;a class="heading-anchor" href="#features" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Multiplatform&lt;/li&gt;&#10;&lt;li&gt;Syntax inspired by C#&lt;/li&gt;&#10;&lt;li&gt;Proof, parallelism and speed inspired by &lt;a href="https://bend-lang.com/"&gt;Bend&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="roadmap"&gt;Roadmap&lt;a class="heading-anchor" href="#roadmap" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Develop a minimal version&lt;/li&gt;&#10;&lt;li&gt;Develop and test more features on top of the minimal version&lt;/li&gt;&#10;&lt;li&gt;Once we have a first stable version, start to develop simple programs in it&lt;/li&gt;&#10;&lt;li&gt;Develop more features, as we test and identify requirements&lt;/li&gt;&#10;&lt;li&gt;Build more complex programs and develop the language as we go&lt;/li&gt;&#10;&lt;li&gt;After having a stable programming language, with complex projects written on it, create a compiler written in Craft itself&lt;/li&gt;&#10;&lt;li&gt;Build an Operating System using the language&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="technology-stack"&gt;Technology stack&lt;a class="heading-anchor" href="#technology-stack" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;A language is two things: the design people write in, and the compiler and&#10;runtime that make it run. The stack is mostly the second, but three design&#10;choices shape it so much that they come first: how parallelism works, how&#10;memory is managed, and what &amp;ldquo;proof&amp;rdquo; means. The background on how a compiler is&#10;structured is in &lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/compilers/"&gt;Compilers&lt;/a&gt;, and the&#10;way C# itself runs is in &lt;a href="https://artur-rios.github.io/personal-lab/dotnet/compilation-and-execution/"&gt;How C# Runs&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Anvil OS: An Operating System From Scratch</title><link>https://artur-rios.github.io/personal-lab/brainstorms/anvil-os/</link><pubDate>Wed, 21 Oct 2026 15:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/brainstorms/anvil-os/</guid><description>&lt;p&gt;An open source operating system built from scratch.&lt;/p&gt;&#10;&lt;h2 id="overview"&gt;Overview&lt;a class="heading-anchor" href="#overview" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The idea is to build a fully functional operating system, to learn about how an operating system works, and from the simpler version of a kernel, improve it until something really usable.&lt;/p&gt;&#10;&lt;h2 id="roadmap"&gt;Roadmap&lt;a class="heading-anchor" href="#roadmap" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Start with the simpler version of a kernel&lt;/li&gt;&#10;&lt;li&gt;Build functionalities on top of the kernel&lt;/li&gt;&#10;&lt;li&gt;Improve as we test&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="technology-stack"&gt;Technology stack&lt;a class="heading-anchor" href="#technology-stack" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;An operating system has almost no stack in the usual sense: there is no&#10;runtime, no standard library and no framework beneath it, because it is the&#10;thing those normally run on. The choices that matter are the language, the&#10;processor architecture, how the kernel gets loaded, and the tools for running&#10;and debugging a kernel that cannot print an error when it crashes. The&#10;background for all of it is in &lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/operating-systems/"&gt;Operating Systems&lt;/a&gt;&#10;and &lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/processors/"&gt;Processors&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>The .NET Libraries I Reach For</title><link>https://artur-rios.github.io/personal-lab/dotnet/library-recommendations/</link><pubDate>Wed, 21 Oct 2026 13:20:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/library-recommendations/</guid><description>&lt;p&gt;Every new .NET project starts with the same handful of decisions. How will I&#10;test it? Where does fake data come from? How do I validate input, survive a&#10;flaky dependency, export a spreadsheet, run something every night? The base&#10;class library answers some of these. For the rest, I have settled on a short&#10;list of NuGet packages that I add almost without thinking.&lt;/p&gt;&#10;&lt;p&gt;This page is that list, with the reasoning written down. For each library I&#10;explain what it is for, why I use it, show a small example and say when I&#10;would pick something else. A recommendation is only as good as what it&#10;leaves out, so I also flag what I would want to know before adding a&#10;dependency: licence, maintenance, breaking changes, and in two cases events&#10;that every user of the library should know about.&lt;/p&gt;</description></item><item><title>Test Coverage in .NET: What It Measures and How to Collect It</title><link>https://artur-rios.github.io/personal-lab/dotnet/test-coverage/</link><pubDate>Wed, 21 Oct 2026 13:10:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/test-coverage/</guid><description>&lt;p&gt;A pull request comes back with a comment: &amp;ldquo;coverage dropped from 84% to 81%&amp;rdquo;.&#10;What does the number mean? Which 3% went missing, and does it matter? Coverage&#10;is one of the few test metrics that every .NET tool can produce for free, and&#10;one of the easiest to misread. It is very good at answering &lt;em&gt;which code did no&#10;test run?&lt;/em&gt; and close to useless at answering &lt;em&gt;are the tests any good?&lt;/em&gt;&lt;/p&gt;</description></item><item><title>EF Core or Dapper? Two Ways to Talk to a Database from .NET</title><link>https://artur-rios.github.io/personal-lab/dotnet/ef-core-and-dapper/</link><pubDate>Wed, 21 Oct 2026 13:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/ef-core-and-dapper/</guid><description>&lt;p&gt;Almost every .NET application that stores data ends up choosing how its C#&#10;code will talk to a relational database. Two names come up more than any&#10;other. &lt;strong&gt;Entity Framework Core&lt;/strong&gt; is Microsoft&amp;rsquo;s object-relational mapper: you&#10;describe your classes, and it writes the SQL, tracks what you change and&#10;evolves the schema. &lt;strong&gt;Dapper&lt;/strong&gt; is a small library from Stack Overflow: you&#10;write the SQL, and it turns the rows that come back into objects.&lt;/p&gt;</description></item><item><title>C# Delegates: Methods as Values</title><link>https://artur-rios.github.io/personal-lab/dotnet/delegates/</link><pubDate>Wed, 21 Oct 2026 12:50:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/delegates/</guid><description>&lt;p&gt;&lt;code&gt;List&amp;lt;T&amp;gt;.Sort&lt;/code&gt; doesn&amp;rsquo;t know how you want your items ordered, so it asks you:&#10;pass it a method that compares two items, and it calls that method whenever it&#10;needs to. A button doesn&amp;rsquo;t know what should happen when it is clicked, so it&#10;keeps a list of methods to call. LINQ&amp;rsquo;s &lt;code&gt;Where&lt;/code&gt; doesn&amp;rsquo;t know which items you&#10;want, so it takes a method that answers yes or no for each one. All three&#10;need the same thing from the language: a way to treat &lt;em&gt;a method&lt;/em&gt; as a value&#10;that can be stored in a field, passed as an argument and called later. In C#&#10;that value is a &lt;strong&gt;delegate&lt;/strong&gt;.&lt;/p&gt;</description></item><item><title>IEnumerable, ICollection, IList and IQueryable: What Each Collection Interface Promises</title><link>https://artur-rios.github.io/personal-lab/dotnet/collection-interfaces/</link><pubDate>Wed, 21 Oct 2026 12:40:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/collection-interfaces/</guid><description>&lt;p&gt;Open almost any C# codebase and you will find method signatures that take an&#10;&lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;, entities with &lt;code&gt;ICollection&amp;lt;T&amp;gt;&lt;/code&gt; navigation properties,&#10;repositories returning &lt;code&gt;IQueryable&amp;lt;T&amp;gt;&lt;/code&gt;, and the occasional &lt;code&gt;IList&amp;lt;T&amp;gt;&lt;/code&gt; or&#10;&lt;code&gt;IReadOnlyList&amp;lt;T&amp;gt;&lt;/code&gt;. They are easy to treat as interchangeable names for &amp;ldquo;a bunch&#10;of items&amp;rdquo;, and the code usually compiles whichever one you pick. Yet each&#10;interface makes a different promise, and choosing the wrong one causes real&#10;bugs: a query that runs three times, a database table loaded into memory to be&#10;filtered in C#, an exception thrown far from the line that caused it, or a&#10;&amp;ldquo;read-only&amp;rdquo; list that changes under your feet.&lt;/p&gt;</description></item><item><title>How C# Runs: From Source to IL to Machine Code</title><link>https://artur-rios.github.io/personal-lab/dotnet/compilation-and-execution/</link><pubDate>Wed, 21 Oct 2026 12:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/dotnet/compilation-and-execution/</guid><description>&lt;p&gt;A C# program is not compiled straight to machine code, and it is not&#10;interpreted either. It is compiled &lt;strong&gt;twice&lt;/strong&gt;. When you build, the C# compiler&#10;turns source code into an intermediate language and a description of every&#10;type, packed into an assembly, a &lt;code&gt;.dll&lt;/code&gt; file. When you run, the .NET runtime&#10;turns that intermediate language into machine code for the CPU it is running&#10;on, usually one method at a time and often more than once as it learns which&#10;code is hot.&lt;/p&gt;</description></item><item><title>Git Tags: Naming the Commits That Matter</title><link>https://artur-rios.github.io/personal-lab/git/git-tags/</link><pubDate>Wed, 21 Oct 2026 12:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/git/git-tags/</guid><description>&lt;p&gt;Branches move: every commit on &lt;code&gt;main&lt;/code&gt; moves &lt;code&gt;main&lt;/code&gt; forward. Sometimes you need&#10;a name that stays where it is put, such as &amp;ldquo;the commit that went out as&#10;version 1.6.0&amp;rdquo;. That is a &lt;strong&gt;tag&lt;/strong&gt;. Tags mark releases, the build a bug report&#10;refers to, or the last commit before a large refactor, and almost every&#10;release tool, from GitHub Releases to package registries, reads them.&lt;/p&gt;&#10;&lt;p&gt;Tags look simple, and mostly are. The parts that cause trouble are the two&#10;kinds of tag, which behave differently in some commands, and the fact that&#10;tags are not pushed, fetched or overwritten the way branches are. This article&#10;covers both. The commands shown were run with Git 2.56 on 21 October 2026, in&#10;a scratch repository and in this site&amp;rsquo;s own repository. Long temporary paths&#10;in the output are left out.&lt;/p&gt;</description></item><item><title>Thoth: An IDE That Grows With You</title><link>https://artur-rios.github.io/personal-lab/brainstorms/thoth/</link><pubDate>Wed, 21 Oct 2026 12:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/brainstorms/thoth/</guid><description>&lt;p&gt;An IDE that adapts to your exact needs, nothing more, nothing less.&lt;/p&gt;&#10;&lt;h2 id="features"&gt;Features&lt;a class="heading-anchor" href="#features" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Starts like a simple and lightweight code editor and the user can activate modules to add functionalities to fill their needs. For example a .NET module, an Angular module etc&lt;/li&gt;&#10;&lt;li&gt;Experience must be similar to Visual Studio Code on Linux and Windows and similar to LunarVim on terminal&lt;/li&gt;&#10;&lt;li&gt;Do not support extensions, the idea is to use the modules to extend the application on-demand&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="platforms"&gt;Platforms&lt;a class="heading-anchor" href="#platforms" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Linux&lt;/li&gt;&#10;&lt;li&gt;Windows&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="first-release-modules"&gt;First release modules&lt;a class="heading-anchor" href="#first-release-modules" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;.NET&lt;/li&gt;&#10;&lt;li&gt;Angular&lt;/li&gt;&#10;&lt;li&gt;React&lt;/li&gt;&#10;&lt;li&gt;Flutter&lt;/li&gt;&#10;&lt;li&gt;Python&lt;/li&gt;&#10;&lt;li&gt;Rust&lt;/li&gt;&#10;&lt;li&gt;HTML/CSS&lt;/li&gt;&#10;&lt;li&gt;JavaScript/TypeScript&lt;/li&gt;&#10;&lt;li&gt;Java&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="technology-stack"&gt;Technology stack&lt;a class="heading-anchor" href="#technology-stack" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;The feature that shapes the stack most is the second one: the same IDE in a&#10;window and in a terminal. If the window and the terminal are two programs, every&#10;feature is built twice. So the design starts from one &lt;strong&gt;core&lt;/strong&gt; that owns&#10;everything an editor does, such as buffers, cursors, syntax trees, language&#10;servers, commands, keymaps and modules, and two thin &lt;strong&gt;front ends&lt;/strong&gt; that only&#10;draw what the core describes and send it the user&amp;rsquo;s input. The core and the&#10;front ends talk only through typed messages: input events go in, view updates&#10;come out. Neither side calls into the other, so a front end can be replaced,&#10;and the core could later run in a separate process, for example on a remote&#10;machine over SSH.&lt;/p&gt;</description></item><item><title>Git Submodules: One Repository Pinned Inside Another</title><link>https://artur-rios.github.io/personal-lab/git/git-submodules/</link><pubDate>Wed, 21 Oct 2026 11:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/git/git-submodules/</guid><description>&lt;p&gt;This site is built with a Hugo theme I also maintain,&#10;&lt;a href="https://github.com/artur-rios/hugo-theme-nuno"&gt;nuno&lt;/a&gt;, and the theme lives in&#10;its own repository. The site needs an exact version of it, and I want to change&#10;the theme without copying files back and forth. Git&amp;rsquo;s answer is a&#10;&lt;strong&gt;submodule&lt;/strong&gt;: a repository placed inside another repository, the&#10;&lt;em&gt;superproject&lt;/em&gt;, which records exactly which commit of it to use. The site&amp;rsquo;s&#10;&lt;code&gt;themes/nuno&lt;/code&gt; folder is one, and it is the example throughout this article.&lt;/p&gt;</description></item><item><title>My Git Config and the Commands I Keep Reaching For</title><link>https://artur-rios.github.io/personal-lab/git/my-git-config-and-commands/</link><pubDate>Wed, 21 Oct 2026 10:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/git/my-git-config-and-commands/</guid><description>&lt;p&gt;This page is a reference rather than an article: the global configuration I set&#10;on every new machine, and the commands I look up often enough to keep written&#10;down. Each one comes with what it actually does and, where it rewrites history&#10;or throws work away, what to watch out for. Every command here was run against&#10;Git 2.56 on 21 October 2026, and the explanations follow the official Git&#10;reference pages linked at the end.&lt;/p&gt;</description></item><item><title>Mosaic: A Second Brain App</title><link>https://artur-rios.github.io/personal-lab/brainstorms/mosaic/</link><pubDate>Wed, 21 Oct 2026 09:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/brainstorms/mosaic/</guid><description>&lt;p&gt;An app that wants to be your second brain.&lt;/p&gt;&#10;&lt;h2 id="features"&gt;Features&lt;a class="heading-anchor" href="#features" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Create and organize notes in Markdown&lt;/li&gt;&#10;&lt;li&gt;Calendar&lt;/li&gt;&#10;&lt;li&gt;To do list&lt;/li&gt;&#10;&lt;li&gt;Kanban board&lt;/li&gt;&#10;&lt;li&gt;Pomodoro sessions&lt;/li&gt;&#10;&lt;li&gt;Mermaid diagrams&lt;/li&gt;&#10;&lt;li&gt;Draw diagrams&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="inspiration"&gt;Inspiration&lt;a class="heading-anchor" href="#inspiration" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;This app wants to combine features from these apps:&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;a href="https://obsidian.md/"&gt;Obsidian&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://super-productivity.com/"&gt;Super Productivity&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://excalidraw.com/"&gt;Excalidraw&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="platforms"&gt;Platforms&lt;a class="heading-anchor" href="#platforms" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Android&lt;/li&gt;&#10;&lt;li&gt;Linux&lt;/li&gt;&#10;&lt;li&gt;Web&lt;/li&gt;&#10;&lt;li&gt;Windows&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="technology-stack"&gt;Technology stack&lt;a class="heading-anchor" href="#technology-stack" aria-label="Link to this section"&gt;&lt;/a&gt;&lt;/h2&gt;&#10;&lt;p&gt;Two of the features decide most of the stack before anything else is weighed.&#10;Excalidraw is published as a React component, and Mermaid is a JavaScript&#10;library. Any stack that does not run JavaScript in a web view has to embed one&#10;to get them, so the cheapest path is to make the whole app a web app and wrap&#10;it for each platform. The suggestion below follows that path.&lt;/p&gt;</description></item><item><title>What Is the Dependency Inversion Principle? Policy, Detail and Who Owns the Interface</title><link>https://artur-rios.github.io/personal-lab/concepts/dependency-inversion-principle/</link><pubDate>Wed, 21 Oct 2026 00:05:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/concepts/dependency-inversion-principle/</guid><description>&lt;p&gt;A checkout that takes a payment has to call the payment provider: there is no&#10;way around that at run time. It does not follow that the checkout&amp;rsquo;s source code&#10;has to &lt;em&gt;name&lt;/em&gt; the provider, import its SDK, or change when the provider changes&#10;its API. The &lt;strong&gt;dependency inversion principle&lt;/strong&gt; is the rule that separates those&#10;two things. It asks which way the arrows between modules should point, and its&#10;answer is that the code holding the important decisions should not depend on the&#10;code holding the details; the details should depend on it. This is part five of&#10;a series on SOLID, after the &lt;a href="../single-responsibility-principle/"&gt;single responsibility&lt;/a&gt;,&#10;&lt;a href="../open-closed-principle/"&gt;open-closed&lt;/a&gt;, &lt;a href="../liskov-substitution-principle/"&gt;Liskov substitution&lt;/a&gt;&#10;and &lt;a href="../interface-segregation-principle/"&gt;interface segregation&lt;/a&gt; principles, and&#10;it leads into &lt;a href="../inversion-of-control/"&gt;inversion of control&lt;/a&gt;, the mechanism&#10;most programs use to put the principle into practice. This article explains what&#10;the principle says, where it came from, why the flow of control and the&#10;direction of a dependency can point opposite ways, why the abstraction has to&#10;belong to the code that uses it, and what is not worth inverting. Every output&#10;shown here was produced by running the code on Windows 11, with Python 3.14.6,&#10;not written by hand.&lt;/p&gt;</description></item><item><title>What Is the Interface Segregation Principle? Fat Interfaces, Role Interfaces and the Clients That Shape Them</title><link>https://artur-rios.github.io/personal-lab/concepts/interface-segregation-principle/</link><pubDate>Wed, 21 Oct 2026 00:04:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/concepts/interface-segregation-principle/</guid><description>&lt;p&gt;An invoice printer needs to read one order. In many codebases it is handed an&#10;object that can also save orders, cancel them, total the month&amp;rsquo;s revenue and&#10;export everything to a spreadsheet, because that is the interface the order&#10;store happens to have. The printer never calls those methods, but it depends on&#10;them all the same: when one of them changes, the printer is rebuilt, retested&#10;and redeployed, and anyone writing a stand-in for it in a test has to implement&#10;all five. The &lt;strong&gt;interface segregation principle&lt;/strong&gt; is the rule against that&#10;arrangement, and the fourth of the five SOLID principles this&#10;&lt;a href="../../series/solid/"&gt;series&lt;/a&gt; covers. This article explains&#10;what it says, where it came from, what a fat interface costs, how to split one&#10;into interfaces shaped by their clients, and where splitting stops paying.&#10;Every output shown here was produced by running the code on Windows 11, with&#10;Python 3.14.6 and with the .NET 10 SDK, not written by hand.&lt;/p&gt;</description></item><item><title>What Is the Liskov Substitution Principle? Subtypes, Contracts and the Promises a Base Class Makes</title><link>https://artur-rios.github.io/personal-lab/concepts/liskov-substitution-principle/</link><pubDate>Wed, 21 Oct 2026 00:03:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/concepts/liskov-substitution-principle/</guid><description>&lt;p&gt;A function that sorts a list of shapes by area has never heard of the square.&#10;It was written against a base type, and it will be handed whatever subclasses&#10;exist now and whatever subclasses someone writes next year. Whether it keeps&#10;working depends on a promise nobody wrote down: that every one of those classes&#10;behaves the way the base type said it would. The &lt;strong&gt;Liskov substitution&#10;principle&lt;/strong&gt; is that promise, made explicit. It is the third of the five SOLID&#10;principles, and this is part 3 of a &lt;a href="../../series/solid/"&gt;series on SOLID&lt;/a&gt;.&#10;This article explains what the principle says, where it came from, the rules a&#10;subtype has to keep, the violations that ship inside widely used platforms, and&#10;how to repair one. Every output shown here was produced by running the code on&#10;Windows 11, with Python 3.14.6, mypy 2.4.0 and the .NET 10 SDK, not written by&#10;hand.&lt;/p&gt;</description></item><item><title>What Is the Open-Closed Principle? Extension, Abstraction, Plug-ins and the Expression Problem</title><link>https://artur-rios.github.io/personal-lab/concepts/open-closed-principle/</link><pubDate>Wed, 21 Oct 2026 00:02:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/concepts/open-closed-principle/</guid><description>&lt;p&gt;A shop adds a new way to ship parcels. In one codebase that means opening the&#10;function that prices shipping, adding a branch to the middle of it, and&#10;re-testing everything that calls it. In another it means writing one new class&#10;in one new file, and nothing that already works is touched. The difference&#10;between the two is what the &lt;strong&gt;open-closed principle&lt;/strong&gt; is about: arranging code&#10;so that new behaviour arrives as new code, rather than as edits to code that is&#10;released, tested and depended on. It is the second of the five SOLID principles,&#10;and this is part 2 of a series on them, after&#10;&lt;a href="../single-responsibility-principle/"&gt;the single responsibility principle&lt;/a&gt;.&#10;This article explains what the principle means, where it came from, what it&#10;looks like in running code, why no module can be closed against every change,&#10;how the expression problem sets its limits, and when the abstraction it calls&#10;for is worth paying for. Every output shown here was produced by running the&#10;code on Windows 11, with Python 3.14.6, not written by hand.&lt;/p&gt;</description></item><item><title>What Is the Single Responsibility Principle? Reasons to Change, Actors and Cohesion</title><link>https://artur-rios.github.io/personal-lab/concepts/single-responsibility-principle/</link><pubDate>Wed, 21 Oct 2026 00:01:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/concepts/single-responsibility-principle/</guid><description>&lt;p&gt;An online shop has an &lt;code&gt;Order&lt;/code&gt; class. Finance uses it to book revenue, the&#10;storefront uses it to print receipts, and the platform team uses it to store&#10;orders in the database. One day the storefront asks for receipts to show prices&#10;with VAT, a developer makes the change in the obvious place, every test the&#10;storefront cares about passes, and at the end of the month finance&amp;rsquo;s revenue is&#10;twenty per cent too high. Nobody touched finance&amp;rsquo;s code. They touched code that&#10;finance &lt;em&gt;shared&lt;/em&gt;. The &lt;strong&gt;single responsibility principle&lt;/strong&gt; is the rule that&#10;would have kept those two apart, and it is the most quoted and least understood&#10;of the five SOLID principles. This is the first part of a series on SOLID: it&#10;explains what the principle says, where it came from, how the acronym itself&#10;was born, what it looks like in running code, and how far to take it. Every&#10;output shown here was produced by running the code on Windows 11, with Python&#10;3.14.6, not written by hand.&lt;/p&gt;</description></item><item><title>What Are CVE and CWE? Naming Vulnerabilities and the Weaknesses Behind Them</title><link>https://artur-rios.github.io/personal-lab/security/cve-and-cwe/</link><pubDate>Tue, 20 Oct 2026 23:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/security/cve-and-cwe/</guid><description>&lt;p&gt;A dependency scanner fails your build with &amp;ldquo;CVE-2021-44228, critical&amp;rdquo;. A static&#10;analysis tool flags a line of code as &amp;ldquo;CWE-89&amp;rdquo;. A vendor&amp;rsquo;s release notes list&#10;a dozen CVE numbers fixed in the latest patch, and a security questionnaire&#10;asks how you prevent &amp;ldquo;the CWE Top 25&amp;rdquo;. The two acronyms look alike, both are&#10;run by the same organisation and both turn up in the same tools, but they&#10;answer different questions. &lt;strong&gt;CVE&lt;/strong&gt; answers &lt;em&gt;which vulnerability is this?&lt;/em&gt;: it&#10;gives one specific, publicly known flaw in one product a name everyone can&#10;use. &lt;strong&gt;CWE&lt;/strong&gt; answers &lt;em&gt;what kind of mistake is this?&lt;/em&gt;: it names a type of&#10;weakness that can occur in any product, and that may cause many&#10;vulnerabilities over the years.&lt;/p&gt;</description></item><item><title>What Is Inversion of Control? Frameworks, Callbacks, Dependency Injection and Containers</title><link>https://artur-rios.github.io/personal-lab/concepts/inversion-of-control/</link><pubDate>Tue, 20 Oct 2026 23:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/concepts/inversion-of-control/</guid><description>&lt;p&gt;A web framework calls a function when a request arrives. A test runner finds&#10;the tests in a file and runs each one. A browser calls a handler when a button&#10;is clicked, and an application server hands a class the database connection it&#10;asked for in its constructor. In each case the code a programmer wrote does not&#10;decide when it runs or where its collaborators come from: something else does.&#10;That reversal has a name, &lt;strong&gt;inversion of control&lt;/strong&gt;, and it is one of the ideas&#10;most of modern software is quietly built on. This article explains what it&#10;means, where the term came from, the forms it takes, how dependency injection&#10;and IoC containers work inside, and when the indirection is worth paying for.&#10;It closes a series on &lt;a href="../../series/solid/"&gt;SOLID&lt;/a&gt;: where the&#10;&lt;a href="../dependency-inversion-principle/"&gt;dependency inversion principle&lt;/a&gt; says which&#10;way dependencies should point, this is the mechanism that makes them point&#10;that way at run time. Every output shown here was produced by running the code on Windows 11, with&#10;Python 3.14.6 and with the .NET 10 SDK and Microsoft.Extensions.DependencyInjection&#10;10.0.13, not written by hand.&lt;/p&gt;</description></item><item><title>What Is a Unit Test? Where Unit Testing Came From and How to Write Good Ones</title><link>https://artur-rios.github.io/personal-lab/fundamentals/unit-tests/</link><pubDate>Tue, 20 Oct 2026 22:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/unit-tests/</guid><description>&lt;p&gt;You change one line in a pricing function and want to know whether anything&#10;broke. You could start the whole application, log in, fill a cart and look at&#10;the total, for every kind of cart you can think of. Or you could run a few&#10;hundred small programs that each call the pricing function with one input and&#10;check the answer, and know in under a second. Those small programs are &lt;strong&gt;unit&#10;tests&lt;/strong&gt;, and the second way of working is one of the biggest changes in how&#10;software has been written in the last thirty years: from testing as a phase at&#10;the end of a project, done by someone else, to testing as something every&#10;programmer does every few minutes.&lt;/p&gt;</description></item><item><title>How Do Programs Talk to Each Other? JSON, XML, Protobuf, RPC, REST, gRPC, GraphQL and Messaging</title><link>https://artur-rios.github.io/personal-lab/fundamentals/communication-techniques/</link><pubDate>Tue, 20 Oct 2026 20:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/communication-techniques/</guid><description>&lt;p&gt;A mobile app asks a server for a user&amp;rsquo;s orders. The server asks a payment&#10;service whether an order was paid, tells a warehouse system to ship it, and&#10;announces to anyone interested that it has shipped. A code editor asks a&#10;language server where a function is defined; an AI agent asks a tool to read a&#10;file. All of these are programs talking to other programs, and every one of&#10;those conversations rests on two decisions: &lt;strong&gt;how the data is encoded&lt;/strong&gt; into&#10;bytes, and &lt;strong&gt;how the conversation is shaped&lt;/strong&gt;, as a function call, a request&#10;for a resource, a query, a stream or a message dropped in a queue.&lt;/p&gt;</description></item><item><title>Angular, React or Flutter? How They Compare and How to Choose</title><link>https://artur-rios.github.io/personal-lab/front-end/choosing-a-front-end-framework/</link><pubDate>Tue, 20 Oct 2026 18:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/front-end/choosing-a-front-end-framework/</guid><description>&lt;p&gt;&amp;ldquo;Angular or React?&amp;rdquo; is one of the most common questions in front-end&#10;development, and &amp;ldquo;or Flutter?&amp;rdquo; is now often added to it. The question sounds&#10;like a choice between three brands of the same product. It is not. Angular is&#10;a complete framework for web applications; React is a library for turning state&#10;into UI, which needs a framework around it to make an application; Flutter is a&#10;toolkit for mobile, desktop, web and embedded apps that does not use the&#10;browser&amp;rsquo;s HTML at all, but draws every pixel itself. Each has been described in&#10;detail in this section: &lt;a href="https://artur-rios.github.io/personal-lab/front-end/angular/"&gt;What Is Angular?&lt;/a&gt;,&#10;&lt;a href="https://artur-rios.github.io/personal-lab/front-end/react/"&gt;What Is React?&lt;/a&gt; and&#10;&lt;a href="https://artur-rios.github.io/personal-lab/front-end/flutter/"&gt;What Is Flutter?&lt;/a&gt;. This article puts them&#10;side by side and ends with a guide to choosing.&lt;/p&gt;</description></item><item><title>How Do Computer Networks Work? TCP/IP, the OSI Model and the Protocols Every Programmer Uses</title><link>https://artur-rios.github.io/personal-lab/fundamentals/computer-networks/</link><pubDate>Tue, 20 Oct 2026 18:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/computer-networks/</guid><description>&lt;p&gt;Very few programs work alone. A web page fetches data from an API, the API&#10;queries a database on another machine, the database replicates to a third, and&#10;all of them ask a time server what time it is and a name server where everyone&#10;else lives. Every one of those conversations crosses a network, and every one&#10;of them can be slow, fail halfway or arrive in pieces. A programmer who&#10;understands what happens between &lt;code&gt;connect()&lt;/code&gt; and the reply can tell a DNS&#10;problem from a TLS problem from a congested link, and can write code that&#10;copes with all three.&lt;/p&gt;</description></item><item><title>What Is Angular? Google's Web Framework, From AngularJS to Signals</title><link>https://artur-rios.github.io/personal-lab/front-end/angular/</link><pubDate>Tue, 20 Oct 2026 18:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/front-end/angular/</guid><description>&lt;p&gt;Most web pages are documents. Some are applications: a mail client, an&#10;analytics dashboard, a banking back office, a cloud console. Those have&#10;hundreds of screens, thousands of components and teams of dozens of people&#10;working on them for years, and building them directly on the browser&amp;rsquo;s&#10;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/how-browsers-work/"&gt;DOM and event loop&lt;/a&gt; quickly becomes&#10;unmanageable. &lt;strong&gt;Angular&lt;/strong&gt; is Google&amp;rsquo;s answer to that problem: a complete,&#10;opinionated framework that decides how such an application is structured,&#10;compiled, tested and shipped.&lt;/p&gt;</description></item><item><title>What Is Flutter? History, Architecture and How to Build With It</title><link>https://artur-rios.github.io/personal-lab/front-end/flutter/</link><pubDate>Tue, 20 Oct 2026 18:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/front-end/flutter/</guid><description>&lt;p&gt;Most toolkits for building an app on more than one platform make a choice&#10;early on: either they wrap each platform&amp;rsquo;s own buttons, lists and text fields,&#10;or they run the app inside a web view. Flutter does neither. It ships its own&#10;rendering engine inside every app and draws every pixel of the interface&#10;itself, from the text to the scroll bars, on a canvas the operating system&#10;hands it. The same Dart code then runs on Android, iOS, the web, Windows,&#10;macOS and Linux, and on embedded devices through a custom host.&lt;/p&gt;</description></item><item><title>What Is React? Components, Rendering and the Library Behind Modern Interfaces</title><link>https://artur-rios.github.io/personal-lab/front-end/react/</link><pubDate>Tue, 20 Oct 2026 18:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/front-end/react/</guid><description>&lt;p&gt;React is a JavaScript library for building user interfaces out of&#10;&lt;strong&gt;components&lt;/strong&gt;: small functions that describe what a piece of the screen&#10;should look like for a given state. You never tell React &lt;em&gt;how&lt;/em&gt; to change the&#10;page; you describe what it should be now, and React works out the smallest set&#10;of changes that gets the screen there. The idea met a cool reception when&#10;Facebook released React in 2013; today React is the most used library of its&#10;kind. In Stack Overflow&amp;rsquo;s 2026 Developer Survey, 42 percent of respondents said&#10;they had used it, second among web frameworks and technologies only to&#10;Node.js.&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;</description></item><item><title>How Does a Web Browser Work? From a URL to Pixels on the Screen</title><link>https://artur-rios.github.io/personal-lab/fundamentals/how-browsers-work/</link><pubDate>Tue, 20 Oct 2026 17:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/how-browsers-work/</guid><description>&lt;p&gt;A web browser is probably the most complex program most people use every day.&#10;In a few hundred milliseconds it turns a line of text in an address bar into&#10;a network connection, a stream of bytes, a tree of objects, a set of styled and&#10;measured boxes, and finally pixels, then keeps all of that live while scripts&#10;change it and the user scrolls, types and clicks. It is also a small operating&#10;system in its own right (&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/operating-systems/"&gt;What Is an Operating System?&lt;/a&gt;),&#10;running untrusted code from every site you visit and keeping those sites apart.&lt;/p&gt;</description></item><item><title>What Is Text Encoding? From Telegraph Codes to Unicode and UTF-8</title><link>https://artur-rios.github.io/personal-lab/fundamentals/text-encoding/</link><pubDate>Tue, 20 Oct 2026 17:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/text-encoding/</guid><description>&lt;p&gt;A computer stores nothing but numbers. Every letter you read on a screen, every&#10;name in a database and every line of source code is held as a sequence of&#10;numbers, and something has to agree on which number means which character.&#10;That agreement is a &lt;strong&gt;text encoding&lt;/strong&gt;. When it works, nobody notices. When two&#10;programs disagree, &amp;ldquo;café&amp;rdquo; turns into &amp;ldquo;cafÃ©&amp;rdquo;, a customer&amp;rsquo;s name is rejected as&#10;invalid, or an emoji crashes a database insert. This article explains what a&#10;text encoding is, how the world got from telegraph codes to Unicode, how the&#10;modern encodings work bit by bit, and where text still goes wrong. The examples&#10;were run with Python 3.10 and Node.js 12, and their output is shown as printed.&lt;/p&gt;</description></item><item><title>What Are Data Structures? From Arrays to Hash Tables, and How to Choose One</title><link>https://artur-rios.github.io/personal-lab/fundamentals/data-structures/</link><pubDate>Tue, 20 Oct 2026 16:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/data-structures/</guid><description>&lt;p&gt;Niklaus Wirth titled a 1976 book &lt;em&gt;Algorithms + Data Structures =&#10;Programs&lt;/em&gt;,&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; and &lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/what-is-programming/"&gt;What Is Programming?&lt;/a&gt;&#10;quoted it: choosing how to represent information is as much a part of&#10;programming as choosing the steps that work on it. This article is about the&#10;second half of that equation. It explains what a data structure is, where the&#10;classic ones came from, how each works and what it costs, and how to choose&#10;between them. The examples were run with Python 3.10 on an Intel Core&#10;i9-13900K, and their output is shown exactly as printed.&lt;/p&gt;</description></item><item><title>What Is a Compiler? How Source Code Becomes a Running Program</title><link>https://artur-rios.github.io/personal-lab/fundamentals/compilers/</link><pubDate>Tue, 20 Oct 2026 16:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/compilers/</guid><description>&lt;p&gt;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/what-is-programming/"&gt;What Is Programming?&lt;/a&gt; ended with&#10;high-level languages taking over from machine code, and&#10;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/processors/"&gt;What Is a Processor?&lt;/a&gt; described the machine&#10;instructions a CPU actually runs. Between the two sits the compiler: the&#10;program that turns one into the other. This article explains what a compiler&#10;is, where compilers came from, how each of their phases works, how a C file&#10;becomes an executable on a real system, and how to build a small compiler of&#10;your own. Every compiler output shown here was produced by running the tools&#10;on Ubuntu 22.04 with GCC 11.4 and Python 3.10, not written by hand.&lt;/p&gt;</description></item><item><title>Processes and Threads: What They Are, Where They Came From and How They Work</title><link>https://artur-rios.github.io/personal-lab/fundamentals/processes-and-threads/</link><pubDate>Tue, 20 Oct 2026 15:30:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/processes-and-threads/</guid><description>&lt;p&gt;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/operating-systems/"&gt;What Is an Operating System?&lt;/a&gt; introduced&#10;processes and threads in a few paragraphs, and&#10;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/processors/"&gt;What Is a Processor?&lt;/a&gt; showed the hardware they run&#10;on. This article gives them the space they deserve. Almost every question about&#10;how a program behaves when it does more than one thing at a time, from &amp;ldquo;why did&#10;my server run out of memory?&amp;rdquo; to &amp;ldquo;why does this counter come out wrong?&amp;rdquo;, comes&#10;down to the difference between a process and a thread.&lt;/p&gt;</description></item><item><title>What Is a Processor? History, Architectures and How a CPU Works</title><link>https://artur-rios.github.io/personal-lab/fundamentals/processors/</link><pubDate>Tue, 20 Oct 2026 15:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/processors/</guid><description>&lt;p&gt;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/what-is-programming/"&gt;What Is Programming?&lt;/a&gt; described programs as&#10;precise descriptions of a process, and&#10;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/operating-systems/"&gt;What Is an Operating System?&lt;/a&gt; described the&#10;software that shares a machine between them. This article goes one level&#10;further down, to the part that does the work: the processor. It covers what a&#10;processor is, how it got from vacuum tubes to tens of billions of transistors,&#10;the main ways processors are designed, and, in some detail, how a modern CPU&#10;turns instructions into results.&lt;/p&gt;</description></item><item><title>What Is an Operating System? History, Architectures and How It Works</title><link>https://artur-rios.github.io/personal-lab/fundamentals/operating-systems/</link><pubDate>Tue, 20 Oct 2026 09:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/operating-systems/</guid><description>&lt;p&gt;Every program you have ever written leaned on an operating system without&#10;asking. Printing a line, opening a file, allocating memory, waiting for a key&#10;press: none of these is something a processor knows how to do. The operating&#10;system does them on the program&amp;rsquo;s behalf, and does them for hundreds of other&#10;programs at the same time without letting any of them trample the others.&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://artur-rios.github.io/personal-lab/fundamentals/what-is-programming/"&gt;What Is Programming?&lt;/a&gt; followed the history&#10;of telling machines what to do. This article follows the program that stands&#10;between every other program and the machine: what it is, how it came to exist,&#10;the main ways it can be built, and, in some detail, how it actually works.&lt;/p&gt;</description></item><item><title>What Is Programming? A Short History of Telling Machines What to Do</title><link>https://artur-rios.github.io/personal-lab/fundamentals/what-is-programming/</link><pubDate>Mon, 19 Oct 2026 09:00:00 +0000</pubDate><guid>https://artur-rios.github.io/personal-lab/fundamentals/what-is-programming/</guid><description>&lt;p&gt;Ask ten developers what programming is and you will get ten answers: &amp;ldquo;writing&#10;code&amp;rdquo;, &amp;ldquo;solving problems&amp;rdquo;, &amp;ldquo;telling a computer what to do&amp;rdquo;. All of them are&#10;true, and none of them is quite enough. This article tries to pin the idea down,&#10;and then follows it through roughly two centuries of history — because most of&#10;what feels arbitrary about programming today makes sense once you know where it&#10;came from.&lt;/p&gt;</description></item></channel></rss>