<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:source="https://source.scripting.com/">
  <channel>
    <title>rbstp.dev</title>
    <link>https://rbstp.dev</link>
    <description>There and Back Again: A DevOps Engineer's Journey Through AI and Infrastructure</description>
    <language>en-us</language>
    <lastBuildDate>Mon, 14 Sep 2026 12:35:00 GMT</lastBuildDate>
    <pubDate>Tue, 01 Sep 2026 19:53:00 GMT</pubDate>
    <ttl>60</ttl>
    <atom:link href="https://rbstp.dev/feed.xml" rel="self" type="application/rss+xml"/>
    <generator>gist-blog-generator</generator>
    <cloud domain="rpc.rsscloud.io" port="5337" path="/pleaseNotify" registerProcedure="" protocol="http-post"/>
    <image>
      <url>https://rbstp.dev/favicon.png</url>
      <title>rbstp.dev</title>
      <link>https://rbstp.dev</link>
      <width>128</width>
      <height>128</height>
    </image>
    <item>
      <title><![CDATA[Omarchy ruined clicking to type, so I wrote focus follows mouse for macOS]]></title>
      <link>https://rbstp.dev/posts/632e12c3125f80bdec4f8240b205f5dc.html</link>
      <guid>https://rbstp.dev/posts/632e12c3125f80bdec4f8240b205f5dc.html</guid>
      <pubDate>Tue, 01 Sep 2026 19:53:00 GMT</pubDate>
      <description><![CDATA[<p>Omarchy is what did it. Hyprland hands keyboard focus to whatever window the pointer is over, no click, and you stop thinking about it inside a day. Back on macOS I was clicking a window before typing into it again, every single time.</p>
<p><strong><a href="https://github.com/rbstp/heed">github.com/rbstp/heed</a></strong></p>
<pre><code class="hljs language-sh">brew install --cask rbstp/tap/heed</code></pre><p>That is the whole setup. Grant Accessibility when macOS asks and it runs as a login agent, no Dock icon and no window of its own. A menu bar cube switches it off, ⌃⌘H does the same from the keyboard. macOS 14 or newer, Apple Silicon, MIT.</p>
<h2 id="knowing-when-to-leave-you-alone-is-the-whole-job">Knowing when to leave you alone is the whole job</h2><p>Following the pointer is the easy part. Almost all of the work went into the moments where focus must not move, because getting those wrong makes the idea unusable rather than merely annoying.</p>
<p>Type a sentence and let the mouse drift over another window. The rest of the sentence stays where you started it. Focus also holds still while a mouse button is down, while a menu or a drag image is on screen, while you are in a password field, and while ⌘ is held for Cmd-Tab. Open a new window and it keeps focus until you actually come to rest somewhere else, so you can walk over to it across two displays without losing it to everything you cross on the way.</p>
<p>It stops sampling when the pointer stops, which is what keeps it off your battery.</p>
]]></description>
      <category>hyprland</category>
      <category>macos</category>
      <category>omarchy</category>
      <category>swift</category>
    </item>
    <item>
      <title><![CDATA[The lab was the easy half. This is the curriculum that drives it]]></title>
      <link>https://rbstp.dev/posts/00c624e2eabbeb8b25cba8eea3b2553d.html</link>
      <guid>https://rbstp.dev/posts/00c624e2eabbeb8b25cba8eea3b2553d.html</guid>
      <pubDate>Sat, 29 Aug 2026 03:42:33 GMT</pubDate>
      <description><![CDATA[<p><a href="/posts/310b6468965d431012494df3d860ca13.html">Last time</a> I published the CNPE lab, an internal developer platform on <code>kind</code> as layered <code>make</code> targets, with 71 checks that ask whether things work rather than whether pods are Running. That was the machinery. It says nothing about what to do with it on a Tuesday evening.</p>
<p>This is the other half.</p>
<p><strong><a href="https://cnpe.rbstp.dev/">cnpe.rbstp.dev</a></strong></p>
<p>Twenty-nine sections across the five exam domains, one evening each, covering every competency in the official curriculum PDF. Concepts, exercises against the lab, then a self-check. It is a static site with no build step, so <code>curriculum/index.html</code> opens straight out of the clone and <code>make study</code> does it for you. Thirteen of the figures are interactive, because dragging a pod&#39;s memory request until the QoS class flips beats reading about eviction order.</p>
<h2 id="every-exercise-ends-in-a-command">Every exercise ends in a command</h2><p>The lab&#39;s rule carries over. Never trust &quot;the pod is Running&quot;, make it do something. All 123 exercises finish with a command whose output proves the thing worked.</p>
<p>Seventy-one of those command blocks carry a collapsed drawer holding the real output. I ran every one against a freshly built lab on 26 August 2026 and captured what it printed, the failures included. Predict the output first, then open the drawer. Chart versions float on purpose, so yours will drift from mine, and working out why is the exercise.</p>
<h2 id="two-hours-is-the-whole-design-constraint">Two hours is the whole design constraint</h2><p>The exam is 120 minutes of performance-based tasks on a remote desktop. 15 to 20 tasks in two hours is 6 to 8 minutes each, and everything here falls out of that number. <code>make break</code> runs a 7-minute clock. Both mock exams carry a 120-minute clock and a grading block you run with <code>make grade</code>, fifteen tasks each, no task shape shared between the papers. The first exam-day tactic on the dashboard is to flag and move on, because a stuck task costs you two easy ones.</p>
<p>Documentation is tighter than people expect. The instructions allow <a href="https://kubernetes.io/docs/">kubernetes.io/docs</a> plus the task-specific links in each question&#39;s Quick Reference panel, and prohibit the rest. Tool documentation reaches you only through those links. So <code>kubectl explain --recursive</code>, <code>kubectl api-resources | grep &lt;tool&gt;</code> and <code>--help</code> are your real references, and every section leans on them rather than on a URL you will not be able to open.</p>
<p>Domain weights are not study time. Domains 2 and 3 are half the exam and mostly mechanical skills that improve with reps. Domain 1 and half of domain 5 are things you already know if you run Kubernetes for a living. Check yourself against the exercises before spending evenings there.</p>
<h2 id="the-drill">The drill</h2><p>The 148 self-check questions double as flashcards on an expanding review interval, scaled by how often you miss the card. First review a day later, then four days, then multiply. Miss one and it comes back immediately, a rung lower. Nothing rests longer than 21 days, because the exam is weeks away and not years. A weak-spots panel splits lifetime accuracy by domain and wants five answers in a domain before calling it weak, since one bad card is noise.</p>
<h2 id="using-it">Using it</h2><pre><code class="hljs language-crmsh">git <span class="hljs-keyword">clone</span> <span class="hljs-title">https</span>://github.com/rbstp/cnpe-exam-prep.git &amp;&amp; cd cnpe-exam-prep
make study          <span class="hljs-comment"># opens curriculum/index.html, no server, no build</span>
make grade <span class="hljs-attr">EXAM=</span><span class="hljs-number">1</span>   <span class="hljs-comment"># runs mock exam 1&#x27;s grading block against your lab</span></code></pre><p>Or read it at <a href="https://cnpe.rbstp.dev/">cnpe.rbstp.dev</a>. There is a single-file build at <a href="https://cnpe.rbstp.dev/console.html">cnpe.rbstp.dev/console.html</a> too, all 33 pages and the fonts inlined into one 1.1 MB document that works offline. Progress lives in local storage, Export and Import move it as JSON, and signing in with GitHub is optional, off by default and identity only. The OAuth scope is empty, so the token opens nothing.</p>
]]></description>
      <category>certification</category>
      <category>cnpe</category>
      <category>platformengineering</category>
    </item>
    <item>
      <title><![CDATA[I built the CNPE exam lab I wanted to study from]]></title>
      <link>https://rbstp.dev/posts/310b6468965d431012494df3d860ca13.html</link>
      <guid>https://rbstp.dev/posts/310b6468965d431012494df3d860ca13.html</guid>
      <pubDate>Sat, 22 Aug 2026 17:50:01 GMT</pubDate>
      <description><![CDATA[<p>The CNCF&#39;s <a href="https://training.linuxfoundation.org/certification/certified-cloud-native-platform-engineer-cnpe/">Certified Cloud Native Platform Engineer</a> exam is hands-on across five domains. Reading docs does not prepare you for that. So I built the platform instead and published it.</p>
<p><strong><a href="https://github.com/rbstp/cnpe-exam-prep">github.com/rbstp/cnpe-exam-prep</a></strong></p>
<p>A full internal developer platform on <code>kind</code>, as layered <code>make</code> targets you install and remove one at a time. Cilium, Gitea, Argo CD, Flux, Argo Rollouts, Tekton, Crossplane, CloudNativePG, Prometheus, Grafana, OpenTelemetry, Jaeger, Loki, OpenCost, Kyverno, Gatekeeper, SPIRE, Istio ambient, and Backstage.</p>
<h2 id="checking-behaviour-instead-of-pod-status">Checking behaviour instead of pod status</h2><p><code>make validate</code> runs 69 checks, and none of them ask whether a pod is Running. It does not ask &quot;is Crossplane installed&quot;. It applies an XR and asserts a real namespace appeared with the quota values patched from its spec. It does not ask &quot;is Cilium up&quot;. It runs a pod that has to fail to reach the internet, and the check fails if that egress works.</p>
<p>That distinction is the whole point. kindnet does not enforce NetworkPolicy, so on most kind-based labs every network-policy exercise silently passes and you learn nothing at all. Use Cilium, then prove enforcement.</p>
<h2 id="four-things-that-cost-me-real-time">Four things that cost me real time</h2><p><strong>The audit policy filename stops the cluster from booting.</strong> kube-apiserver is started with <code>--audit-policy-file=/etc/kubernetes/audit/policy.yaml</code>, so the mounted directory has to contain a file called exactly that. Get it wrong and the API server refuses to start. It looks like a cluster that never boots, not a config error.</p>
<p><strong>You cannot break DNS by adding a NetworkPolicy.</strong> They are additive allow-lists, so a new restrictive policy cannot revoke an allowance another policy already granted. My fault-injection drill &quot;blocked DNS&quot; by adding one, and it never blocked anything. To actually break resolution you have to remove the rule that permitted it.</p>
<p><strong>An <code>ipBlock</code> on the API server ClusterIP does not work.</strong> CloudNativePG hangs forever in a default-deny namespace because its instance manager cannot reach the API server. The obvious fix, allowing egress to <code>10.96.0.1/32:443</code>, still fails. The ClusterIP is DNAT&#39;d to a node&#39;s <code>:6443</code> before policy evaluation. With Cilium you want <code>toEntities: [kube-apiserver]</code>.</p>
<p><strong>Gateway API v1.5 and later blocks older Gateway API CRDs.</strong> It ships a policy that rejects any CRD before v1.5.0, and <code>cloud-provider-kind</code> embeds an older bundle it installs at startup. It gets denied, its service controller dies, and no LoadBalancer ever gets an IP. Start it with <code>--gateway-channel=disabled</code>.</p>
<h2 id="running-it">Running it</h2><p>Tested on a 2019 Intel MacBook Pro, i9-9880H with 32 GB, running Arch. Roughly 70 minutes for everything, about 25 for a useful subset. At rest it is two clusters, around 100 pods and 21 GB of RAM. CPU is the bottleneck, never memory.</p>
<pre><code class="hljs language-bash">git <span class="hljs-built_in">clone</span> https://github.com/rbstp/cnpe-exam-prep.git &amp;&amp; <span class="hljs-built_in">cd</span> cnpe-exam-prep
<span class="hljs-built_in">cp</span> lab.env.example lab.env
make host tools core
make validate</code></pre><p>The part I will use to study with is <code>make break</code>. It injects one of seven realistic faults into a tenant namespace and starts a seven minute clock, which is about exam pace. <code>make break-fix</code> diagnoses it from cluster state and tells you where the evidence was. Incident response is a third of the observability domain and the hardest thing to practise alone.</p>
<p>MIT licensed. I am still working through the material, so the repo will keep moving.</p>
]]></description>
      <category>certification</category>
      <category>cnpe</category>
      <category>homelab</category>
    </item>
    <item>
      <title><![CDATA[Vibe Coding Audiobook Review]]></title>
      <link>https://rbstp.dev/posts/6b4a80a7b06535327b2093d3d03ea004.html</link>
      <guid>https://rbstp.dev/posts/6b4a80a7b06535327b2093d3d03ea004.html</guid>
      <pubDate>Mon, 06 Oct 2025 02:02:38 GMT</pubDate>
      <description><![CDATA[<p><strong>Story: ⭐⭐⭐ | Narration: ⭐⭐⭐⭐⭐</strong></p>
<p>Gene Kim and Steve Yegge’s audiobook on vibe coding has excellent narration, but I’d recommend checking out <a href="https://youtube.com/@vibecodingwithsteveandgene">their YouTube channel</a> instead. Most of the book’s examples were already covered in their promotional videos, and the high-level approach makes you wonder how long the advice will stay relevant in this fast-moving space.</p>
<p>The core framework they present, the Three Developer Loops, is genuinely useful though:</p>
<h2 id="inner-loop-seconds-to-minutes">Inner Loop (Seconds to Minutes)</h2><p>This is where AI shines brightest. Get AI to write specifications and tests, use it as your “Git maestro” for quick iterations. The speed here is incredible.</p>
<h2 id="middle-loop-hours-to-days">Middle Loop (Hours to Days)</h2><p>Focus on getting code into users’ hands quickly, working with AI on real issues, and maintaining that human collaboration element. It’s about keeping your development cycle tight while staying grounded in actual user needs.</p>
<h2 id="outer-loop-weeks-to-months">Outer Loop (Weeks to Months)</h2><p>The bigger picture stuff: preventing “kitchen fires” through stress tests and automation, detecting issues with proper CI/CD pipelines, and correcting problems systematically. This is where the Prevent-Detect-Correct cycle really matters.</p>
<h2 id="other-notes">Other Notes</h2><p>Parts 3 and 4 had some solid insights, but nothing groundbreaking if you’re already working with AI tools. The kitchen analogy gets overused pretty quickly, which doesn’t help.</p>
<p>If you’re new to AI-assisted development, the YouTube series gives you the essentials without the time commitment. If you’re already familiar with these concepts, you won’t find much new here beyond the well-produced audio experience.</p>
]]></description>
      <category>ai</category>
      <category>book</category>
      <category>vibe</category>
    </item>
  </channel>
</rss>