<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>Linkblog</title>
        <description></description>
        <link></link>
        <lastBuildDate>Thu, 11 Jun 2026 06:24:13 +0000</lastBuildDate>
        <generator>FeedCreator 1.8</generator>
        <item>
            <title>Vibe Engineering a Personal Tool</title>
            <link>https://www.cosmocode.de/en/blog/agoh/20260609-vibe-engineering/</link>
            <description>
&lt;p&gt;There are two approaches when it comes to using modern coding agents. On one end of the spectrum is pure vibe coding: you let the agent build and never look at the code. The other end has been dubbed agentic engineering: you treat the agent as a co-developer, and you discuss and review all changes in detail.&lt;/p&gt;
&lt;p&gt;At CosmoCode, we usually use the latter approach. We want to own and understand the code we deliver. &lt;strong&gt;Coding agents can help us deliver better code, not necessarily more code or code built faster&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;But if the approach to coding agents is a spectrum, then there should be a middle ground as well. I like to call it “vibe engineering”. Vibe engineering is a more relaxed approach to coding agents: you still review the code it generates, but you don’t scrutinize every line of it.&lt;/p&gt;
&lt;p&gt;I like this approach for personal tools that aren’t purely one-off scripts, but also aren’t production code. These are tools that I want to use for myself, but that I don’t necessarily want to turn into real “projects”.&lt;/p&gt;
&lt;p&gt;One of my colleagues asked me if I could describe how I approach &lt;strong&gt;vibe engineering&lt;/strong&gt; for such &lt;strong&gt;a personal tool&lt;/strong&gt;, using a real example. This is easier said than done, but I’ll try anyway. I will give some examples of the kind of interactions I have with the agent without reproducing the entire conversation. I’ll hide the full Claude answers behind a &lt;code&gt;details&lt;/code&gt; tag, so you can drill into them if you want to see the full context. I will still omit the tool calls.&lt;/p&gt;
&lt;h2&gt;Step 1: Brainstorming&lt;/h2&gt;
&lt;p&gt;We’re running most of our services in a &lt;strong&gt;Kubernetes cluster&lt;/strong&gt;, and sometimes you need to move files to or from a storage volume mounted to a specific pod. This can be done with &lt;code&gt;kubectl cp&lt;/code&gt;. However, &lt;code&gt;kubectl cp&lt;/code&gt; does not take care of copying last modified dates. The workaround is to use &lt;code&gt;kubectl exec&lt;/code&gt; and tar to stream to stdout, then use a second tar to read stdin on the other side: classic Unix tooling. But constructing the right &lt;code&gt;kubectl exec&lt;/code&gt; call is non-trivial.&lt;/p&gt;
&lt;p&gt;I wanted a simple, Midnight Commander-like, &lt;strong&gt;two-panel TUI interface for copying files&lt;/strong&gt;. One side shows my local computer and the pod’s filesystem is shown on the other side. Files can simply be selected and copied by the press of a button.&lt;/p&gt;
&lt;p&gt;To figure out how feasible this is, I actually started in Claude chat. I find that the chat interface is a better way to do initial brainstorming than jumping right into Claude Code - especially when I am not even sure I want to pursue the project in the end. I can ask questions, get suggestions, and iterate on the idea without constantly having to tell Claude not to start coding. But yes, I could also have used Claude Code’s plan mode.&lt;/p&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;question: how complicated would it be to create a simple TUI tool that uses kubectl and tar to allow for easy file transfer between the local machine and a kubernetes pod using a two panel layout? (tar to preserve timestamps and file permissions)&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude explains how it could work and offers three approaches&lt;/summary&gt;&lt;div&gt;&lt;p&gt;Not very complicated. A working version is a weekend project; a polished one is maybe a week.&lt;/p&gt;&lt;p&gt;Here’s the breakdown:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The core mechanics are easy.&lt;/strong&gt; kubectl already does the heavy lifting:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;List remote files: &lt;code&gt;kubectl exec &amp;lt;pod&amp;gt; -- ls -la --time-style=full-iso /path&lt;/code&gt; (parse the output)&lt;/li&gt;
&lt;li&gt;Pull a file/dir preserving metadata: &lt;code&gt;kubectl exec &amp;lt;pod&amp;gt; -- tar cf - -C /parent target | tar xf - -C /local/dest&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Push: &lt;code&gt;tar cf - -C /local target | kubectl exec -i &amp;lt;pod&amp;gt; -- tar xf - -C /remote/dest&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This is essentially what &lt;code&gt;kubectl cp&lt;/code&gt; does internally (it’s tar-based), but you get to control flags like &lt;code&gt;--numeric-owner&lt;/code&gt;, &lt;code&gt;-p&lt;/code&gt;, etc. yourself.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The TUI is the bulk of the work.&lt;/strong&gt; A two-panel layout (local on left, remote on right, Tab to switch focus, arrows to navigate, Enter to descend, F5/F6 to copy — basically Midnight Commander) is a well-trodden pattern. The real effort goes into directory navigation state, scrolling, selection, and async transfers so the UI doesn’t freeze.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Recommended stack:&lt;/strong&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Go&lt;/strong&gt; — &lt;code&gt;bubbletea&lt;/code&gt;/&lt;code&gt;bubbles&lt;/code&gt; for the TUI, and you can use &lt;code&gt;client-go&lt;/code&gt; to talk to the API directly (including the exec/SPDY streaming) instead of shelling out. Natural fit since kubectl is Go.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt; — &lt;code&gt;textual&lt;/code&gt; for the TUI is very fast to build in; shell out to &lt;code&gt;kubectl&lt;/code&gt; or use the &lt;code&gt;kubernetes&lt;/code&gt; client library. Lowest effort to a prototype.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust&lt;/strong&gt; — &lt;code&gt;ratatui&lt;/code&gt; if you want a single static binary and don’t mind more work.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;The fiddly parts&lt;/strong&gt; (where the time actually goes):&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Pods often lack &lt;code&gt;tar&lt;/code&gt; (especially distroless/scratch images) — you need a fallback or a clear error.&lt;/li&gt;
&lt;li&gt;Multi-container pods need &lt;code&gt;-c &amp;lt;container&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Async progress reporting for large transfers without blocking the event loop.&lt;/li&gt;
&lt;li&gt;Error handling for permissions, broken pipes, missing paths.&lt;/li&gt;
&lt;li&gt;Context/namespace selection.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If you shell out to &lt;code&gt;kubectl&lt;/code&gt; and use Textual or Bubbletea, a usable single-pod-context prototype is genuinely a 1–2 day effort. Going to API-direct streaming, progress bars, multi-namespace browsing, and the tar-missing fallbacks is what stretches it toward a week.&lt;/p&gt;&lt;p&gt;Want me to sketch out a starter implementation in one of these stacks?&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;Hmm I would tend towards go because I like the single binary and I know a bit of go. But you say it’s the most difficult option?&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude suggests to keep things simple&lt;/summary&gt;&lt;div&gt;&lt;p&gt;Not the most difficult — I’d put it in the middle. The ordering I had in mind:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python/Textual&lt;/strong&gt; — fastest to a prototype, but you don’t get the single binary you want (you’re shipping a Python env or doing PyInstaller gymnastics).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Go/Bubbletea&lt;/strong&gt; — slightly more upfront ceremony than Python, but you get the single static binary, and you already know some Go. This is the sweet spot for &lt;em&gt;your&lt;/em&gt; constraints.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rust/ratatui&lt;/strong&gt; — most work (borrow checker + more manual TUI plumbing), only worth it if you specifically want it.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So Go isn’t the hard option — it’s the right one for what you care about. Python only “wins” on raw speed-to-prototype, and it loses the thing you explicitly said you like.&lt;/p&gt;&lt;p&gt;One more decision inside the Go path that affects difficulty:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Shell out to &lt;code&gt;kubectl&lt;/code&gt;&lt;/strong&gt; (run &lt;code&gt;exec.Command(&quot;kubectl&quot;, ...)&lt;/code&gt;) — much simpler. You let the user’s existing kubeconfig/context do its thing, and you just pipe tar streams around. This keeps you firmly in the “1–2 day prototype” zone.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Use &lt;code&gt;client-go&lt;/code&gt; directly&lt;/strong&gt; — no kubectl dependency, cleaner streaming, but &lt;code&gt;client-go&lt;/code&gt; has a real learning curve (the exec/SPDY/remotecommand setup is notoriously fiddly, and kubeconfig loading has its own boilerplate). This is what pushes things toward the week.&lt;/p&gt;&lt;p&gt;My suggestion: start by shelling out to &lt;code&gt;kubectl&lt;/code&gt;. You get a working tool fast, and you can swap the transfer layer for &lt;code&gt;client-go&lt;/code&gt; later without touching the TUI — if you keep a clean interface like:&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; Transfer&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) ([]&lt;/span&gt;&lt;span&gt;FileInfo&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Pull&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;remotePath&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;localPath&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;localPath&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;remotePath&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then the kubectl-shelling implementation and a future client-go implementation are just two structs satisfying the same interface.&lt;/p&gt;&lt;p&gt;Want me to put together a starter Bubbletea skeleton with the two-panel layout and a kubectl-backed &lt;code&gt;Transfer&lt;/code&gt; implementation?&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;can you create a PLAN file that I can pass to a coding agent?&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;At that point, Claude created a plan artifact, which I read through and addressed my concerns about certain details.&lt;/p&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;one question about the numeric UIDs. when the pod container runs rootless, you probably can not change UIDs?&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;After Claude clarified, I asked it to update the plan, and then I was ready to start coding.&lt;/p&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;PLAN.md:&lt;/summary&gt;&lt;div&gt;&lt;h1&gt;PLAN: &lt;code&gt;k8tc&lt;/code&gt; — A Two-Panel TUI for Kubernetes Pod File Transfer&lt;/h1&gt;&lt;h2&gt;Goal&lt;/h2&gt;&lt;p&gt;Build a terminal UI tool, written in &lt;strong&gt;Go&lt;/strong&gt;, that lets a user browse the local
filesystem and a Kubernetes pod’s filesystem side-by-side in a two-panel
(Midnight Commander style) layout, and transfer files/directories between them.
Transfers use &lt;strong&gt;&lt;code&gt;tar&lt;/code&gt; streamed over &lt;code&gt;kubectl exec&lt;/code&gt;&lt;/strong&gt; so that timestamps and file
permissions are preserved.&lt;/p&gt;&lt;p&gt;Ship as a &lt;strong&gt;single static binary&lt;/strong&gt;.&lt;/p&gt;&lt;h2&gt;Non-Goals (v1)&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;No &lt;code&gt;client-go&lt;/code&gt; integration. v1 shells out to the user’s existing &lt;code&gt;kubectl&lt;/code&gt;.
(Keep the transfer layer behind an interface so &lt;code&gt;client-go&lt;/code&gt; can be added later
without touching the TUI.)&lt;/li&gt;
&lt;li&gt;No editing of remote files in-place.&lt;/li&gt;
&lt;li&gt;No multi-pod parallel transfers.&lt;/li&gt;
&lt;li&gt;No Windows-specific polish (target Linux/macOS; it may work on Windows but
that is not a v1 requirement).&lt;/li&gt;
&lt;/ul&gt;&lt;hr&gt;&lt;h2&gt;Tech Stack&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Language:&lt;/strong&gt; Go (1.22+)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TUI framework:&lt;/strong&gt; &lt;a href=&quot;https://github.com/charmbracelet/bubbletea&quot;&gt;Bubble Tea&lt;/a&gt;
(&lt;code&gt;github.com/charmbracelet/bubbletea&lt;/code&gt;) with
&lt;a href=&quot;https://github.com/charmbracelet/bubbles&quot;&gt;Bubbles&lt;/a&gt; components and
&lt;a href=&quot;https://github.com/charmbracelet/lipgloss&quot;&gt;Lip Gloss&lt;/a&gt; for styling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;External dependency at runtime:&lt;/strong&gt; &lt;code&gt;kubectl&lt;/code&gt; must be on the user’s &lt;code&gt;PATH&lt;/code&gt;
and configured (valid kubeconfig / current context). The target pod must have
&lt;code&gt;tar&lt;/code&gt; available in the chosen container.&lt;/li&gt;
&lt;/ul&gt;&lt;hr&gt;&lt;h2&gt;Architecture&lt;/h2&gt;&lt;h3&gt;Package layout&lt;/h3&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;cmd/k8tc/main.go        # entrypoint, flag parsing, bubbletea program start&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;internal/transfer/      # the Transfer interface + kubectl implementation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;transfer.go           # interface + shared types (FileInfo)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;kubectl.go            # kubectl-backed implementation&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;internal/local/         # local filesystem browsing (List/Stat helpers)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;internal/ui/            # bubbletea model, panels, key handling, rendering&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;model.go&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;panel.go&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;keys.go&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;styles.go&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Core interface&lt;/h3&gt;&lt;p&gt;The transfer layer is abstracted so the kubectl implementation can later be
swapped for a &lt;code&gt;client-go&lt;/code&gt; one:&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;package&lt;/span&gt;&lt;span&gt; transfer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;import&lt;/span&gt;&lt;span&gt; &quot;&lt;/span&gt;&lt;span&gt;time&lt;/span&gt;&lt;span&gt;&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; FileInfo&lt;/span&gt;&lt;span&gt; struct&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Name    &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Size    &lt;/span&gt;&lt;span&gt;int64&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Mode    &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;    // e.g. &quot;drwxr-xr-x&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    IsDir   &lt;/span&gt;&lt;span&gt;bool&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    ModTime &lt;/span&gt;&lt;span&gt;time&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Time&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; Transfer&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // List returns directory contents at path inside the pod.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    List&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;container&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) ([]&lt;/span&gt;&lt;span&gt;FileInfo&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Pull copies remotePath (file or dir) from the pod to localPath, preserving metadata.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Pull&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;container&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;remotePath&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;localPath&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;progress&lt;/span&gt;&lt;span&gt; func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt; int64&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    // Push copies localPath (file or dir) into the pod at remotePath, preserving metadata.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    Push&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;pod&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;container&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;localPath&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;remotePath&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;progress&lt;/span&gt;&lt;span&gt; func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;n&lt;/span&gt;&lt;span&gt; int64&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The local filesystem panel does &lt;strong&gt;not&lt;/strong&gt; go through &lt;code&gt;Transfer&lt;/code&gt;; it uses the
&lt;code&gt;internal/local&lt;/code&gt; helpers directly. Only the remote panel uses &lt;code&gt;Transfer&lt;/code&gt;.&lt;/p&gt;&lt;hr&gt;&lt;h2&gt;Transfer Mechanics (the important bit)&lt;/h2&gt;&lt;p&gt;All remote operations shell out to &lt;code&gt;kubectl&lt;/code&gt;. Build commands with
&lt;code&gt;os/exec.CommandContext&lt;/code&gt; and stream stdin/stdout — &lt;strong&gt;never&lt;/strong&gt; buffer whole files
in memory.&lt;/p&gt;&lt;h3&gt;Listing remote files&lt;/h3&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;kubectl exec &amp;lt;pod&amp;gt; [-c &amp;lt;container&amp;gt;] -- ls -la --full-time &amp;lt;path&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Parse the output into &lt;code&gt;[]FileInfo&lt;/code&gt;. Notes:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;--full-time&lt;/code&gt; (GNU coreutils) for a parseable ISO timestamp. If that fails
(BusyBox), fall back to &lt;code&gt;ls -la&lt;/code&gt; and accept coarser/absent mtimes rather than
erroring out.&lt;/li&gt;
&lt;li&gt;Skip the &lt;code&gt;total N&lt;/code&gt; first line.&lt;/li&gt;
&lt;li&gt;Always synthesize a &lt;code&gt;..&lt;/code&gt; entry for navigation (unless at &lt;code&gt;/&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Detect directories from the leading &lt;code&gt;d&lt;/code&gt; in the mode string.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Pull (pod → local), metadata-preserving&lt;/h3&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;kubectl exec &amp;lt;pod&amp;gt; [-c &amp;lt;container&amp;gt;] -- tar cf - -C &amp;lt;remoteParent&amp;gt; &amp;lt;remoteBase&amp;gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;| tar xpf - --no-same-owner -C &amp;lt;localDest&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tar c&lt;/code&gt; on the remote side, piped to &lt;code&gt;tar xp&lt;/code&gt; locally (&lt;code&gt;-p&lt;/code&gt; preserves mode +
mtime). &lt;code&gt;--no-same-owner&lt;/code&gt; is the default for pulling — see “tar flags &amp;amp;
ownership” below for why.&lt;/li&gt;
&lt;li&gt;Run the local &lt;code&gt;tar&lt;/code&gt; via &lt;code&gt;exec.Command&lt;/code&gt; and connect the kubectl stdout to its
stdin with an &lt;code&gt;io.Pipe&lt;/code&gt; (or &lt;code&gt;cmd.StdoutPipe()&lt;/code&gt; → &lt;code&gt;cmd2.Stdin&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Wrap the pipe in a counting &lt;code&gt;io.Reader&lt;/code&gt; to drive the &lt;code&gt;progress&lt;/code&gt; callback.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Push (local → pod), metadata-preserving&lt;/h3&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;tar cf - -C &amp;lt;localParent&amp;gt; &amp;lt;localBase&amp;gt; \&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;| kubectl exec -i &amp;lt;pod&amp;gt; [-c &amp;lt;container&amp;gt;] -- tar xpf - --no-same-owner -C &amp;lt;remoteDest&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;Note the &lt;code&gt;-i&lt;/code&gt; on &lt;code&gt;kubectl exec&lt;/code&gt; so stdin is forwarded.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--no-same-owner&lt;/code&gt; again by default — in a rootless container the extract
cannot chown anyway (see below); this makes the intent explicit and avoids
warnings.&lt;/li&gt;
&lt;li&gt;Same counting-reader trick for progress.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;tar flags &amp;amp; ownership&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Mode bits and mtime are reliably preserved without privilege. Owner UID/GID
is not — treat it as best-effort.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;When &lt;code&gt;tar x&lt;/code&gt; runs without &lt;code&gt;CAP_CHOWN&lt;/code&gt; (extracting on your local machine as a
normal user, or inside a rootless pod), the &lt;code&gt;chown()&lt;/code&gt; calls fail with &lt;code&gt;EPERM&lt;/code&gt;.
GNU tar’s default for a non-root extract is to &lt;em&gt;silently drop&lt;/em&gt; ownership restore
and create files owned by the extracting user — it does &lt;strong&gt;not&lt;/strong&gt; hard-fail. So a
blanket &lt;code&gt;--numeric-owner&lt;/code&gt; on extract buys nothing in the common case: it only
controls &lt;em&gt;how&lt;/em&gt; a UID is chosen (by number vs. name lookup), not whether tar is
&lt;em&gt;allowed&lt;/em&gt; to apply it.&lt;/p&gt;&lt;p&gt;Defaults, therefore:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Create side:&lt;/strong&gt; &lt;code&gt;tar --numeric-owner -cf - ...&lt;/code&gt;
Numeric is harmless here and avoids name-lookup surprises when packing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Extract side (default):&lt;/strong&gt; &lt;code&gt;tar -xpf - --no-same-owner ...&lt;/code&gt;
Preserves mode + mtime, and explicitly tells tar not to attempt chown. This is
the right default for both directions:&lt;/li&gt;
&lt;li&gt;Pulling to local: you almost never want the pod’s UIDs applied on your
machine anyway (UID 1000 in the pod ≠ you).&lt;/li&gt;
&lt;li&gt;Pushing to a rootless pod: the chown would no-op regardless, so don’t pretend
otherwise.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Opt-in ownership preservation:&lt;/strong&gt; add a &lt;code&gt;--preserve-ownership&lt;/code&gt; flag to &lt;code&gt;k8tc&lt;/code&gt;.
When set, use &lt;code&gt;tar --same-owner --numeric-owner -xpf - ...&lt;/code&gt; on the extract side.
This only does anything useful when the extracting end is privileged (root in
the container, or root locally); otherwise it degrades to the same best-effort
behavior. Document this clearly so users aren’t surprised when UIDs don’t carry
across into a rootless target.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What actually hard-fails&lt;/strong&gt; is unrelated to ownership: writing into a directory
you lack write permission for, or a restored directory mode that locks tar out
mid-extract. Those surface as &lt;code&gt;EPERM&lt;/code&gt;/&lt;code&gt;EACCES&lt;/code&gt; on the file ops themselves and
should be reported per-transfer (see Error Handling).&lt;/p&gt;&lt;hr&gt;&lt;h2&gt;TUI Behavior&lt;/h2&gt;&lt;h3&gt;Layout&lt;/h3&gt;&lt;p&gt;Two equal-width panels filling the terminal, a header line, and a footer/status
line.&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;┌─ LOCAL: /home/user/project ──┐┌─ POD nginx-abc:/var/www ──────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│ ..                           ││ ..                             │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│ &amp;gt; src/                       ││   index.html                   │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   README.md                  ││   assets/                      │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│   go.mod                     ││                                │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;│                              ││                                │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;└──────────────────────────────┘└────────────────────────────────┘&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Tab: switch  ↑↓: move  ⏎: open  F5: copy  q: quit      [status...]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;focused&lt;/strong&gt; panel has a highlighted border; the cursor row is highlighted.&lt;/li&gt;
&lt;li&gt;Each panel maintains its own &lt;code&gt;cwd&lt;/code&gt;, file list, cursor index, and scroll
offset.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Keybindings&lt;/h3&gt;




































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Key&lt;/th&gt;&lt;th&gt;Action&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Tab&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Switch focus between local and remote panel&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;↑&lt;/code&gt; / &lt;code&gt;↓&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Move cursor&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;PgUp/PgDn&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Page cursor&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;Enter&lt;/code&gt;&lt;/td&gt;&lt;td&gt;If dir: descend; if &lt;code&gt;..&lt;/code&gt;: go up; if file: no-op (v1)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;F5&lt;/code&gt; / &lt;code&gt;c&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Copy highlighted entry from focused panel → other panel’s cwd&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;r&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Refresh focused panel&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;q&lt;/code&gt; / &lt;code&gt;Ctrl+C&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Quit&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;Async transfers&lt;/h3&gt;&lt;p&gt;Transfers must not block the event loop. Use the Bubble Tea pattern:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;On &lt;code&gt;F5&lt;/code&gt;, dispatch a &lt;code&gt;tea.Cmd&lt;/code&gt; that runs the &lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; in a goroutine and
returns a &lt;code&gt;transferDoneMsg{err}&lt;/code&gt; (and intermediate &lt;code&gt;transferProgressMsg{n}&lt;/code&gt;
via a channel + &lt;code&gt;tea.Tick&lt;/code&gt; or a custom message pump).&lt;/li&gt;
&lt;li&gt;While in flight, show progress/byte-count in the status line and disable
further copy actions.&lt;/li&gt;
&lt;li&gt;On completion, refresh the destination panel and clear status.&lt;/li&gt;
&lt;/ul&gt;&lt;hr&gt;&lt;h2&gt;CLI&lt;/h2&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;k8tc --pod &amp;lt;name&amp;gt; [--namespace &amp;lt;ns&amp;gt;] [--container &amp;lt;name&amp;gt;] [--remote-path &amp;lt;path&amp;gt;] [--local-path &amp;lt;path&amp;gt;]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--pod&lt;/code&gt; (required for v1)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--namespace&lt;/code&gt; / &lt;code&gt;-n&lt;/code&gt; → passed through as &lt;code&gt;kubectl -n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--container&lt;/code&gt; / &lt;code&gt;-c&lt;/code&gt; → passed through as &lt;code&gt;kubectl exec -c&lt;/code&gt;; if omitted, let
kubectl pick the default container&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--remote-path&lt;/code&gt; initial remote dir (default &lt;code&gt;/&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--local-path&lt;/code&gt; initial local dir (default &lt;code&gt;.&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--preserve-ownership&lt;/code&gt; attempt to restore owner UID/GID on extract
(&lt;code&gt;--same-owner --numeric-owner&lt;/code&gt;). Off by default; only effective when the
extracting end is privileged. See “tar flags &amp;amp; ownership.”&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;(Stretch: a pod picker if &lt;code&gt;--pod&lt;/code&gt; is omitted, via &lt;code&gt;kubectl get pods -o json&lt;/code&gt;.)&lt;/p&gt;&lt;hr&gt;&lt;h2&gt;Error Handling &amp;amp; Edge Cases&lt;/h2&gt;&lt;p&gt;The agent must handle these explicitly, surfacing errors in the status line
rather than crashing:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;kubectl&lt;/code&gt; not found on PATH&lt;/strong&gt; → fail fast at startup with a clear message.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;tar&lt;/code&gt; missing in the pod&lt;/strong&gt; (distroless/scratch images) → detect the exec
failure and show: “pod has no &lt;code&gt;tar&lt;/code&gt;; cannot transfer.” Do &lt;strong&gt;not&lt;/strong&gt; hang.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-container pod with no &lt;code&gt;--container&lt;/code&gt;&lt;/strong&gt; → kubectl will error; surface
its message and hint to pass &lt;code&gt;-c&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Permission denied&lt;/strong&gt; on read (local or remote) → show per-transfer error,
keep the UI alive.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;BusyBox &lt;code&gt;ls&lt;/code&gt;&lt;/strong&gt; lacking &lt;code&gt;--full-time&lt;/code&gt; → fall back gracefully (see Listing).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Broken pipe / context cancel&lt;/strong&gt; mid-transfer → clean up both processes
(&lt;code&gt;CommandContext&lt;/code&gt; + &lt;code&gt;cmd.Wait()&lt;/code&gt; on both ends; kill the partner on failure).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Empty directories&lt;/strong&gt; and the root &lt;code&gt;/&lt;/code&gt; (no &lt;code&gt;..&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Large files&lt;/strong&gt; → never read fully into memory; always stream.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Spaces / special chars in paths&lt;/strong&gt; → pass paths as separate &lt;code&gt;exec.Command&lt;/code&gt;
args (no shell string interpolation); when piping two &lt;code&gt;exec.Cmd&lt;/code&gt;s, do it in
Go via pipes, not via a &lt;code&gt;sh -c &quot;... | ...&quot;&lt;/code&gt; string.&lt;/li&gt;
&lt;/ol&gt;&lt;hr&gt;&lt;h2&gt;Suggested Build Order (milestones)&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Transfer interface + kubectl &lt;code&gt;List&lt;/code&gt;.&lt;/strong&gt; CLI prints a remote &lt;code&gt;ls&lt;/code&gt;. Verify
parsing against a real pod.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Local &lt;code&gt;List&lt;/code&gt;.&lt;/strong&gt; Mirror the same &lt;code&gt;FileInfo&lt;/code&gt; for the local FS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Static two-panel render&lt;/strong&gt; (Lip Gloss) with both panels populated, no
interaction.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Navigation:&lt;/strong&gt; focus switching, cursor movement, &lt;code&gt;Enter&lt;/code&gt; to descend/ascend,
scroll offset, refresh.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Pull&lt;/code&gt; (pod → local)&lt;/strong&gt; synchronous first, then move it onto the async
&lt;code&gt;tea.Cmd&lt;/code&gt; pattern with a status line.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Push&lt;/code&gt; (local → pod)&lt;/strong&gt; same shape as Pull.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Progress reporting&lt;/strong&gt; via counting reader → status line.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Edge-case hardening&lt;/strong&gt; from the list above (tar-missing, busybox ls,
cancellation).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Polish:&lt;/strong&gt; styling, help footer, &lt;code&gt;--namespace&lt;/code&gt;/&lt;code&gt;--container&lt;/code&gt; plumbing.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Milestones 1–6 are the usable prototype. 7–9 are the path to “done.”&lt;/p&gt;&lt;hr&gt;&lt;h2&gt;Acceptance Criteria&lt;/h2&gt;&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt; Launches with &lt;code&gt;k8tc --pod &amp;lt;p&amp;gt;&lt;/code&gt; and shows local + remote panels.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; Tab switches focus; arrows + Enter navigate both filesystems.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; F5 copies the highlighted file &lt;strong&gt;or directory&lt;/strong&gt; in the focused panel into
the other panel’s current directory.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; Transferred files retain original mtime and permission (mode) bits
(verify with &lt;code&gt;stat&lt;/code&gt; on both ends). Owner UID/GID is best-effort: preserved
only with &lt;code&gt;--preserve-ownership&lt;/code&gt; against a privileged extract target.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; Directory transfers are recursive and also preserve metadata.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; A transfer of a large file does not freeze the UI and shows progress.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; Missing &lt;code&gt;tar&lt;/code&gt; in the pod produces a clear error, not a hang or panic.&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt; Builds to a single static binary: &lt;code&gt;CGO_ENABLED=0 go build&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;hr&gt;&lt;h2&gt;Future (post-v1, do not build now)&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Swap the kubectl-backed &lt;code&gt;Transfer&lt;/code&gt; for a &lt;code&gt;client-go&lt;/code&gt; implementation
(exec via &lt;code&gt;remotecommand&lt;/code&gt; SPDY) to drop the &lt;code&gt;kubectl&lt;/code&gt; runtime dependency.&lt;/li&gt;
&lt;li&gt;Pod/namespace picker UI.&lt;/li&gt;
&lt;li&gt;Multi-select and queued transfers.&lt;/li&gt;
&lt;li&gt;File preview / view pane.&lt;/li&gt;
&lt;li&gt;Delete / rename / mkdir operations.&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;p&gt;The main takeaway here is not to start the implementation in the chat. That’s the entirely wrong environment. Get a &lt;strong&gt;PLAN artifact&lt;/strong&gt; and take it to the code environment.&lt;/p&gt;
&lt;h2&gt;Step 2: Initial Implementation&lt;/h2&gt;
&lt;p&gt;It was time to move to Claude Code. I run Claude in a &lt;a href=&quot;https://gist.github.com/splitbrain/5b20b82abfcd874c0b5b6ed22cb40443&quot;&gt;custom sandbox&lt;/a&gt; using bubblewrap on Linux. This allows me to &lt;strong&gt;safely run in &lt;code&gt;auto&lt;/code&gt; mode&lt;/strong&gt;, which means Claude is running mostly autonomously with an LLM classifier as the only safeguard.&lt;/p&gt;
&lt;p&gt;In this concrete example, the sandbox prevented Claude from accessing my kubectl config and thus from running kubectl commands against our cluster unchecked.&lt;/p&gt;
&lt;p&gt;I added the &lt;code&gt;PLAN.md&lt;/code&gt; to a new repository and let Claude one-shot the initial implementation.&lt;/p&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;read @PLAN.md and implement it&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;About 20 minutes later, Claude reported that it was done. Time to give the tool a quick test.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.cosmocode.de/en/_astro/k8tc-initial.CWqxJFxk_Z22WC5H.webp&quot; alt=&quot;Initial implementation&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1145&quot; height=&quot;674&quot;&gt;&lt;/p&gt;
&lt;p&gt;It worked just as specified ✨️. I could have stopped here if this were an one-off tool.&lt;/p&gt;
&lt;h2&gt;Step n: Review&lt;/h2&gt;
&lt;p&gt;Before I decided to add more features, I wanted to review the code.&lt;/p&gt;
&lt;p&gt;Another reason why I decided to use Go is that the code is usually more straightforward and easier to review than Python or Rust. Go tends to have only one way to do things, which makes it easier for the agent to generate code that is correct and idiomatic. And that in turn makes it easier for me to review the code and understand what it does.&lt;/p&gt;
&lt;p&gt;When vibe engineering, I mostly &lt;strong&gt;look at architectural decisions and code structure&lt;/strong&gt;. I don’t want to nitpick every line of code, but I want to make sure that the overall design makes sense and that the code is organized in a way that is maintainable.&lt;/p&gt;
&lt;p&gt;As an example, here is the review session I had with Claude right after the initial implementation.&lt;/p&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;Let’s review the current state. I see that we have a FileInfo struct and a Transfer interface. The comment says that this only covers the remote side and that the local side does not use the interface. But then looking at local.go it uses transfer.FileInot and transfer.Sort so it seems the two sides are not that different?&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude gives an explanation that doesn’t fully satisfy me&lt;/summary&gt;&lt;div&gt;&lt;p&gt;I read all four files. Here’s what’s actually going on — the tension you spotted is real but it’s conflating two different things that live in the &lt;code&gt;transf er&lt;/code&gt; package.&lt;/p&gt;&lt;h2&gt;There are two separate things in &lt;code&gt;transfer.go&lt;/code&gt;&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;A shared data layer&lt;/strong&gt; — the &lt;code&gt;FileInfo&lt;/code&gt; struct (transfer.go:15) and the &lt;code&gt;Sort&lt;/code&gt; helper (transfer.go:40). Both panels use these, by design. That’s why &lt;code&gt; FileInfo&lt;/code&gt;’s own comment says “on either the local or the remote side.”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code&gt;Transfer&lt;/code&gt; interface&lt;/strong&gt; — &lt;code&gt;List&lt;/code&gt;/&lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; (transfer.go:25). &lt;em&gt;This&lt;/em&gt; is what the local side doesn’t use.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;The comment at transfer.go:23-24 is talking strictly about #2. And it’s literally accurate: the local panel calls &lt;code&gt;local.List(p)&lt;/code&gt; — a plain package functi
on (model.go:109) — whereas the remote panel dispatches through the interface, &lt;code&gt;t.List(...)&lt;/code&gt; (model.go:111). So when the comment says “does not go through
this interface,” it means local doesn’t implement the &lt;code&gt;List/Pull/Push&lt;/code&gt; &lt;em&gt;method set&lt;/em&gt;, not that local is walled off from the package.&lt;/p&gt;&lt;p&gt;So your instinct is &lt;strong&gt;half right&lt;/strong&gt;: the &lt;em&gt;display&lt;/em&gt; side is barely different (shared types + shared sort), but the &lt;em&gt;transfer&lt;/em&gt; side is fundamentally asymmetr
ic.&lt;/p&gt;&lt;h2&gt;Why local isn’t behind the interface&lt;/h2&gt;&lt;p&gt;Two reasons, and the second is the deeper one:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nothing to swap.&lt;/strong&gt; The package doc says the interface exists “so the kubectl implementation can later be swapped for a client-go one.” The local files
ystem has no such alternative — it’s always &lt;code&gt;os.ReadDir&lt;/code&gt;. An interface with exactly one possible implementation is just ceremony.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The local side has no &lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; of its own.&lt;/strong&gt; Look at the signatures: &lt;code&gt;Pull(pod, container, remotePath, localPath, ...)&lt;/code&gt; and &lt;code&gt;Push(pod, container,  localPath, remotePath, ...)&lt;/code&gt; — the &lt;code&gt;Kubectl&lt;/code&gt; value &lt;em&gt;already straddles both ends&lt;/em&gt;; it reads/writes local paths itself (it’s the local &lt;code&gt;tar&lt;/code&gt; process in &lt;code&gt;pi pe&lt;/code&gt;). So &lt;code&gt;Transfer&lt;/code&gt; isn’t really “the remote filesystem” — it’s “the thing that bridges local↔remote.” The only purely-local operation is &lt;em&gt;listing a direc
tory&lt;/em&gt;, and that’s a one-liner over &lt;code&gt;os.ReadDir&lt;/code&gt;. There’s no “local Transfer” concept to even abstract.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;That’s the real answer to “are the two sides that different?”: for browsing, no; for transferring, there is no local side — it’s subsumed into &lt;code&gt;Kubectl&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;Two minor warts worth noting in the review&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;FileInfo&lt;/code&gt;/&lt;code&gt;Sort&lt;/code&gt; live in the package named after the remote side&lt;/strong&gt;, yet are used by both. It’s pragmatic (local imports transfer, not vice versa), but it’s why the comment has to keep clarifying “this is also used locally.” If you wanted stricter cohesion you’d hoist &lt;code&gt;FileInfo&lt;/code&gt;+&lt;code&gt;Sort&lt;/code&gt; into a small shared package (e.g. &lt;code&gt;fileinfo&lt;/code&gt;) that both &lt;code&gt;transfer&lt;/code&gt; and &lt;code&gt;local&lt;/code&gt; import — but that’s arguably over-engineering for two callers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The &lt;code&gt;..&lt;/code&gt;/root-synthesis logic is duplicated&lt;/strong&gt; — local.go:36-38 vs kubectl.go:139-141. The duplication is &lt;em&gt;justified&lt;/em&gt;: local uses &lt;code&gt;filepath&lt;/code&gt; (OS separators) and remote uses &lt;code&gt;path&lt;/code&gt; (always &lt;code&gt;/&lt;/code&gt;, inside a Linux pod), so they can’t trivially share it. But it’s worth a one-line comment on each noting the deliberate split, since they’ll need to stay in sync.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;If you want, I can tighten the interface comment to say “the &lt;code&gt;List&lt;/code&gt;/&lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; &lt;em&gt;method set&lt;/em&gt;” instead of “this interface” (to kill the ambiguity you hit), or sketch the &lt;code&gt;fileinfo&lt;/code&gt; extraction so you can judge whether it’s worth it. Which direction do you want to take?&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;I feel like if there are two concerns (transfer and file representation) then the two should be separated. It would make it less weird that local reuses the file representation then&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude refactors and mentions another issue&lt;/summary&gt;&lt;div&gt;&lt;h2&gt;Decisions I made&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Renamed &lt;code&gt;FileInfo&lt;/code&gt; → &lt;code&gt;file.Info&lt;/code&gt;.&lt;/strong&gt; &lt;code&gt;file.FileInfo&lt;/code&gt; would stutter; &lt;code&gt;file.Info&lt;/code&gt; is the idiomatic Go form. &lt;code&gt;Sort&lt;/code&gt; keeps its name (&lt;code&gt;file.Sort&lt;/code&gt;). If you’d
rather preserve the &lt;code&gt;FileInfo&lt;/code&gt; name, say so and I’ll rename — it’s a mechanical change.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Reworded the &lt;code&gt;Transfer&lt;/code&gt; doc comment&lt;/strong&gt; to describe it as a local↔remote &lt;em&gt;bridge&lt;/em&gt; (List reads the pod; Pull/Push move trees between pod and disk), which
is the accurate framing we landed on in the previous discussion — and it no longer needs to awkwardly disclaim the shared type, since the type now visibl
y lives in its own package.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Still untouched (deliberately)&lt;/h2&gt;&lt;p&gt;The &lt;code&gt;..&lt;/code&gt;/root-synthesis duplication between &lt;code&gt;local.List&lt;/code&gt; and &lt;code&gt;parseLS&lt;/code&gt; is still there — that’s the &lt;code&gt;filepath&lt;/code&gt;-vs-&lt;code&gt;path&lt;/code&gt; split we discussed, and it’s ortho
gonal to this refactor. &lt;code&gt;file&lt;/code&gt; would be the natural home for a shared helper if you ever want to collapse it, but I left it alone since it’d need the sepa
rator parameterized. Want me to tackle that too?&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;I don’t remember discussing filepath-vs-path - what’s that about?&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude explains the issue and recommends to ignore it&lt;/summary&gt;&lt;div&gt;&lt;p&gt;Fair — I overstated it as “discussed.” It was a one-line aside in my earlier review, not something we actually worked through. Here’s what I meant.&lt;/p&gt;&lt;p&gt;It’s about two different standard-library packages in Go:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;path&lt;/code&gt;&lt;/strong&gt; — manipulates always-slash-separated paths (&lt;code&gt;/&lt;/code&gt;). It’s what you use for URLs and anything that is &lt;em&gt;defined&lt;/em&gt; to use forward slashes regardless of the host OS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;path/filepath&lt;/code&gt;&lt;/strong&gt; — manipulates paths using the &lt;em&gt;host OS’s&lt;/em&gt; rules: &lt;code&gt;/&lt;/code&gt; on Linux/macOS, &lt;code&gt;\&lt;/code&gt; on Windows.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;In k8tc the two panels live on different sides of that line:&lt;/p&gt;&lt;p&gt;The &lt;strong&gt;local&lt;/strong&gt; panel walks the filesystem of whatever machine k8tc runs on, so it correctly uses &lt;code&gt;filepath&lt;/code&gt;:&lt;/p&gt;&lt;p&gt;That last grep is the clearest illustration: &lt;code&gt;kubectl.go&lt;/code&gt; uses &lt;strong&gt;both&lt;/strong&gt; packages, deliberately. The remote (pod) side uses &lt;code&gt;path&lt;/code&gt; (lines 141, 149–150) and the local side of the very same transfer uses &lt;code&gt;filepath&lt;/code&gt; (lines 158–159).&lt;/p&gt;&lt;p&gt;The reason: a pod is a Linux container, so its filesystem paths are &lt;em&gt;always&lt;/em&gt; &lt;code&gt;/&lt;/code&gt;-separated, no matter what OS k8tc itself is running on. If you used &lt;code&gt;filepath&lt;/code&gt; on a pod path while running k8tc on Windows, you’d get backslash semantics applied to a path that is genuinely slash-based — wrong. So pod paths must go through &lt;code&gt;path&lt;/code&gt;; host paths must go through &lt;code&gt;filepath&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Now, the &lt;code&gt;..&lt;/code&gt;-synthesis duplication I flagged. The two snippets are:&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// local.go:36 — host filesystem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; filepath.&lt;/span&gt;&lt;span&gt;Clean&lt;/span&gt;&lt;span&gt;(dir) &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;(filepath.Separator) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// kubectl.go:141 — pod filesystem&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; path.&lt;/span&gt;&lt;span&gt;Clean&lt;/span&gt;&lt;span&gt;(dir) &lt;/span&gt;&lt;span&gt;!=&lt;/span&gt;&lt;span&gt; &quot;/&quot;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;They’re structurally identical (“if this isn’t the root, prepend a &lt;code&gt;..&lt;/code&gt; entry”), but they differ in exactly the two spots where the path-flavor matters:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;which &lt;code&gt;Clean&lt;/code&gt;&lt;/strong&gt; — OS-aware vs. always-slash&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;what counts as root&lt;/strong&gt; — &lt;code&gt;string(filepath.Separator)&lt;/code&gt; (the host’s root) vs. the literal &lt;code&gt;&quot;/&quot;&lt;/code&gt; (the pod’s root)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So you &lt;em&gt;can’t&lt;/em&gt; just lift the snippet into one shared function and call it from both sides — you’d have to parameterize it with “which path semantics,” e.g. pass in the clean-func and the root sentinel. That’s why I called the duplication “justified”: collapsing it would trade two obvious 3-line blocks for one indirection-laden helper, and arguably make it &lt;em&gt;less&lt;/em&gt; clear that one side is host-pathed and the other is pod-pathed.&lt;/p&gt;&lt;p&gt;So nothing for you to do here — I just wanted to flag that the duplication is intentional, not an oversight, in case it caught your eye during review. It’s unrelated to the &lt;code&gt;file&lt;/code&gt; extraction we just did.&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;Hmm to me it sound like local and remote should implement at least Transfer.List (don’t implement, discuss)&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude suggests different ways to address the issue&lt;/summary&gt;&lt;div&gt;&lt;p&gt;Good instinct — and it points at a real seam. Let me lay out the case for and against, because there’s a genuine obstacle that’s worth seeing clearly. First let me confirm one thing the argument hinges on:&lt;/p&gt;&lt;p&gt;Confirmed what I needed: &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; are set once in &lt;code&gt;New&lt;/code&gt; (model.go:66–67) and only ever read after that. They’re &lt;strong&gt;session-constant&lt;/strong&gt;, yet they’re threaded as arguments into every single &lt;code&gt;List&lt;/code&gt;/&lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; call. That detail is the whole crux of your suggestion. Here’s the discussion.&lt;/p&gt;&lt;h2&gt;Your instinct is right — for &lt;code&gt;List&lt;/code&gt; specifically&lt;/h2&gt;&lt;p&gt;The two operations in &lt;code&gt;Transfer&lt;/code&gt; have fundamentally different &lt;em&gt;shapes&lt;/em&gt;:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;List&lt;/code&gt;&lt;/strong&gt; is &lt;strong&gt;symmetric and one-sided&lt;/strong&gt;: &lt;code&gt;(path) → []file.Info&lt;/code&gt;. Both panels do &lt;em&gt;exactly&lt;/em&gt; this. There’s nothing pod-specific about the operation itself — “read a directory, give me the entries.”&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt;&lt;/strong&gt; are &lt;strong&gt;asymmetric and two-sided&lt;/strong&gt;: they move a tree &lt;em&gt;across&lt;/em&gt; the local↔pod boundary. There is no “local Pull”; the kubectl process is inherently both ends at once. These genuinely belong only to the bridge.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;So &lt;code&gt;Transfer&lt;/code&gt; today actually bundles two responsibilities — &lt;em&gt;browsing&lt;/em&gt; and &lt;em&gt;moving&lt;/em&gt; — and you’ve spotted that browsing is the half that’s symmetric. This is the same kind of cut we just made pulling &lt;code&gt;file&lt;/code&gt; out: separate the thing that’s shared from the thing that isn’t.&lt;/p&gt;&lt;h2&gt;The obstacle: the signature carries &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;Why local &lt;em&gt;can’t&lt;/em&gt; satisfy &lt;code&gt;Transfer.List&lt;/code&gt; as written:&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;Kubectl: &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;(pod, container, path &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;) ([]file.Info, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)   &lt;/span&gt;&lt;span&gt;// 3 path-ish args&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;local:   &lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;(path &lt;/span&gt;&lt;span&gt;string&lt;/span&gt;&lt;span&gt;)                 ([]file.Info, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)   &lt;/span&gt;&lt;span&gt;// 1&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The local side has no pod or container, so it can’t match. But — as the grep above shows — &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; are session-constant. They don’t &lt;em&gt;need&lt;/em&gt; to be per-call args; they’re only per-call because the interface made them so. Bind them once and the signatures converge:&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;type&lt;/span&gt;&lt;span&gt; Lister&lt;/span&gt;&lt;span&gt; interface&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    List&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;path&lt;/span&gt;&lt;span&gt; string&lt;/span&gt;&lt;span&gt;) ([]&lt;/span&gt;&lt;span&gt;file&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Info&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;local&lt;/strong&gt;: a zero-field &lt;code&gt;local.FS{}&lt;/code&gt; whose &lt;code&gt;List(path)&lt;/code&gt; wraps today’s &lt;code&gt;local.List&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;remote&lt;/strong&gt;: a tiny adapter holding &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt;, whose &lt;code&gt;List(path)&lt;/code&gt; calls &lt;code&gt;kubectl.List(pod, container, path)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;What it buys, concretely&lt;/h2&gt;&lt;p&gt;&lt;code&gt;loadPanel&lt;/code&gt; loses its &lt;code&gt;which == focusLocal&lt;/code&gt; fork (model.go:108–112):&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// before&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; which &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; focusLocal {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    files, err &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; local.&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;(p)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;} &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;    files, err &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; t.&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;(pod, container, p)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;// after — each Panel owns its own lister&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;files, err &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; m.&lt;/span&gt;&lt;span&gt;panelPtr&lt;/span&gt;&lt;span&gt;(which).lister.&lt;/span&gt;&lt;span&gt;List&lt;/span&gt;&lt;span&gt;(p)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each &lt;code&gt;Panel&lt;/code&gt; becomes self-sufficient: it knows how to load &lt;em&gt;itself&lt;/em&gt;, and the Model stops caring whether a panel is local or remote when listing. That’s a real improvement in the model’s coherence, and it makes test fakes trivial — a &lt;code&gt;Lister&lt;/code&gt; fake is one method, versus today’s &lt;code&gt;fakeTransfer&lt;/code&gt; that must stub &lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; even for a listing test.&lt;/p&gt;&lt;h2&gt;Where I’d put the interface&lt;/h2&gt;&lt;p&gt;The idiomatic Go move: &lt;strong&gt;define &lt;code&gt;Lister&lt;/code&gt; in the consumer (&lt;code&gt;ui&lt;/code&gt;), not the producer.&lt;/strong&gt; Then &lt;code&gt;local.FS&lt;/code&gt; satisfies it structurally without importing anything, and &lt;code&gt;local&lt;/code&gt; stays fully decoupled (no &lt;code&gt;transfer&lt;/code&gt; import — which we just worked to remove). The remote adapter can live in &lt;code&gt;ui&lt;/code&gt; too. &lt;code&gt;transfer.Transfer&lt;/code&gt; keeps &lt;code&gt;List&lt;/code&gt; as the &lt;em&gt;backend&lt;/em&gt; capability (the future client-go backend must still list), and the adapter just curries &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; onto it.&lt;/p&gt;&lt;h2&gt;Two honest caveats&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;It doesn’t unify everything.&lt;/strong&gt; &lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; stay asymmetric and the push-vs-pull decision stays in the UI (model.go:289/292). The &lt;code&gt;Lister&lt;/code&gt; cut only simplifies &lt;em&gt;browsing&lt;/em&gt;. That’s fine — but don’t expect it to collapse the transfer logic.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;It doesn’t touch the &lt;code&gt;..&lt;/code&gt;/&lt;code&gt;filepath&lt;/code&gt;-vs-&lt;code&gt;path&lt;/code&gt; duplication.&lt;/strong&gt; Each side’s &lt;code&gt;List&lt;/code&gt; still synthesizes &lt;code&gt;..&lt;/code&gt; its own way. Orthogonal to this.&lt;/li&gt;
&lt;/ol&gt;&lt;h2&gt;My recommendation&lt;/h2&gt;&lt;p&gt;Worth doing, at the &lt;strong&gt;lightweight&lt;/strong&gt; end: introduce a consumer-side &lt;code&gt;Lister&lt;/code&gt;, adapt both sides, give each &lt;code&gt;Panel&lt;/code&gt; its own. It’s contained, reversible, and improves the conceptual model.&lt;/p&gt;&lt;p&gt;I’d &lt;em&gt;stop short&lt;/em&gt; of the maximal version (ripping &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; out of the &lt;code&gt;Transfer&lt;/code&gt; interface entirely and binding them at &lt;code&gt;Kubectl&lt;/code&gt; construction). That’s arguably “more correct” — it’d kill the per-call threading on &lt;code&gt;Pull&lt;/code&gt;/&lt;code&gt;Push&lt;/code&gt; too — but it turns &lt;code&gt;Kubectl&lt;/code&gt; from a reusable engine into a session-scoped object, and the blast radius is much larger for a payoff that’s mostly aesthetic.&lt;/p&gt;&lt;p&gt;The deciding question is really: do you want each &lt;code&gt;Panel&lt;/code&gt; to “own how it lists itself”? If yes, the &lt;code&gt;Lister&lt;/code&gt; is the clean expression of that. If the 6-line branch in &lt;code&gt;loadPanel&lt;/code&gt; doesn’t bother you, the status quo is defensible too — the asymmetry it encodes (only the remote side is swappable) is real.&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;TBH your “maximal version” sounds more correct. I feel like there are distinct responsibilities. A kubernetes package which wraps around kubectl and handling the tar commands. A ls parser (used probably remotely only). A Transfer manager that implements the push/pull mechanism. And remote/local implementations of the same “virtual” file system list. Would you agree?&lt;/p&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-claude&quot;&gt;&lt;details&gt;&lt;summary&gt;Claude comes up with a detailed proposal for what I suggested&lt;/summary&gt;&lt;div&gt;&lt;p&gt;Yes — broadly I agree. Those are real, separable responsibilities, and the fact that you can name them this cleanly is a good sign the seams are real and
not invented. But I’d refine &lt;em&gt;one&lt;/em&gt; of your four boundaries, and in doing so I think the decomposition gets sharper than what you sketched. Let me give you the version I’d actually defend.&lt;/p&gt;&lt;h2&gt;The dependency graph I’d aim for&lt;/h2&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;plaintext&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;file        Info + Sort                                    (done; depends on nothing)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ▲   ▲&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  │   └──────────────┐&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;parser              local Lister        kube      ← the swap seam&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;(ls -la → []Info)   (os.ReadDir)         ▲  ▲&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  ▲                                      │  │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;  └────── remote Lister ─────────────────┘  │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;          (ls via kube + parse)             │&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                  transfer (Pull/Push)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;line&quot;&gt;&lt;span&gt;                                  (tar streaming over kube)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;file&lt;/code&gt;&lt;/strong&gt; — representation. Done.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;kube&lt;/code&gt;&lt;/strong&gt; — the exec/stream primitive: “run this command in this pod/container, give me stdin/stdout/stderr.” Holds the bound &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;container&lt;/code&gt; (killing the per-call threading you spotted). Knows nothing about tar, ls, or &lt;code&gt;file.Info&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;parser&lt;/strong&gt; — pure &lt;code&gt;[]byte → []file.Info&lt;/code&gt;. Remote-only, as you said (locally &lt;code&gt;os.ReadDir&lt;/code&gt; already hands back structured entries; nothing to parse).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;two Listers&lt;/strong&gt; — local (&lt;code&gt;os.ReadDir&lt;/code&gt;) and remote (&lt;code&gt;kube&lt;/code&gt; + parser), both satisfying one &lt;code&gt;List(path) → []file.Info&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;transfer&lt;/code&gt;&lt;/strong&gt; — the Pull/Push manager: tar create/extract + the streaming pipe, using &lt;code&gt;kube&lt;/code&gt; for the remote endpoint and local &lt;code&gt;exec&lt;/code&gt; for the local one.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;No cycles, clean DAG. Each node has an independent test story — and notably the tests you &lt;em&gt;already have&lt;/em&gt; fall out naturally: &lt;code&gt;parse_test.go&lt;/code&gt; (pure parser), and &lt;code&gt;fakeKubectl&lt;/code&gt; (which makes the “pod” just the local fs) is really a test of the transfer streaming independent of real k8s.&lt;/p&gt;&lt;h2&gt;Where I’d push back: tar does &lt;em&gt;not&lt;/em&gt; belong in the &lt;code&gt;kube&lt;/code&gt; package&lt;/h2&gt;&lt;p&gt;You said the kubernetes package wraps kubectl &lt;em&gt;and&lt;/em&gt; the tar commands. I’d split those. Put &lt;strong&gt;only the exec/stream primitive&lt;/strong&gt; in &lt;code&gt;kube&lt;/code&gt;; keep &lt;strong&gt;tar&lt;/strong&gt; (createArgs/extractArgs/&lt;code&gt;pipe&lt;/code&gt;/classify) in the &lt;code&gt;transfer&lt;/code&gt; manager.&lt;/p&gt;&lt;p&gt;The reason is your own swappability rationale. The package doc promises “swap the kubectl implementation for a client-go one without touching the TUI.” The thing that differs between kubectl and client-go is &lt;em&gt;how you exec into a pod and get a byte stream&lt;/em&gt; — not tar. tar runs identically either way. So the swap seam is the exec primitive, and it must be tar-agnostic, or every transfer detail leaks across the seam. If &lt;code&gt;kube&lt;/code&gt; owns tar, you haven’t isolated the swappable part; you’ve just renamed &lt;code&gt;Kubectl&lt;/code&gt;.&lt;/p&gt;&lt;h2&gt;The non-obvious consequence — and why this is the version that makes the doc &lt;em&gt;true&lt;/em&gt;&lt;/h2&gt;&lt;p&gt;Here’s the part I think is the real payoff, and it’s hidden in &lt;code&gt;pipe&lt;/code&gt;:&lt;/p&gt;&lt;pre class=&quot;astro-code github-dark&quot; tabindex=&quot;0&quot; data-language=&quot;go&quot;&gt;&lt;code&gt;&lt;span class=&quot;line&quot;&gt;&lt;span&gt;func&lt;/span&gt;&lt;span&gt; pipe&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;src&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;dst&lt;/span&gt;&lt;span&gt; *&lt;/span&gt;&lt;span&gt;exec&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Cmd&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;progress&lt;/span&gt;&lt;span&gt; func&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;int64&lt;/span&gt;&lt;span&gt;)) &lt;/span&gt;&lt;span&gt;error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;pipe&lt;/code&gt; wires together &lt;strong&gt;two &lt;code&gt;*exec.Cmd&lt;/code&gt;&lt;/strong&gt;. That’s fine for kubectl (both endpoints are local processes — &lt;code&gt;kubectl exec …&lt;/code&gt; is itself a local process). But &lt;strong&gt;client-go does not give you an &lt;code&gt;*exec.Cmd&lt;/code&gt;&lt;/strong&gt; — it gives you a &lt;code&gt;remotecommand&lt;/code&gt; executor you hand &lt;code&gt;Stdin&lt;/code&gt;/&lt;code&gt;Stdout&lt;/code&gt;/&lt;code&gt;Stderr&lt;/code&gt; io streams. So today’s &lt;code&gt;Transfer&lt;/code&gt; interface &lt;em&gt;claims&lt;/em&gt; client-go swappability while its internals (two &lt;code&gt;*exec.Cmd&lt;/code&gt;) would actively fight it. The swappability is currently aspirational, not real.&lt;/p&gt;&lt;p&gt;The decomposition you’re proposing fixes exactly that — if the &lt;code&gt;kube&lt;/code&gt; seam is expressed as streams (&lt;code&gt;Run(cmd, stdin io.Reader, stdout, stderr io.Writer) error&lt;/code&gt;) rather than &lt;code&gt;*exec.Cmd&lt;/code&gt;, then &lt;code&gt;pipe&lt;/code&gt; connects two &lt;em&gt;stream endpoints&lt;/em&gt;, the local tar side is one impl, the pod side is another, and kubectl-vs-client-go becomes a true drop-in. So this isn’t just tidying — it’s the refactor that would make the package doc’s promise honest. That’s the strongest argument &lt;em&gt;for&lt;/em&gt; going maximal.&lt;/p&gt;&lt;h2&gt;Two cautions&lt;/h2&gt;&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Granularity.&lt;/strong&gt; Four responsibilities ≠ four packages. The parser is ~45 lines of pure code — I’d keep it as &lt;code&gt;parse.go&lt;/code&gt; &lt;em&gt;inside&lt;/em&gt; the remote-listing package with its existing test, not a package of its own. A package per function is its own smell. The boundaries that earn a package are &lt;code&gt;file&lt;/code&gt;, &lt;code&gt;kube&lt;/code&gt;, &lt;code&gt;local&lt;/code&gt;, &lt;code&gt;transfer&lt;/code&gt;, and the remote side; whether remote-List and Pull/Push are one “pod” package or two is a coin-flip I’d decide on cohesion (I lean: one &lt;code&gt;pod&lt;/code&gt;/&lt;code&gt;remote&lt;/code&gt; package exposing both, since they share the &lt;code&gt;kube&lt;/code&gt; client and the “pod-ness” — but your capability-split is defensible).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cost is front-loaded in &lt;code&gt;pipe&lt;/code&gt;.&lt;/strong&gt; Everything else (extract &lt;code&gt;kube&lt;/code&gt;, bind pod/container, add Listers) is mechanical and low-risk. Re-expressing &lt;code&gt;pipe&lt;/code&gt; around streams instead of &lt;code&gt;*exec.Cmd&lt;/code&gt; is the one genuinely fiddly change, and it only pays off the day someone actually writes the client-go backend. If that day is hypothetical, you can stop short: extract &lt;code&gt;kube&lt;/code&gt; as an &lt;code&gt;*exec.Cmd&lt;/code&gt; factory (still removes the threading, still separates concerns) and leave &lt;code&gt;pipe&lt;/code&gt; alone. You lose nothing you have today and can tighten the seam later.&lt;/li&gt;
&lt;/ol&gt;&lt;h2&gt;So, sequencing&lt;/h2&gt;&lt;p&gt;If you want to do this, I’d go in dependency order, each step independently shippable and green:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;Extract &lt;strong&gt;&lt;code&gt;kube&lt;/code&gt;&lt;/strong&gt; (exec primitive, pod/container bound) — removes the per-call threading.&lt;/li&gt;
&lt;li&gt;Introduce the &lt;strong&gt;&lt;code&gt;Lister&lt;/code&gt;&lt;/strong&gt; interface + local/remote impls — collapses the &lt;code&gt;loadPanel&lt;/code&gt; branch.&lt;/li&gt;
&lt;li&gt;Move &lt;strong&gt;&lt;code&gt;transfer&lt;/code&gt;&lt;/strong&gt; to Pull/Push-only on top of &lt;code&gt;kube&lt;/code&gt;; isolate the &lt;strong&gt;parser&lt;/strong&gt; into the remote lister.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Optional, later:&lt;/em&gt; re-express &lt;code&gt;pipe&lt;/code&gt;/&lt;code&gt;kube&lt;/code&gt; around streams when (if) client-go becomes real.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Net: I agree with your four-way split, with the single amendment that tar lives with &lt;code&gt;transfer&lt;/code&gt;, not &lt;code&gt;kube&lt;/code&gt; — and the headline is that doing this is what would finally make the “swap to client-go” sentence in the package doc actually true rather than aspirational.&lt;/p&gt;&lt;p&gt;Want me to start at step 1?&lt;/p&gt;&lt;/div&gt;&lt;/details&gt;&lt;/blockquote&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;I like your analysis and corrections. It seems like a sound plan. Implement the changes fully&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;The final result was a lot cleaner than the original first version. At the same time, I had gotten a rough overview of the codebase.&lt;/p&gt;
&lt;p&gt;As you can see, I often try to give Claude &lt;strong&gt;open-ended questions&lt;/strong&gt; to coax it to “think” through the problem and come up with its own analysis, rather than just asking for a specific change. Only when I am confident that I have understood the issue and solution well enough do I come in with specific guidance. A &lt;code&gt;question:&lt;/code&gt; prefix or an explicit &lt;code&gt;discuss, don&#039;t code&lt;/code&gt; can keep it from jumping to code before the design is clear without having to switch back to planning mode.&lt;/p&gt;
&lt;p&gt;The example above also shows the importance of &lt;strong&gt;pushing back&lt;/strong&gt; on the agent’s suggestions when they don’t feel right. Claude often tries to take the lazy way out ;-)&lt;/p&gt;
&lt;h2&gt;Step n+1: Add Features&lt;/h2&gt;
&lt;p&gt;With a first prototype and a clearer understanding of the codebase, I can now start adding features. I won’t go through all the details here, but the process is similar to what we did before: identify a feature, discuss it with Claude, and then ask it to implement it.&lt;/p&gt;
&lt;blockquote class=&quot;chat chat-me&quot;&gt;&lt;p&gt;Currently only a single item can be copied. I would like to be able to mark multiple files or directories and then copy them over. Before the copy starts, a confirmation dialog should be shown. While the copy is running a progress dialog (with abort button) should be shown instead of using the status line for progress tracking. Can you come up with a plan first?&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Once a feature is planned and implemented, it’s a good time to review the code again and make more architectural improvements if needed. Repeat until you’re happy.&lt;/p&gt;
&lt;p&gt;I usually start a new session for each feature and for each review.&lt;/p&gt;
&lt;h2&gt;Final Result&lt;/h2&gt;
&lt;p&gt;The final tool is available at its &lt;a href=&quot;https://github.com/cosmocode/k8tc&quot;&gt;GitHub repository&lt;/a&gt;. Following the commits, you can see the sequence of adding new features and refactorings in between.&lt;/p&gt;
&lt;p&gt;The final tool has the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;selecting multiple files and directories&lt;/li&gt;
&lt;li&gt;copying files and directories&lt;/li&gt;
&lt;li&gt;deleting files and directories&lt;/li&gt;
&lt;li&gt;creating new directories&lt;/li&gt;
&lt;li&gt;confirmation dialogs for copy and delete operations&lt;/li&gt;
&lt;li&gt;abortable progress dialog for copy and delete operations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I might add a pod/container selector on startup in the future, but for now it’s doing exactly what I wanted it to do, and the whole process took about four hours of work. Incidentally, writing this blog post took nearly the same amount of time ;-)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.cosmocode.de/en/_astro/k8tc-final.DYVF5lhV_K7k0t.webp&quot; alt=&quot;Final result&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; width=&quot;1145&quot; height=&quot;674&quot;&gt;&lt;/p&gt;</description>
            <pubDate>Tue, 09 Jun 2026 00:00:00 +0000</pubDate>
            <guid>https://www.cosmocode.de/en/blog/agoh/20260609-vibe-engineering/</guid>
        </item>
        <item>
            <title>Stop Using Conventional Commits - Sumner Evans</title>
            <link>https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/</link>
            <description>&lt;blockquote&gt;&lt;hr&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;p&gt;You’ve almost certainly encountered
&lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0/&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Conventional Commits&lt;/a&gt; before.
It may have reared its ugly head in the changelog of an open source project
you’ve used. It may have been the enforced commit format for an open source
project you contributed to. A lot of people swear by it. I swear &lt;em&gt;at&lt;/em&gt; it.&lt;/p&gt;&lt;p&gt;Even though it is used by
&lt;a href=&quot;https://github.com/angular/angular/blob/main/contributing-docs/commit-message-guidelines.md&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;a&lt;/a&gt;
&lt;a href=&quot;https://electronjs.org/docs/development/pull-requests#commit-message-guidelines&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;large&lt;/a&gt;
&lt;a href=&quot;https://contribute.freecodecamp.org/how-to-contribute-to-the-codebase/&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;number&lt;/a&gt;
&lt;a href=&quot;https://jenkins-x.io/community/code/&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;of&lt;/a&gt;
&lt;a href=&quot;https://github.com/conventional-changelog/commitlint/blob/master/.github/CONTRIBUTING.md&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;popular&lt;/a&gt;
&lt;a href=&quot;https://github.com/semantic-release/semantic-release/blob/master/CONTRIBUTING.md&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;open&lt;/a&gt;
&lt;a href=&quot;https://github.com/nuxt/nuxt/blob/main/CONTRIBUTING.md&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;source&lt;/a&gt;
&lt;a href=&quot;https://github.com/vitejs/vite/blob/main/.github/commit-convention.md&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;projects&lt;/a&gt;,
Conventional Commits is an actively bad standard which
&lt;strong&gt;&lt;a href=&quot;#focus-failure&quot;&gt;encourages focus on the wrong things&lt;/a&gt; and
&lt;a href=&quot;#broken-promises&quot;&gt;fails to deliver on its promises&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;&lt;h2 id=&quot;focus-failure&quot;&gt;Focus Failure
&lt;a href=&quot;#focus-failure&quot; aria-label=&quot;Permalink to Focus Failure&quot;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Conventional Commits promises to add semantic meaning to commit messages to aid
developers and end-users in understanding the changes made in a commit. However,
Conventional Commits fails to do this in spectacular fashion. To demonstrate
this, let’s look at the anatomy of a conventional commit. According to the
&lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0/#summary&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Conventional Commit website&lt;/a&gt;
commit messages should be formatted as follows:&lt;/p&gt;&lt;div&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code data-lang=&quot;patch&quot;&gt;&lt;span&gt;&lt;span&gt;&amp;lt;type&amp;gt;[optional scope]: &amp;lt;description&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;[optional body]
&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;[optional footer(s)]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The commit’s subject line has a &lt;code&gt;&amp;lt;type&amp;gt;&lt;/code&gt; (something like &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;feat&lt;/code&gt;, &lt;code&gt;chore&lt;/code&gt;,
&lt;code&gt;docs&lt;/code&gt;, or &lt;code&gt;refactor&lt;/code&gt;&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; role=&quot;doc-noteref&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;) describing the type of change. Following that, there
is an optional scope, and then a description.&lt;/p&gt;&lt;p&gt;This format has a major failing: &lt;strong&gt;type is prioritised over scope&lt;/strong&gt;. This is
exactly backwards.&lt;/p&gt;&lt;h3 id=&quot;scope--type&quot;&gt;Scope &amp;gt; Type
&lt;a href=&quot;#scope--type&quot; aria-label=&quot;Permalink to Scope &gt; Type&quot;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;The &lt;em&gt;scope&lt;/em&gt; of a change (the subject of the change) is the most important part
of a commit. To demonstrate this, let’s consider why each one of the following
stakeholders care about the scope of the change more than the type of the
change:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Contributors:&lt;/strong&gt; when you are a contributor to a project, you often need to
read the commit log to identify changes in the codebase relevant to a certain
area of the code. There are many reasons for this including:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Wanting to catch up on what has happened since the last time you
contributed.&lt;/li&gt;&lt;li&gt;Trying to understand where the project’s overall inertia is.&lt;/li&gt;&lt;li&gt;Looking for commits that might conflict with your in-progress work when
pulling or rebasing.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;As you read the commit log, you’re looking at &lt;em&gt;what areas&lt;/em&gt; were touched. You
really do not care about the &lt;em&gt;type&lt;/em&gt; of change happening, you care about the
&lt;em&gt;scope&lt;/em&gt; of the change.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Debuggers:&lt;/strong&gt; when investigating a bug, you often want to look through the
commit log to see what changes might have touched areas related to the
component where the bug manifested. Once again, the scope is the most
important piece of information. The type of change is entirely useless because
bugs can be introduced in any change regardless of type. (I’m sure we’ve all
experienced writing a bugfix that caused another bug.)&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Incident responders:&lt;/strong&gt; when production is down, scanning the commit log for
changes that were made around the time of the outage is an effective way to
identify what areas may be causing the problem. Scope is once again the most
important piece of information you can have at this point. For example, if you
see a commit related to the &lt;code&gt;auth&lt;/code&gt; scope at the tip of the spike of inbound
API errors, it’s a likely culprit for the problem. And once again, type is
irrelevant because bugs could have been added by any change.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So what does Conventional Commits do? It deprioritises scope so much that it’s
&lt;em&gt;optional&lt;/em&gt;! Why the hell is &lt;em&gt;scope&lt;/em&gt; optional? Having a commit without a scope is
like having a sentence without a subject! Then, to add insult to injury,
Conventional Commits elevates &lt;em&gt;type&lt;/em&gt; to the front of the commit message.
Conventional Commits gets the priority of scope and type entirely wrong.&lt;/p&gt;&lt;h3 id=&quot;type-is-redundant-and-restrictive&quot;&gt;Type is Redundant and Restrictive
&lt;a href=&quot;#type-is-redundant-and-restrictive&quot; aria-label=&quot;Permalink to Type is Redundant and Restrictive&quot;&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;You might be thinking “so it may be backwards, but commit type is at least still
important, right?” and to that I say “no”. A commit’s description should almost
always tell you the type of the change! Consider
&lt;a href=&quot;https://github.com/angular/angular/commit/ec138c3645f6e28829e69b6da2a839c248bb3bf0&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;this commit message&lt;/a&gt;
as an example:&lt;/p&gt;&lt;div&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code data-lang=&quot;patch&quot;&gt;&lt;span&gt;&lt;span&gt;fix(compiler): prevent namespaced SVG &amp;lt;style&amp;gt; elements from being stripped
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Even if you only had the description, it’s obvious that it was a bugfix! Space
on the subject line of a commit is already at a premium, wasting characters on
the type is not helpful! But it’s often even worse than useless; it’s often
restrictive. Take
&lt;a href=&quot;https://github.com/angular/angular/commit/683172b39a602ac9ec15db69d22853433a67a084&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;this commit message&lt;/a&gt;
as an example:&lt;/p&gt;&lt;div&gt;&lt;pre tabindex=&quot;0&quot;&gt;&lt;code data-lang=&quot;patch&quot;&gt;&lt;span&gt;&lt;span&gt;refactor(core): Update webmcp support to use document.modelContext
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This commit updated the &lt;code&gt;webmcp&lt;/code&gt; functionality in the &lt;code&gt;core&lt;/code&gt; component to
support both &lt;code&gt;document.modelContext&lt;/code&gt; and &lt;code&gt;navigator.modelContext&lt;/code&gt;, so was that a
bugfix, refactor, or new feature? I would argue it’s all of them! But again, the
only thing that really matters is that it was a change to the &lt;code&gt;core/webmcp&lt;/code&gt;
component.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Conventional Commits fundamentally focuses on the wrong thing (the commit
type) and devalues the scope (which is what people actually care about).&lt;/strong&gt;&lt;/p&gt;&lt;h2 id=&quot;broken-promises&quot;&gt;Broken Promises
&lt;a href=&quot;#broken-promises&quot; aria-label=&quot;Permalink to Broken Promises&quot;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;So we have determined that the format of Conventional Commits sucks, but it must
provide &lt;em&gt;some&lt;/em&gt; benefit. Let’s read the
&lt;a href=&quot;https://www.conventionalcommits.org/en/v1.0.0/#why-use-conventional-commits&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;em&gt;Why Use Conventional Commits&lt;/em&gt;&lt;/a&gt;
section to see if any of the reasons make any sense.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automatically generating CHANGELOGs.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This is the biggest promise of Conventional Commits: you can run a tool like
&lt;a href=&quot;https://git-cliff.org/&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;git-cliff&lt;/a&gt; or
&lt;a href=&quot;https://github.com/conventional-changelog/conventional-changelog&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;conventional-changelog&lt;/a&gt;
to generate a changelog from the commits since your last release. Is this even
a good idea? No! The audience of a changelog is entirely different than the
audience for a commit log!&lt;/p&gt;&lt;p&gt;A changelog is user-facing, and the user cares about understanding the
functional differences between versions. They care about what changed from a
&lt;strong&gt;business/functional&lt;/strong&gt; perspective.&lt;/p&gt;&lt;p&gt;A commit log is developer-facing, and the developers care about reading a
story of how the codebase has changed over time. They care about what changed
from a &lt;strong&gt;scope&lt;/strong&gt; perspective.&lt;/p&gt;&lt;p&gt;As you can see, these are two entirely different grains, and any efforts to
combine them result in subpar results. The reasons for this are multiple:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;In any moderately complex project, it takes multiple commits to land any
notable feature. The process of landing the feature (as documented by the
commit log) is valuable for developers and contributors, but it’s useless
for the end-user. The end-user only cares about the new feature, not how it
was built!&lt;/li&gt;&lt;li&gt;As
&lt;a href=&quot;https://richvdh.org/conventional-commits-considered-harmful.html#reverts-are-hard&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Rich pointed out&lt;/a&gt;,
reverts are problematic for Conventional Commits. Revert commits are
important from a commit log story perspective for developers, but to the end
user, a change that is reverted is equivalent to a change not made.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automatically determining a semantic version bump (based on the types of
commits landed).&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This sounds nice, but the realities of software engineering often interfere
significantly with the viability of accurately accomplishing this task.
Consider the following situations:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reverts:&lt;/strong&gt; imagine a situation where the breaking change you introduced
was actually so breaking that you have to revert it? Your tooling will pick
up a breaking change and increment the major version even though the
breakage was actually reverted and there is no breaking change.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Accidental breakages:&lt;/strong&gt; maybe the breakage is subtle and you don’t realise
a change is a breaking change when you make the change. Only in retrospect
realise that it’s breaking. You will incorrectly increment a minor/patch
version when a major version bump is necessary.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Retroactive unbreakages:&lt;/strong&gt; say you later add a commit which, in
composition with a previously breaking commit, results in a diff which is
not breaking. Similar to the revert situation, tooling would incorrectly
identify a breaking change.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In such situations, you could rewrite history with a rebase, but that often
breaks or is prevented by workflows. It also presents a revisionist history to
the contributors trying to contribute to the project, reducing the reliability
of the story the commit log is telling.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Communicating the nature of changes to teammates, the public, and other
stakeholders.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;As we have established up to this point, teammates and the public have very
different needs from a changelog and commit log. Conventional Commits manages
to solve neither.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Triggering build and publish processes.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;This is just a bad idea. Say you only run automated security checks on commits
that touch code and then someone creates a Trojan-horse commit titled
&lt;code&gt;docs: fix typos&lt;/code&gt; which actually introduces vulnerabilities into the
authentication subsystem? Obviously, that sort of malicious activity would
hopefully be caught in code review, but the automated tooling is bypassed,
putting the onus on a human to identify the problem.&lt;/p&gt;&lt;p&gt;Compute is cheap, just use &lt;code&gt;git diff&lt;/code&gt; to identify changed files (scope, once
again) and run build/publish processes based on that.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Making it easier for people to contribute to your projects, by allowing them
to explore a more structured commit history.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;More structured, sure. Making it easier to contribute? Not at all (as we have
already demonstrated at length).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Not a single one of the “selling points” for Conventional Commits actually holds
water.&lt;/p&gt;&lt;p&gt;Conventional Commits is also extremely difficult to apply to a project. You are
supposed to define your own set of “types”, but pretty much everyone just takes
the defaults from
&lt;a href=&quot;https://github.com/conventional-changelog/commitlint&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;commitlint&lt;/a&gt; which often
don’t fit well with the particulars of individual projects. This problem is
especially acute in corporate environments where change management and audit
requirements often mandate a ticket number in every commit message. The
&lt;code&gt;&amp;lt;scope&amp;gt;&lt;/code&gt; field is the obvious place to put it, but this ends up replacing the
only useful metadata in a Conventional Commit with a completely useless ticket
number.&lt;/p&gt;&lt;h2 id=&quot;a-better-way&quot;&gt;A Better Way
&lt;a href=&quot;#a-better-way&quot; aria-label=&quot;Permalink to A Better Way&quot;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;So what should you do instead? Follow the lead of truly successful software
projects like Linux, FreeBSD, Git, Go, and NixOS! What do these projects have in
common? They all use scope-prefixed commit messages (where “scope” is defined to
be relevant to the actual project). Usually, the scope to use on a given project
is self-evident. For the Linux kernel, the subsystem is the natural scope. For
Go projects, the package path is the natural scope. For a project using a
microservice architecture, the microservice name is the natural scope.&lt;/p&gt;&lt;p&gt;Here are some examples of projects and their commit format guidelines.&lt;/p&gt;&lt;table readabilityDataTable=&quot;1&quot;&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Project&lt;/th&gt;&lt;th&gt;Format&lt;/th&gt;&lt;th&gt;Example&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=&quot;https://www.kernel.org/doc/html/v4.14/process/submitting-patches.html&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Linux&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;subsystem: description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/torvalds/linux/commit/1d774589f924&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;i2c: virtio: mark device ready before registering the adapter&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=&quot;https://freebsdfoundation.org/wp-content/uploads/2020/11/Writing-Commit-Messages.pdf&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;FreeBSD&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;prefix: Description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/freebsd/freebsd-src/commit/f77d37cffdf3&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;linuxulator: Return EINVAL for invalid inotify flags&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=&quot;https://git-scm.com/docs/SubmittingPatches&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Git&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;area: description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/git/git/commit/62319b49bbe7&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;gitlab-ci: update macOS image&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=&quot;https://go.dev/wiki/CommitMessage&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Go&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;package: description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/golang/go/commit/517d4d3c7976&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;net/http/cookiejar: add godoc links&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/NixOS/nixpkgs/blob/master/CONTRIBUTING.md&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;nixpkgs&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;pkg-name: description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/NixOS/nixpkgs/commit/7bf858875a54&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;xwayland: 24.1.11 -&amp;gt; 24.1.12&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/nodejs/node/blob/main/doc/contributing/pull-requests.md#commit-message-guidelines&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;Node.js&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;subsystem: description&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;a href=&quot;https://github.com/nodejs/node/commit/5f727fdc89c06782652bfbf6a4d05ade1db3d2c8&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;&lt;code&gt;stream: fast-path stateless transform flush results&lt;/code&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;Unfortunately, despite being used by some of the most successful open source
projects ever created, this commit style seems to have lost the branding war. I
intend to change that. Introducing
&lt;a href=&quot;https://scopedcommits.com&quot; title=&quot;(opens in new tab)&quot; rel=&quot;external&quot; target=&quot;_blank&quot;&gt;scopedcommits.com&lt;/a&gt;. The website is dedicated to
advocating for a return to commit message sanity, and separating the concern of
changelog generation from commit log management.&lt;/p&gt;&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion
&lt;a href=&quot;#conclusion&quot; aria-label=&quot;Permalink to Conclusion&quot;&gt;&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Conventional Commits’ purported advantages are actually illusory and the
industry has seen no tangible benefit from using it as a standard. However,
Conventional Commits unfortunately seems to have become fairly popular in open
source projects, and due to this it seems like AIs have a habit of defaulting to
using it for commit messages. This has caused propagation of anti-pattern-ridden
commit messages across projects.&lt;/p&gt;&lt;p&gt;My goal in this article is to fight against Conventional Commits’ dominance, and
demonstrate that there better ways to structure commit messages. But if this
article has not convinced you to stop using Conventional Commits, I look forward
to the flame war in the comment section.&lt;/p&gt;&lt;/div&gt;</description>
            <pubDate>Sat, 06 Jun 2026 04:53:43 +0000</pubDate>
            <guid>https://sumnerevans.com/posts/software-engineering/stop-using-conventional-commits/</guid>
        </item>
        <item>
            <title>SpaceX Boersengang – Der groesste Bankraub Geschichte</title>
            <link>https://www.metacheles.de/spacex-boersengang-der-groesste-bankraub-geschichte/</link>
            <description>&lt;blockquote&gt;&lt;hr&gt;&lt;/blockquote&gt;&lt;div&gt;
         &lt;p&gt;&lt;strong&gt;Diesen Monat geht SpaceX an die Boerse und es wird wohl der groesste Boersengang der Geschichte! Aber nicht nur das..., denn wenn alles glatt laeuft, dann wird dadurch Elon Musk zum ersten Billionaer ueberhaupt. &lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Was aber noch viel gruseliger ist: Millionen Amerikaner werden SpaceX-Aktionaere – ohne eine einzige Aktie aktiv zu kaufen. Klingt nach einer technologischen Erfolgsgeschichte? Ist es nicht. Es ist die mutmasslich groesste (und am offensten orchestrierte) Vermoegensumverteilung von Kleinanlegern hin zu einer Handvoll Tech-Investoren, die wir je gesehen haben. Und sie ist wohl komplett legal!&lt;/strong&gt;&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://share.transistor.fm/s/d3800dbf?ref=metacheles.de&quot;&gt;&lt;div&gt;&lt;p&gt;SpaceX Börsengang Analyse - Der größte Bankraub der Geschichte!? | MeTacheles Tonspur | Episode 209&lt;/p&gt;&lt;p&gt;Hier 👉 https://t.ly/SpaceXIPO geht es zum wichtigen, begleitenden Artikel zu dieser Spezial-Ausgabe!🚨 SpaceX-Börsengang: Der grösste Bankraub der Geschichte? Wie Musk uns alle abzockt!Der SpaceX-IPO wird der grösste Börsengang aller Zeiten – und laut Sascha Pallenberg auch die offenste…&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://static.ghost.org/v5.0.0/images/link-icon.svg&quot; alt&gt;&lt;span&gt;Der größte Bankraub der Geschichte!?&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/NzZiNy5qcGc-2039c70163aacda68f6c78c4c113dfd7f4b14205092983bcadafc8e6c1c2e249.webp&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;figcaption&gt;&lt;p&gt;&lt;a href=&quot;https://share.transistor.fm/s/d3800dbf?ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;&lt;b&gt;&lt;strong&gt;HIER&lt;/strong&gt;&lt;/b&gt;&lt;/a&gt;&lt;span&gt; oder auf das Widget klicken, um zum Podcast zu gelangen&lt;/span&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Wenn ihr MeTacheles direkt unterstuetzen wollt, dann &quot;chippt&quot; doch einfach den Gegenwert einer Currywurst (gerne auch vegan) in meine Paypal:&lt;/p&gt;&lt;p&gt;oder meine Wero-Kasse:&lt;/p&gt;&lt;p&gt;MeTacheles funktioniert nicht ohne euch und wenn ihr glaubt, dass dieses Format auch in eurem Netzwerk ankommt, dann teilt es doch genau mit diesem.&lt;/p&gt;&lt;blockquote&gt;&lt;em&gt;&lt;strong&gt;Ganz wichtig:&amp;nbsp;&lt;/strong&gt;Den Podcast koennt ihr hier direkt oben im Browser, aber auch auf diversen Plattformen wie u.a.&lt;/em&gt;&lt;p&gt;&lt;a href=&quot;https://podcasts.apple.com/de/podcast/metacheles-tonspur/id1615163239?ref=metacheles.de&quot;&gt;&lt;strong&gt;Apple&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;nbsp;-&amp;nbsp;&lt;/strong&gt;&lt;a href=&quot;https://open.spotify.com/show/1u9cHXItGCXCKzjGqTCANH?ref=metacheles.de&quot;&gt;&lt;strong&gt;Spotify&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;nbsp;-&amp;nbsp;&lt;/strong&gt;&lt;a href=&quot;https://youtube.com/playlist?list=PLW2eMAjI1-0N-3DEYyVc_iP25D7JBKKo8&amp;amp;si=y5VyNPThjq1Ny3uW&amp;amp;ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Youtube&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;nbsp;-&amp;nbsp;&lt;/strong&gt;&lt;a href=&quot;https://music.amazon.de/podcasts/cfd2d49c-efd7-4152-8c7c-9e283a94dff8/metacheles-tonspur?ref=metacheles.de&quot;&gt;&lt;strong&gt;Amazon&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;&amp;nbsp;oder als&amp;nbsp;&lt;/strong&gt;&lt;a href=&quot;https://t.ly/MeTaRSS?ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;RSS-Feed&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;anhoeren und abonnieren. Gerade&amp;nbsp;&lt;/em&gt;&lt;strong&gt;Apple &amp;amp; Spotify-Abrufe helfen dem Format&lt;/strong&gt;&lt;em&gt;, denn dort gibt es entsprechende Rankings!&lt;/em&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; Die Nummer hier wird ein wenig umfangreicher... ich denke es ist hinlaenglich bekannt, wie kritisch ich Musks Unternehmungen seit gut 15 Jahren kommentiere... aber die Recherche fuer diese Analyse, die hat auch mich immer und immer wieder dem Kopf schuetteln lassen. Setzt euch nen Bookmark, hoert euch den Podcast an und vielleicht denkt ihr ja darueber nach diesen Artikel mit eurem Netzwerk zu teilen? Ich bin mir sicher, dass der ziemlich gut altern wird!&lt;/p&gt;&lt;p&gt;Gehen wir es an!&lt;/p&gt;



&lt;h2 id=&quot;175-billionen-dollar-fuer-eine-raketenfirma&quot;&gt;1,75 Billionen Dollar fuer eine Raketenfirma&lt;/h2&gt;&lt;p&gt;Lasst uns direkt in die Glaswolle der Fantasiebewertungen springen und mit einer Zahl anfangen. &lt;strong&gt;1,75 Billionen Dollar.&lt;/strong&gt; Das ist die Bewertung, die Elon Musk fuer SpaceX in den Raum gestellt hat... Mehr als Walmart! Mehr als die meisten Volkswirtschaften dieses Planeten. Mehr als ich, der mit einem Jeanssparbuch angefangen hat die Finanzwelt zu erkunden, auch nur ansatzweise begreifen kann!&lt;/p&gt;&lt;p&gt;Ist SpaceX ein echtes Unternehmen? Absolut! Sie schiessen Satelliten in den Himmel. Sie betreiben Starlink mit ueber 10 Millionen Abonnenten in 164 Laendern. Sie sind technisch beeindruckend und.... schliesslichen haben sie ja letztes Jahr rund 19 Milliarden Dollar Umsatz gemacht – &lt;strong&gt;das meiste davon mit Starlink und Regierungsauftraegen&lt;/strong&gt;. Bei einem GAAP-Nettoverlust von &lt;strong&gt;4,94 Milliarden Dollar&lt;/strong&gt;. Merkt euch die Zahl, wir kommen darauf zurueck!&lt;/p&gt;&lt;figure data-kg-thumbnail=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Starship-V3_thumb.jpg&quot; data-kg-custom-thumbnail&gt;
            &lt;div&gt;
                &lt;video src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Starship-V3.mp4&quot; poster=&quot;https://img.spacergif.org/v1/1920x1080/0a/spacer.png&quot; width=&quot;1920&quot; height=&quot;1080&quot; playsinline preload=&quot;metadata&quot;&gt;&lt;/video&gt;
                
                &lt;div&gt;
                        &lt;p&gt;
                        
                        &lt;span&gt;0:00&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
                            /&lt;span&gt;0:24&lt;/span&gt;
                        &lt;/p&gt;
                        &lt;/div&gt;
            &lt;/div&gt;
            &lt;figcaption&gt;&lt;p&gt;&lt;span&gt;Powered by US-Taxpayers. Knapp $3 Mrd hat die NASA SpaceX ueberwiesen, dass sie Astronauten auf den Mond bringen. Stattdessen explodieren Starships mit schoener Regelmaessigkeiten und beehren die Oekosysteme unserer Ozeane mit Tonnen an Muell. Die SpaceX-MitarbeiterLinnen finden das offensichtlich richtig gut!&lt;/span&gt;&lt;/p&gt;&lt;/figcaption&gt;
        &lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Starship-V3_thumb.jpg&quot;&gt;&lt;/figure&gt;&lt;p&gt;Jetzt zur eigentlichen Kuriositaet. Eine Bewertung an der Boerse ist immer auch eine Wette auf zukuenftige Umsaetze. Die Nummer nennt sich Revenue Multiple oder Price-to-Sales. Bei der SpaceX-Zielbewertung kommen wir auf ein P/S-Verhaeltnis von rund 94 – Jeffrey Kluge von der University of Colorado nennt das &lt;a href=&quot;https://papers.ssrn.com/sol3/papers.cfm?abstract_id=6668799&amp;amp;ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;in einem SSRN-Papier &lt;/a&gt;&quot;&lt;strong&gt;historically associated with the peak of the dot-com bubble&lt;/strong&gt;&quot;.&lt;/p&gt;&lt;p&gt;Zum Vergleich: Lockheed Martin handelt bei einem P/S von 1,7. Northrop Grumman bei 1,9. RTX bei 2,9. Das sind die etablierten US-Verteidigungskonzerne mit echten Gewinnen, echten Margen, echten Bilanzen! Bei dieser Groessenordnung gibt es im Defense- und Aerospace-Bereich nichts Vergleichbares. Es gab es nie und ich habe das Gefuehl, dass dies auch so schnell nicht noch einmal vorkommen wird!&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-29.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-29.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-29.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-29.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-29.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Das ist nicht ambitioniert. Das ist nicht visionaer. Das ist – um es mit &lt;a href=&quot;https://www.ft.com/content/f471fed4-0aee-44b4-8828-d6887c4978f2?ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Robin Wigglesworth von der Financial Times zu sagen&lt;/strong&gt;&lt;/a&gt; – absolut &quot;batshit&quot;. Selbst Baillie Gifford, einer der groessten institutionellen Pre-IPO-Investoren von SpaceX, markiert seine eigene Beteiligung konservativ bei einer impliziten Gesamtbewertung von 1,25 Billionen Dollar. Eine halbe Billion unter dem IPO-Ask. Wenn dein eigener Long-Term-Investor 500 Milliarden (abermals: MILLIARDEN!) unter deinem Wunschpreis bilanziert, sollte das zu denken geben.&lt;/p&gt;&lt;p&gt;Aber die Bewertung muss halten. Weil dahinter ein sehr spezifischer Mechanismus steckt und der muss durchgezogen werden, greifen... denn am Ende wollen ja alle fruehen Investor:innen gluecklich sein, oder? &lt;/p&gt;&lt;h2 id=&quot;wie-wir-hier-hingekommen-sind&quot;&gt;Wie wir hier hingekommen sind&lt;/h2&gt;&lt;p&gt;Spult kurz zurueck ins Jahr 2022. Elon Musk sammelt 44 Milliarden Dollar ein und kauft Twitter. Seine Mitfinanziers: Andreessen Horowitz, ein saudischer Prinz, der Mitgruender von Palantir, Jack Dorsey! &lt;/p&gt;&lt;p&gt;Musk benennt Twitter in X um. Innerhalb eines Jahres ist X weniger als die Haelfte des Kaufpreises wert und genau das ist ein Problem!&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://www.metacheles.de/danke-elon-musk-twitter-ist-der-wichtigste/&quot;&gt;&lt;div&gt;&lt;p&gt;Danke Elon Musk! Twitter ist der wichtigste Honeypot&lt;/p&gt;&lt;p&gt;Der Verkauf Twitters an Elon Musk hat tatsaechlich mein digitales Leben auf den Kopf gestellt und das alles andere als negativ. Und genau dafuer moechte ich mich einmal ausfuehrlich bedanken!&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/Copy-of-Copy-of-Copy-of-metacheles-a9f6cea93ceeb69d21733321db4658fc0c67b1d998e0014c6c0d7270a63039f7.png&quot; alt&gt;&lt;span&gt;MeTacheles&lt;/span&gt;&lt;span&gt;Sascha Pallenberg&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/206b0670-a853-470e-8111-76d5cdc4a8da_1920x1080-f67e8d2d60c62cda440096ae3b16648e26db423ef12ceffc614098ea7694c54b.png&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p&gt;Aber dann kommt aus heiterem Himmel die Loesung: KI ist der naechste heisse Scheiss und Musk hat hat ja eine KI-Firma, also fusioniert er X mit xAI! Kein Cash wechselt den Besitzer. Die X-Investoren bekommen xAI-Aktien. Problem geloest!&lt;/p&gt;&lt;p&gt;Naechstes Problem: xAI ist eine der groessten Geldverbrennungs-Maschinen der westlichen Hemisphaere und zerballert nach Schaetzungen ueber eine Milliarde pro Monat. xAI-CapEx 2025 allein: 12,7 Milliarden Dollar – mehr als Starlink und das SpaceX Launch-Geschaeft zusammen!&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-35.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-35.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-35.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-35.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-35.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;figcaption&gt;&lt;span&gt;xAI verbrennt $1 Mrd/Monat fuer ueberschaubare Marktanteile von Grok&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Loesung Nummer zwei: Musk hat eine Raketenfirma! Also nutzt er nun ganz hurtig SpaceX, um xAI zu kaufen. Wieder kein Cash. Drei Firmen, zwei Fusionen, null Dollar tatsaechlich gezahlt. Alle, die damals geholfen haben, Twitter zu uebernehmen, halten jetzt SpaceX-Aktien.&lt;/p&gt;&lt;figure data-kg-thumbnail=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Bang_thumb.jpg&quot; data-kg-custom-thumbnail&gt;
            &lt;div&gt;
                &lt;video src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Bang.mp4&quot; poster=&quot;https://img.spacergif.org/v1/1920x1080/0a/spacer.png&quot; width=&quot;1920&quot; height=&quot;1080&quot; playsinline preload=&quot;metadata&quot;&gt;&lt;/video&gt;
                
                &lt;div&gt;
                        &lt;p&gt;
                        
                        &lt;span&gt;0:00&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
                            /&lt;span&gt;0:29&lt;/span&gt;
                        &lt;/p&gt;
                        &lt;/div&gt;
            &lt;/div&gt;
            &lt;figcaption&gt;&lt;p&gt;&lt;span&gt;Ich kann mir nicht helfen aber &quot;All-in SpaceX&quot; hat was von &quot;Alles auf Horst!&quot; aus dem Legenden-Film &quot;Bang Boom Bang&quot;&lt;/span&gt;&lt;/p&gt;&lt;/figcaption&gt;
        &lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Bang_thumb.jpg&quot;&gt;&lt;/figure&gt;&lt;p&gt;Und dann kommt im Maerz 2026 der eigentliche Knaller: SpaceX nimmt einen 20-Milliarden-Dollar-Bridge-Loan auf, arrangiert von Goldman Sachs, mit Bank of America, Citi, JPMorgan und Morgan Stanley. Effektivverzinsung 4,58 Prozent. Damit werden fuenf Vorgaenger-Fazilitaeten abgeloest – darunter die toxischen Twitter-Junk-Bonds mit bis zu 12,5 Prozent und die xAI-Senior-Secured-Notes. Bezahlt wird der Kredit zwingend aus den IPO-Erloesen!&lt;/p&gt;&lt;p&gt;Was hier passiert ist, lasst euch das auf der Zunge zergehen: Die ehemaligen Twitter-Glaeubiger – angefuehrt von Morgan Stanley, werden de facto durch SpaceX-IPO-Equity ausbezahlt. Musks toxisches Twitter-Schuldenbuch wird ueber drei Umzuege saniert: Twitter wurde X, X wurde xAI, xAI wurde SpaceX. Und SpaceX wird oeffentlich. Mit eurem Geld!&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-28.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-28.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-28.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-28.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-28.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Und SpaceX ist auf einmal nicht mehr nur eine Raketenfirma, die Internet verkauft. SpaceX ist – laut Musk – die Zukunft. Rechenzentren im Weltraum. &quot;Mehr KI in der Umlaufbahn als auf der gesamten Erde zusammen&quot;, sagt er. Sehe ich, vielleicht ein bisschen pessimistisch, ein bisschen anders. Aber dazu kommen wir spaeter... zuvor oeffne ich noch die Asservatenkammer dieses Scams und praesentiere Beweisstuecke A und B!&lt;/p&gt;&lt;h2 id=&quot;beweisstueck-a-die-cybertruck-connection&quot;&gt;Beweisstueck A: Die Cybertruck-Connection&lt;/h2&gt;&lt;p&gt;Wer wissen will, wie Elon Musk &lt;em&gt;heute schon&lt;/em&gt; Geld zwischen seinen Firmen verschiebt, muss sich die Cybertruck-Verkaufszahlen anschauen. Nicht die Zahlen, die Tesla im Quartalsbericht praesentiert. Die Zahlen &lt;em&gt;dahinter&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;Per S&amp;amp;P Global Mobility und ueberkreuzgeprueft mit den 10-K/A-Filings von Tesla: SpaceX hat allein im vierten Quartal 2025 ganze &lt;strong&gt;1.279 Cybertrucks gekauft&lt;/strong&gt;. Zusammen mit anderen Musk-Vehikeln waren es 1.339 von insgesamt 7.071 US-registrierten Cybertrucks in diesem Quartal. Das sind 18 bis 19 Prozent aller Cybertruck-Registrierungen, die in Q4 2025 quasi an Musk selbst gingen.&lt;/p&gt;&lt;figure data-kg-thumbnail=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/njrESdVnhkNlEmAN_thumb.jpg&quot; data-kg-custom-thumbnail&gt;
            &lt;div&gt;
                &lt;video src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/njrESdVnhkNlEmAN.mp4&quot; poster=&quot;https://img.spacergif.org/v1/1286x720/0a/spacer.png&quot; width=&quot;1286&quot; height=&quot;720&quot; playsinline preload=&quot;metadata&quot;&gt;&lt;/video&gt;
                
                &lt;div&gt;
                        &lt;p&gt;
                        
                        &lt;span&gt;0:00&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
                            /&lt;span&gt;0:21&lt;/span&gt;
                        &lt;/p&gt;
                        &lt;/div&gt;
            &lt;/div&gt;
            &lt;figcaption&gt;&lt;p&gt;&lt;span&gt;Von SpaceX gekaufte Tesla Cybertrucks&lt;/span&gt;&lt;/p&gt;&lt;/figcaption&gt;
        &lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/njrESdVnhkNlEmAN_thumb.jpg&quot;&gt;&lt;/figure&gt;&lt;p&gt;Ohne diese internen Kaeufe waeren Teslas Cybertruck-Registrierungen im Q4 2025 um 51 Prozent year-over-year eingebrochen. Mit ihnen sehen die Zahlen... ja was soll ich sagen? Nicht ganz so katastrophal aus? Ne... es ist der groesste Flop der Automobil-Geschichte. Auch mit den SpaceX-Kaeufen!&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://www.metacheles.de/tesla-cybertruck-analyse-shuttle/&quot;&gt;&lt;div&gt;&lt;p&gt;Tesla Cybertruck Analyse - Shuttle der Apokalypse *Update&lt;/p&gt;&lt;p&gt;Erste Eindruecke vom Tesla Cybertruck, einem ueber 3t schweren Pickup-Truck, der gefuehlt auch den offiziellen Shuttle Service fuer saemtliche kommenden Mad Max-Filme stellen koennte&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://static.ghost.org/v5.0.0/images/link-icon.svg&quot; alt&gt;&lt;span&gt;MeTacheles&lt;/span&gt;&lt;span&gt;Sascha Pallenberg&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/f1e46bc1-f110-40d4-ba88-4249f6cce023_1920x1080-349851ef404907ce7aa1826bffd9b2a76aaf5cd3ce9853f6c6b19fc609ab92d7.png&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p&gt;Aber es kommt noch besser, denn Morningstar-Analyst Seth Goldstein hat herausgearbeitet, dass SpaceX die Cybertrucks zum &lt;strong&gt;vollen Listenpreis&lt;/strong&gt; gekauft hat. &quot;Suggested Retail Price&quot;. Konzerngrosskunden bekommen normalerweise Mengenrabatte. Wenn euer Mittelstaendler 100 Firmenwagen bei VW bestellt, bekommt er einen Rabatt. SpaceX kauft 1.279 Cybertrucks – und zahlt den vollen Listenpreis. Hey... why not? Bleibt doch eh in der Familie, oder?&lt;/p&gt;&lt;p&gt;Ich finde da faellt es ja schon fast kaum noch ins Gewicht, dass auch das Pentagon ein wenig tiefer in die Tasche greifen muss:&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://www.engadget.com/2181419/spacex-reportedly-pressured-the-pentagon-into-paying-more-for-starlink-access/?shem=dsdf,sharefoc,agadiscoversdl,,sh/x/discover/m1/4&amp;amp;ref=metacheles.de&quot;&gt;&lt;div&gt;&lt;p&gt;SpaceX reportedly pressured the Pentagon into paying more for Starlink access - Engadget&lt;/p&gt;&lt;p&gt;SpaceX is reportedly jacking up Starlink prices for the Pentagon.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/engadget-favicon-9d49558c4d5b7ee4748c7fba3bf8d5e746534474da5402a8a2b6d76d467275f2.png&quot; alt&gt;&lt;span&gt;Engadget&lt;/span&gt;&lt;span&gt;Will Shanklin&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/l-intro-1779819014-620dfe5f1af354ad3ed56ec59f90b120b7c1ae2bcff848fc5d04a85fc896b583.jpg&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p&gt;Um das mal fuer das Geschaeftsjahr 2025 zusammenzufassen: SpaceX und xAI zusammen kauften Goods und Services bei Tesla im Wert von rund 650 Millionen Dollar. Davon allein $506 Millionen Megapack-Batteriesysteme fuer Colossus umd $131 Millionen Cybertrucks. Das ist eine direkte Vermoegensuebertragung von SpaceX-Aktionaeren an Tesla-Aktionaere – beide Firmen kontrolliert von derselben Person und wenn ihr mich fragt... ich bin mir ziemlich sicher, dass die SpaceX-Aktionaere davon erstmal nichts wussten... und sich die von Tesla nun freuen 🚀&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-27.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-27.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-27.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-27.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-27.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Und jetzt die Frage, die jeder kuenftige SpaceX-Aktionaer sich stellen sollte: Wenn Musk schon &lt;em&gt;vor&lt;/em&gt; dem IPO SpaceX nutzt, um Tesla-Quartalszahlen aufzuhuebschen – was glaubt ihr, passiert &lt;em&gt;nach&lt;/em&gt; dem IPO mit eurem Geld? Vor allen Dingen der ehemalige Branchen-Primus mal wieder schwaechelt? Wenn ein xAI-Vertrag platzt? Wenn X mal wieder Werbeeinnahmen verliert?&lt;/p&gt;&lt;p&gt;Texas, wo SpaceX inzwischen inkorporiert ist, hat 2024 ein Gesetz erlassen, das Klagen gegen das Management praktisch unmoeglich macht! Mehr dazu spaeter. Aber merkt euch: Die Mechanik des Geld-Hin-und-Her-Schiebens ist nicht hypothetisch. Sie laeuft schon. Sie ist offen in den SEC-Filings dokumentiert. Und nach dem IPO werdet ihr daran beteiligt sein. Ist das alles neu? Nein, so hat Musk bereits vor 10 Jahren Solar City gerettet und den Tesla-Aktionaeren aufgedrueckt... uebrigens, Tesla verkauft inzwischen keine Solardaecher mehr!&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://www.cnbc.com/2016/06/22/chanos-bail-out-of-solarcity-a-corporate-governance-at-its-worst.html?ref=metacheles.de&quot;&gt;&lt;div&gt;&lt;p&gt;Chanos: ‘Brazen’ SolarCity deal is ‘corporate governance at its worst’&lt;/p&gt;&lt;p&gt;High-profile investment manager Jim Chanos blasted Tesla’s proposed acquisition of SolarCity on Wednesday.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/CNBC_LOGO_FAVICON_1C_KO_RGB-981c2c5fe40c1fa85ca16b580fbaaf8b66c7c7f6425bc1542588831b54134e2c.ico&quot; alt&gt;&lt;span&gt;CNBC&lt;/span&gt;&lt;span&gt;Ted Kemp and Scott Wapner&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/102939364-IMG_1585r-3796b9b55cc2805be0dcc5ca25567aea81e420ec40870508ac268b3ffa4fe16d.jpg&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;h2 id=&quot;beweisstueck-b-der-anthropic-deal-und-die-maerchenstunde-mit-den-orbital-datacentern&quot;&gt;Beweisstueck B: Der Anthropic-Deal und die Maerchenstunde mit den Orbital-Datacentern&lt;/h2&gt;&lt;p&gt;Jetzt zum zweiten Beweisstueck. Das ist subtiler, aber meines Erachtens noch entlarvender... also Hyperloop/Neuralink-Level entlarvender!&lt;/p&gt;&lt;p&gt;Im S-1 wird erstmals ein Vertrag offengelegt, von dem die meisten Beobachter bisher nichts wussten: Anthropic zahlt &lt;strong&gt;1,25 Milliarden Dollar pro Monat&lt;/strong&gt; an SpaceX/xAI fuer den Zugang zu Colossus 1, dem KI-Rechenzentrum in Memphis mit ueber 220.000 Nvidia-GPUs. Der Vertrag laeuft bis Mai 2029, mit einem potenziellen Gesamtvolumen von ueber 40 Milliarden Dollar. Das ist – haltet euch fest – fast so viel wie der gesamte SpaceX-Konzernumsatz aus dem letzten Jahr. Wohlgemerkt pro Jahr und wohlgemerkt durch einen Wettbewerber von xAI!&lt;/p&gt;&lt;p&gt;Anthropic kauft also praktisch die gesamten 300 Megawatt Rechenkapazitaet von Colossus 1 auf. Warum? Weil xAI selbst die eigenen Rechenzentren nicht voll auslastet. Grok hat zwar 64 Millionen monatliche Nutzer, aber nur 1,9 Millionen zahlende Abonnenten. Das Geschaeft ist da, aber es ist nicht gross genug, um die Compute-Kapazitaet zu rechtfertigen, die Musk gebaut hat. Es ist einfach nur absurd und wenn man dann noch bedenkt, dass ja jetzt Colussus 2 gebaut wird... oh well:&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-37.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-37.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-37.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-37.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-37.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Lasst das mal sacken. Musk hat sich jahrelang vor jedes Mikrofon gestellt und erklaert, wie kritisch GPU-Kapazitaet fuer die KI-Zukunft sei. Wie xAI nur dann mit OpenAI und Anthropic mithalten koenne, wenn es ueber genug Compute verfuege. Memphis war das groesste GPU-Cluster der Welt. Und jetzt – Plot Twist – vermietet er es an den Wettbewerber. Weil er es selbst nicht braucht oder vielleicht nicht allein fuer die unvergleichbare Umweltbelastung gelten moechte:&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://www.selc.org/news/xai-built-an-illegal-power-plant-to-power-its-data-center/?ref=metacheles.de&quot;&gt;&lt;div&gt;&lt;p&gt;xAI built an illegal power plant to power its data center&lt;/p&gt;&lt;p&gt;This article was updated April, 14, 2026 to reflect new litigation. Just south of the Tennessee-Mississippi state line sits dozens of unpermitted gas turbines that power&amp;nbsp;xAI’s&amp;nbsp;Colossus 2 data center while releasing smog-forming pollution, soot, and hazardous chemicals like formaldehyde. The tech company set up the de facto power plant with no permits, no public input, […]&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/favicon-a2c8f67cf5c504123957b745fd950f6516ff615559626b002ed5542951fc7192.ico&quot; alt&gt;&lt;span&gt;Southern Environmental Law Center&lt;/span&gt;&lt;span&gt;Eric Hilt&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/010_xAI-102531-700x467-fb33bb9875a950f8899c936deed4cb4c07bca3820e2f9ecab21631d50ac149ce.jpeg&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p&gt;Aber zurueck zu Musk und seinem AI-Irrsinn, denn auf der Buehne des World Economic Forum in Davos erklaerte er: KI-Rechenzentren im &lt;strong&gt;Weltraum&lt;/strong&gt; seien ein &quot;no-brainer&quot;. Orbital AI Compute. Mehr Rechenleistung in der Umlaufbahn als auf der gesamten Erde. Das sei die Zukunft!&lt;/p&gt;&lt;figure&gt;&lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/0v4oUcdycjE?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Elon Musk: Using Reusable Rockets To Build Solar-Powered AI Data Centers In Space Is &#039;A No-Brainer&#039;&quot;&gt;&lt;/iframe&gt;&lt;figcaption&gt;&lt;p&gt;&lt;span&gt;Das Interview in Davos fuehrte Blackrock CEO Larry Fink. Blackrock hat einen Anteil an Tesla von um die 5% (Wert ca. $85 Mrd.) und ist bei SpaceX (Pre IPO) mit 300 Millionen eingestiegen. Mit dem SpaceX IPO plant man weitere $5-10 Mrd. zu investieren!&lt;/span&gt;&lt;/p&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;p&gt;Wartet kurz. &lt;em&gt;Wenn xAI seine irdischen Rechenzentren schon nicht voll auslasten kann – warum braucht es dann ueberhaupt welche im Orbit?&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Die Antwort steht im S-1. Im Risk-Factor-Abschnitt. Im selben Dokument, das die Investoren ueberzeugen soll. Heisst also: Im SEC-Pflichttext, fuer den Musk persoenlich haftet, beschreibt SpaceX dieselbe Orbital-AI-Initiative woertlich als: &lt;strong&gt;&quot;in early stages, involve significant technical complexity and unproven technologies, and may not achieve commercial viability&quot;&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Auf der WEF-Buehne: &quot;no-brainer&quot;. Im SEC-Filing: &quot;may not achieve commercial viability&quot;. Es ist eine so unfassbare Clownshow!&lt;/p&gt;&lt;div data-kg-toggle-state=&quot;close&quot;&gt;
            &lt;div&gt;
                &lt;h4&gt;&lt;span&gt;Bonus-Rant: Orbitale Rechenzentren (anklicken!)&lt;/span&gt;&lt;/h4&gt;
                &lt;/div&gt;
            &lt;div&gt;&lt;p&gt;&lt;span&gt;Den Kern des IPO-Pitches bildet eine Vision, die ich euch nicht vorenthalten moechte: SpaceX will eine Million Satelliten starten, die als orbitale Rechenzentren direkt Solarenergie im All nutzen.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Die Logik: Terrestrische Rechenzentren stossen an Grenzen bei Land, Energie und Kuehlung. Also bauen wir sie im All.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Klingt doch logisch, oder? Jaaaaa... ne, nicht wirklich!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Kuehlung im Vakuum funktioniert nicht wie auf der Erde — kein Luftstrom, keine Konvektion, nur Infrarotstrahlung ueber riesige Radiatoren. Ein Startup hat vor Kurzem einen Satelliten in der Groesse eines kleinen Kuehlschranks mit einem einzigen Nvidia-H100-Chip gestartet. Der Chip konnte ein kleines KI-Modell trainieren — musste aber regelmaessig abschalten, weil er ueberhitzte. Fuer die naechste Version plant das Unternehmen das zweitgroesste Kuehlradiator-Array im All. Das groesste ist uebrigens auf der Internationalen Raumstation. Nur damit die Groesenordnung dieses Bullshitting klar wird!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Fuer die von Musk angesprochene Gigawatt-Kapazitaet wuerden Solar- und Kuehlungsarrays von rund vier Kilometern Laenge benoetigt. Das entspricht etwa 40 Fussballfeldern — fragil, im Weg von Weltraumschrott und extrem teuer im Betrieb.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Und dann ist da noch Starship. Das gesamte Geschaeftsmodell basiert auf einem Startet-im-Stundentakt, mit 200 Tonnen Nutzlast pro Flug. Aktuell ist Starship noch in der Phase, die SpaceX intern als &quot;Rapid Unscheduled Disassembly&quot; bezeichnet. Auf Deutsch: Es explodiert noch gelegentlich.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span&gt;Als Bonus hat Musk eine Mondfabrik vorgeschlagen, die Satelliten per elektromagnetischem Maschinengewehr ins All schiesst. Die US Navy hat 16 Jahre und 500 Millionen Dollar in genau diese Technologie investiert — ohne Erfolg. Aber vielleicht klappt es ja im Weltraum besser 🤡&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;
        &lt;/div&gt;&lt;p&gt;Sam Altman, immerhin Chef von OpenAI, hat es auf einer Konferenz in Neu-Delhi unverbluemter formuliert: &quot;I honestly think the idea with the current landscape of putting data centers in space is ridiculous.&quot; Orbital-Datacenter wuerden in diesem Jahrzehnt nicht im relevanten Massstab existieren. Selbst Google rechnet damit, dass kommerzielle Orbital-Compute erst Mitte der 2030er Jahre sinnvoll werde – wenn die Launch-Kosten unter 200 Dollar pro Kilogramm fallen.&lt;/p&gt;&lt;p&gt;Uebrigens... da haette ich noch ein Schmankerl:&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://fortune.com/2026/02/06/elon-musk-space-based-ai-data-centers-spacex-hyperscaler-starship/?queryly=related_article&amp;amp;ref=metacheles.de&quot;&gt;&lt;div&gt;&lt;p&gt;Musk predicts more AI capacity will be in orbit than on earth in 5 years, with SpaceX becoming a ‘hyper-hyper’ scaler | Fortune&lt;/p&gt;&lt;p&gt;Musk said getting all that AI and solar capacity in space will require about 10,000 launches a year—or a launch in less than an hour every day.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/apple-touch-icon-4badb99efe0dfbdaf47c7dcd36618ed659bd86a53575bc36cdae3582d9759c29.png&quot; alt&gt;&lt;span&gt;Fortune&lt;/span&gt;&lt;span&gt;Jason Ma&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/GettyImages-2184685180-e1770390588141-fabf4c593c0f13e0e62a83b6c2804392d80a3f34cea2f1ef9bd26bf727e3f470.jpg&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;blockquote&gt;Musk said getting all that AI and solar capacity in space will require about 10,000 launches a year—or a launch in less than an hour every day. SpaceX is the most prolific rocket company and set a record last year with 165 orbital launches. &lt;p&gt;SpaceX could pull off a 10,000-per-year launch cadence with 20 to 30 Starship rockets, he added, though the company will make more than that, enabling perhaps 20,000 to 30,000 launches a year.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Alle 60 Minuten einen Start der Starship Rakete ist ziemlich sportlich fuer eine Company, die alle paar Monate mal eine dieser Dinger explodieren laesst!&lt;/p&gt;&lt;p&gt;Ihr merkt es sicherlich schon... die &quot;Orbital-AI&quot;-Story ist keine technische Vision. Sie ist ein &lt;strong&gt;Bewertungs-Artefakt&lt;/strong&gt;. Sie muss da sein, weil sonst die Luecke zwischen 19 Milliarden Umsatz und 1,75 Billionen Bewertung nicht zu fuellen ist. Matt Levine von Bloomberg hat es boese pointiert: SpaceX schreibt im S-1, man habe &quot;t&lt;strong&gt;he largest actionable total addressable market in human history&lt;/strong&gt;&quot; identifiziert. Levines Kommentar: &quot;&lt;strong&gt;The upper bound on SpaceX&#039;s TAM is the gross domestic product of the universe.&lt;/strong&gt;&quot;&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-26.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-26.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-26.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-26.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-26.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Und es kommt noch hirnrissiger. Anthropic ist der direkte Konkurrent von xAI. Im KI-Geschaeft kaempfen beide um dieselben Enterprise-Kunden. Aber Anthropic finanziert mit seinen Compute-Zahlungen jetzt SpaceX! Uuuuuuuund..... die koennen kuendigen und das mit einer nur 90 taegigen Frist.&lt;/p&gt;&lt;p&gt;Heisst also: Falls es zu einem Bruch zwischen Musk und Anthropic kommt – oder ein anderer Konflikt aufpoppt – verliert SpaceX mit drei Monaten Vorwarnung rund 15 Milliarden Dollar Jahresumsatz.&lt;/p&gt;&lt;p&gt;Das ist kein robustes Geschaeftsmodell. Das ist eine spektakulaer hochbewertete Wette darauf, dass Anthropic Compute kauft und niemand ueber das Vertragskleingedruckte spricht.&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/CleanShot-2026-05-30-at-21.08.17.png&quot; alt loading=&quot;lazy&quot; width=&quot;1419&quot; height=&quot;623&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/CleanShot-2026-05-30-at-21.08.17.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/CleanShot-2026-05-30-at-21.08.17.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/CleanShot-2026-05-30-at-21.08.17.png 1419w&quot; sizes=&quot;(min-width: 720px) 720px&quot;&gt;&lt;/figure&gt;&lt;h2 id=&quot;das-grundprinzip-des-schemas-indexfonds&quot;&gt;Das Grundprinzip des Schemas: Indexfonds&lt;/h2&gt;&lt;p&gt;Ok, wir atmen mal kurz ein wenig ruhig und sammeln uns wieder... ich weiss, dass das nicht einfach ist und ich muss euch jetzt schon einmal enttaeuschen: es wird nicht besser!&lt;/p&gt;&lt;p&gt;Bis hier hin habt ihr zwei Dinge gesehen: Erstens, wie Musk schon heute Geld zwischen seinen Firmen verschiebt. Zweitens, wie er die Story konstruiert, die die Bewertung tragen muss. Jetzt kommt das eigentliche Geschaeftsmodell des IPOs. Und dafuer muesst ihr verstehen, was Indexfonds sind... halt nicht nur das, vor allen Dingen auch, warum sie so erfolgreich wurden. Also mal kurz und knapp zusammengefasst:&lt;/p&gt;&lt;p&gt;Ein Index ist eine Liste. Jemand entscheidet, welche Firmen draufkommen. Ein Fonds ist ein Korb. Jemand baut den Fonds so, dass er die Liste spiegelt. Wird eine Firma in den Index aufgenommen, muss jeder Fonds, der den Index nachbildet, Aktien dieser Firma kaufen. Nicht, weil sie denken, das sei eine gute Investition. Sondern weil die Regeln das vorschreiben!&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-36.png&quot; alt loading=&quot;lazy&quot; width=&quot;1672&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-36.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-36.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-36.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-36.png 1672w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Indexfonds sind eine der seltenen Erfindungen der Finanzbranche, die Kleinanlegerinnen und Kleinanleger wirklich reicher gemacht haben. Sie haben aktive Fondsmanager in jedem Markt, in jedem Land, ueber jeden Zeitraum, geschlagen! Fast ein Drittel des amerikanischen Aktienvermoegens ist in Indexfonds gebunden. Die meisten amerikanischen Rentenkonten ebenfalls.&lt;/p&gt;&lt;p&gt;Einer der populaersten Indizes ist der Nasdaq-100. Die 100 groessten nicht-finanziellen Aktien an der Nasdaq. Und nach den bisherigen Regeln war SpaceX dafuer nicht qualifiziert. Neue Firmen mussten bis zu einem Jahr warten. Das nennt sich &quot;&lt;strong&gt;Seasoning&lt;/strong&gt;&quot; – die Aktie muss eine Weile oeffentlich gehandelt werden, damit der Markt versteht, was sie eigentlich wert ist.&lt;/p&gt;&lt;p&gt;Und genau diese Regel hat die Nasdaq in diesem Fruehjahr einfach mal geaendert.&lt;/p&gt;&lt;h2 id=&quot;die-regelaenderung-die-alles-ermoeglicht&quot;&gt;Die Regelaenderung, die alles ermoeglicht&lt;/h2&gt;&lt;p&gt;Im Maerz 2026 hat die Nasdaq eine neue &quot;Fast Entry&quot;-Regel eingefuehrt. Wenn ein riesiges Unternehmen an die Boerse geht, kommt es in 15 Handelstagen in den Index. Kein Seasoning. Keine Wartezeit. Zusaetzlich wurde die 10-Prozent-Free-Float-Mindesthuerde abgeschafft und ein 3-fach-Multiplikator fuer kleine Floats eingebaut. Es gab eine oeffentliche Kommentierungsphase. Die Wall Street war dafuer. Die einzigen Gegner waren – Ueberraschung – Kleinanleger.&lt;/p&gt;&lt;p&gt;Jeffrey Kluge nennt die Regelaenderung in seinem SSRN-Papier von April 2026 einen &quot;&lt;strong&gt;bespoke red carpet&lt;/strong&gt;&quot; – einen massgeschneiderten roten Teppich – fuer SpaceX. Aber die Regelaenderung ist nicht das Ziel. Das Ziel ist, was die Regelaenderung ermoeglicht. Und das ist ein vierstufiger Plan.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Stufe 1: Kuenstliche Knappheit.&lt;/strong&gt; Bei einem normalen IPO werden 15 bis 20 Prozent der Aktien an der Boerse angeboten. SpaceX? Weniger als 5 Prozent.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Stufe 2: Hohe Allokation an Kleinanleger.&lt;/strong&gt; Bei normalen IPOs bekommen institutionelle Investoren – Pensionsfonds, Banken, Versicherungen – etwa 90 Prozent. Privatleute kriegen 10. SpaceX kehrt das teilweise um: 30 Prozent gehen an Kleinanleger ueber Schwab, Fidelity, Robinhood, SoFi und Morgan Stanleys E*TRADE. &quot;Main Street, not Wall Street&quot; lautet die PR-Story. Die Fanboys jubeln und ich glaube Elon Musk noch ein wenig umfangreicher!&lt;/p&gt;&lt;p&gt;Denn was er denen nicht erzaehlt: Wenn ein IPO eine ungewoehnlich hohe Allokation an Kleinanleger macht, ist das normalerweise ein Zeichen dafuer, dass die Profis nicht zu diesem Preis kaufen wollen. Der Preis ist verrueckt. Und wenn du es den Profis nicht verkaufen kannst, verkaufst du es an Leute, die es nicht besser wissen.&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-31.png&quot; alt loading=&quot;lazy&quot; width=&quot;1537&quot; height=&quot;1023&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-31.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-31.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-31.png 1537w&quot; sizes=&quot;(min-width: 720px) 720px&quot;&gt;&lt;/figure&gt;&lt;p&gt;&lt;strong&gt;Stufe 3: Fast Entry in den Nasdaq-100.&lt;/strong&gt; 15 Handelstage nach dem IPO landet SpaceX im Index. Jeder Indexfonds, der den Nasdaq-100 abbildet, MUSS jetzt SpaceX-Aktien kaufen. Chan Ahn, frueher bei Goldman Sachs und JPMorgan, jetzt CEO bei Tessera, hat das Zwangskaufvolumen in einem Benzinga-Interview im Mai 2026 beziffert: zwischen &lt;strong&gt;22 und 27 Milliarden Dollar&lt;/strong&gt; an erzwungenen ETF-Kaeufen allein von physisch hinterlegten Indexfonds. Ueber das gesamte Nasdaq-100-Oekosystem inklusive aktiver Benchmark-Mandate koennten es &lt;strong&gt;mehr als 60 Milliarden&lt;/strong&gt; werden. Eine Mauer aus Geld, die kaufen muss, egal zu welchem Preis. Das treibt den Kurs ins Absurde.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Stufe 4: Auszahlung der fruehen Investoren.&lt;/strong&gt; Es gibt Restriktionen – sogenannte Lock-Up-Perioden. Elon selbst muss laut Prospekt ein Jahr warten. Aber die Lock-Up-Struktur fuer andere fruehe Investoren ist ungewoehnlich gestaffelt: 20 Prozent koennen schon nach 70 Tagen verkauft werden, dann 10 Prozent, dann jeweils 7 Prozent in mehreren Tranchen. Wer kauft, waehrend der Preis steigt? Die Rentensparer ueber ihre Indexfonds. Wer verkauft? Die urspruenglichen SpaceX-, Twitter- und xAI-Investoren.&lt;/p&gt;&lt;p&gt;Bag-Holder! Und der Sack heisst Bob, Karen und Mike aus Ohio... ok, ich diversifiziere noch ein wenig: Uschi aus Castrop, Max aus Berlin und Simon aus Taipei sind auch noch mit am Start. Alles selbsternannte Expert:innen, die zwischen Fintech-TikTok und Twitter keine freie Minute mehr finden!&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-25.png&quot; alt loading=&quot;lazy&quot; width=&quot;1671&quot; height=&quot;941&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-25.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-25.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1600/2026/05/image-25.png 1600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-25.png 1671w&quot; sizes=&quot;(min-width: 1200px) 1200px&quot;&gt;&lt;/figure&gt;&lt;h2 id=&quot;nasdaq-ist-hier-nicht-neutral&quot;&gt;Nasdaq ist hier nicht neutral&lt;/h2&gt;&lt;p&gt;Wer glaubt, Nasdaq habe diese Regel einfach so geaendert, weil sich &quot;der Markt weiterentwickelt&quot; – wie es die offizielle Stellungnahme behauptet – der glaubt auch, dass Elon Musk seine Twitter-Investition aus Liebe zur Meinungsfreiheit getaetigt hat.&lt;/p&gt;&lt;p&gt;Der Nasdaq ist zwei Dinge in einer Firma: Er ist ein Indexanbieter UND eine Boerse. Diese beiden Funktionen werden nicht sauber getrennt. Die New York Stock Exchange und Nasdaq konkurrieren um jedes grosse Listing. Und SpaceX war der Preis!&lt;/p&gt;&lt;p&gt;Laut Reuters hat Musk bei der Frage, wo SpaceX gelistet wird, eine Bedingung gestellt: Fast-Track in den Index. Die Nasdaq hat geliefert. Sie verdient an SpaceX nicht nur die Listing-Gebuehren. Das richtig dicke Geld kommt ueber die Daten- und Handelsgebuehren, die sie ueber Jahre an andere Investmentfirmen verkaufen.&lt;/p&gt;&lt;p&gt;Und das Beste: Niemand hat das genehmigt. Die Securities and Exchange Commission, die US-Boersenaufsicht, muss solche Indexaenderungen ueberhaupt nicht absegnen. Mehr als 30 Billionen Dollar Vermoegen werden durch ein System gelenkt, das sich effektiv selbst reguliert. Die einzige Kontrolle ist der interne Kommentierungsprozess des Indexanbieters selbst.&lt;/p&gt;&lt;p&gt;Ja, ihr habt richtig gelesen. Der Indexanbieter prueft seine eigenen Regelaenderungen. Man moechte fast die wilde These in den Ring schmeissen, dass Musk auch noch diesen Laden managed!&lt;/p&gt;&lt;h2 id=&quot;wer-das-wirklich-kontrolliert&quot;&gt;Wer das wirklich kontrolliert&lt;/h2&gt;&lt;p&gt;Damit kommen wir zur Frage, wer SpaceX nach dem IPO eigentlich gehoert. Spoiler: Im wirtschaftlichen Sinne ein paar Tausend Aktionaere. Im rechtlichen Sinne genau einer Person!&lt;/p&gt;&lt;p&gt;Musk haelt nach Vollzug des IPOs &lt;strong&gt;85,1 Prozent der Stimmrechte&lt;/strong&gt; – bei einem wirtschaftlichen Anteil von rund 41 bis 42 Prozent. Moeglich macht das eine Dual-Class-Struktur: Class-A-Aktien fuer den Markt mit einer Stimme pro Aktie. Class-B-Aktien fuer Musk mit zehn Stimmen pro Aktie. Im S-1 steht woertlich: &quot;&lt;strong&gt;This will limit or preclude your ability to influence corporate matters and the election of our directors.&lt;/strong&gt;&quot; Auf gut Deutsch: Liebe Aktionaere, ihr habt nichts zu melden.&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-33.png&quot; alt loading=&quot;lazy&quot; width=&quot;1023&quot; height=&quot;576&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2026/05/image-33.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2026/05/image-33.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/image-33.png 1023w&quot; sizes=&quot;(min-width: 720px) 720px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Dazu kommt ein Compensation-Package, das im Januar 2026 beschlossen wurde. Musks Grundgehalt: 54.080 Dollar pro Jahr. Aber er bekommt potenziell eine &lt;strong&gt;Milliarde&lt;/strong&gt; Class-B-Aktien. In 15 Tranchen. Die letzte Tranche wird erst freigegeben, wenn SpaceX eine &quot;&lt;strong&gt;permanent human colony on Mars with at least one million inhabitants&lt;/strong&gt;&quot; etabliert hat. So steht es im SEC-Filing. Eine Million Menschen auf dem Mars. SpaceX&#039; eigene Auditoren stufen das als &quot;&lt;strong&gt;improbable&lt;/strong&gt;&quot; ein – weshalb es bilanziell nicht als Aufwand erfasst wird. Bilanzielle Magie 🦄&lt;/p&gt;&lt;p&gt;Aber der eigentliche Trick: Musk darf bereits &lt;strong&gt;vor&lt;/strong&gt; der Erfuellung dieser Meilensteine mit diesen Aktien abstimmen, sie als Sicherheit fuer Kredite verpfaenden und sie in Trusts mit Super-Voting-Status fuer seine 14-plus Kinder ueberfuehren. Mars-Kolonie oder nicht.&lt;/p&gt;&lt;p&gt;Und falls jemand auf die Idee kommen sollte, Musk dafuer zu verklagen: SpaceX hat sich nach Texas reinkorporiert. Das Texas-Gesetz SB29 erlaubt es boersennotierten Firmen, eine 3-Prozent-Schwelle fuer Derivative Lawsuits zu setzen. Bei 1,75 Billionen Dollar Bewertung entspricht das 52 Milliarden Dollar Aktienbesitz. Praktisch koennen nur &lt;strong&gt;Musk&lt;/strong&gt;, &lt;strong&gt;BlackRock&lt;/strong&gt; und &lt;strong&gt;Vanguard&lt;/strong&gt; ueberhaupt klagen. Anne Lipton von der University of Colorado Law School &lt;a href=&quot;https://www.nytimes.com/2026/05/26/technology/spacex-elon-musk-pay-board-governance.html?ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;nennt das&lt;/strong&gt;&lt;/a&gt; &quot;&lt;strong&gt;die exotischste Compensation-Konstruktion, die im US-Aktienmarkt je in einer Mega-IPO vorgelegt wurde&lt;/strong&gt;&quot;. Und sie laesst sich praktisch nicht angreifen.&lt;/p&gt;&lt;p&gt;Uebrigens: 2022 entschied der Delaware Court of Chancery im Fall Tornetta v. Musk, dass Musks 56-Milliarden-Dollar-Tesla-Compensation-Package unzulaessig sei. Musks Reaktion: Reinkorporation nach Texas und Wiederholung des Pakets. Die Lektion: Wenn ein Gericht Musk nicht passt, sucht er sich ein anderes Gericht. Das ist die Governance-Realitaet, in die ihr investiert.&lt;/p&gt;&lt;figure data-kg-thumbnail=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Tornetta-v.-Musk-Case-Brief-Summary---Law-Case-Explained_thumb.jpg&quot; data-kg-custom-thumbnail=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2026/05/CleanShot-2026-05-30-at-22.02.23.png&quot;&gt;
            &lt;div&gt;
                &lt;video src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Tornetta-v.-Musk-Case-Brief-Summary---Law-Case-Explained.mp4&quot; poster=&quot;https://img.spacergif.org/v1/1280x720/0a/spacer.png&quot; width=&quot;1280&quot; height=&quot;720&quot; playsinline preload=&quot;metadata&quot;&gt;&lt;/video&gt;
                
                &lt;div&gt;
                        &lt;p&gt;
                        
                        &lt;span&gt;0:00&lt;/span&gt;&lt;/p&gt;&lt;p&gt;
                            /&lt;span&gt;2:22&lt;/span&gt;
                        &lt;/p&gt;
                        &lt;/div&gt;
            &lt;/div&gt;
            &lt;figcaption&gt;&lt;p&gt;&lt;span&gt;Tornetta vs Musk&lt;/span&gt;&lt;/p&gt;&lt;/figcaption&gt;
        &lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/media/2026/05/Tornetta-v.-Musk-Case-Brief-Summary---Law-Case-Explained_thumb.jpg&quot;&gt;&lt;/figure&gt;&lt;h2 id=&quot;und-es-geht-noch-weiter-der-sp-macht-es-nach&quot;&gt;Und es geht noch weiter: Der S&amp;amp;P macht es nach&lt;/h2&gt;&lt;p&gt;Wenn ihr jetzt denkt, das sei ein Einzelfall – nee. &lt;a href=&quot;https://www.bloomberg.com/graphics/2026-spacex-ipo-stock-market-nasdaq-listings/?leadSource=uverify%20wall&amp;amp;embedded-checkout=true&amp;amp;ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;Bloomberg berichtet&lt;/strong&gt;&lt;/a&gt;, dass der S&amp;amp;P 500 – der wichtigste Index der Welt – ebenfalls darueber nachdenkt, was Nasdaq gerade durchgezogen hat. Verkuerzte Seasoning-Periode. Aufnahme von Megakonzernen, die noch nie einen Dollar Gewinn gemacht haben.&lt;/p&gt;&lt;p&gt;Warum? Weil OpenAI und Anthropic in den naechsten Monaten an die Boerse gehen koennten. Mit absurden Bewertungen. Keine davon profitabel. Auch hier wird die Kommentierungsphase gerade durchgenudelt. Sie endet Anfang Juni... excuse my French, aber Leckopfanni ist das alles schrill!&lt;/p&gt;&lt;p&gt;Wir reden hier nicht ueber ein technisches Detail im Finanzmarkt-Klein-Klein. Wir reden ueber die Frage, wer in den naechsten Jahren reicher und wer aermer wird. Und die Antwort schreiben sich die grossen Tech-Investoren gerade selbst auf, mit Hilfe der Indexanbieter, die zufaellig auch Boersen sind. Und ohne dass irgendjemand etwas daran genehmigen muss.&lt;/p&gt;&lt;figure&gt;&lt;iframe width=&quot;200&quot; height=&quot;113&quot; src=&quot;https://www.youtube.com/embed/sYA-z0Y8WRQ?feature=oembed&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen title=&quot;Did Elon Musk Just Rig the Stock Market?&quot;&gt;&lt;/iframe&gt;&lt;/figure&gt;&lt;h2 id=&quot;was-das-mit-uns-zu-tun-hat&quot;&gt;Was das mit uns zu tun hat&lt;/h2&gt;&lt;p&gt;Ihr fragt euch jetzt vielleicht: Sascha, was geht uns das in Europa an?&lt;/p&gt;&lt;p&gt;Eine ganze Menge. Weil etliche europaeische Anlegerinnen und Anleger – auch wir deutschsprachigen – ueber MSCI World, ueber FTSE All-World, ueber S&amp;amp;P-500-ETFs – in genau diesen Indizes investieren. Wir sind alle drin. Auf die eine oder andere Art. Was hier passiert, das betrifft auch unsere Altersvorsorge und zwar umfangreichst!&lt;/p&gt;&lt;p&gt;Die ETFs, ueber die wir uns Jahre lang die digitalen Patte gerieben haben, weil sie endlich mal nicht die Versicherungs- und Bankprovisionsmuelltonnen waren, werden gerade in eine Goldgrube fuer Silicon-Valley-Investoren umgebaut. Und wir merken es nicht, weil wir – zu Recht – die Idee verinnerlicht haben: Indexfonds sind sicher, passiv, regelbasiert.&lt;/p&gt;&lt;p&gt;Well.... diese Regeln werden gerade umgeschrieben. Vor unseren Augen. Damit Elon Musk Billionaer wird!&lt;/p&gt;&lt;p&gt;Und es kommt noch eine zweite Dimension dazu, die mich als jemanden, der seit ueber 15 Jahren von Taiwan aus auf die digitale Welt schaut, besonders aergert: Starlink und Starshield sind inzwischen kritische westliche Verteidigungsinfrastruktur. Vom ukrainischen Drohnenkrieg bis zur NRO-Spionage. Europa hat mit IRIS2 ein Gegenprojekt – Vollbetrieb fruehestens 2030. Fuenf bis sieben Jahre Rueckstand. Bis dahin sind Bundeswehr, ESA und EU-Sicherheitsarchitektur abhaengig von einer in Texas inkorporierten Privatfirma unter Einzelkontrolle eines Mannes, der 2022 in der Ukraine eigenmaechtig Starlink fuer eine Drohnenoperation abgeschaltet hat! &lt;/p&gt;&lt;p&gt;Und jetzt wird genau diese Firma an die Boerse gebracht – und wir kaufen sie ueber unsere ETFs mit. Das ist nicht nur finanzielle, sondern auch strategische Selbstuntergrabung.&lt;/p&gt;&lt;h2 id=&quot;fazit&quot;&gt;Fazit&lt;/h2&gt;&lt;p&gt;Ich bin grundsaetzlich ein Freund davon, dass Menschen sich aktiv an Aktienmaerkten beteiligen. Ich bin grundsaetzlich ein Freund von Indexfonds. Ich rate seit Jahren dazu, weil sie nachweislich besser performen als 99 Prozent der aktiven Fondsmanager.&lt;/p&gt;&lt;p&gt;Aber was hier passiert, ist keine Marktentwicklung. Das ist eine orchestrierte Vermoegensumverteilung. Eric Newcomer und sein Team haben das in ihrer Recherche ausserordentlich gut aufgedroeselt. Ben Schiffrin, 18 Jahre bei der SEC, sagt es selbst: &quot;Ich versuche optimistisch zu bleiben, aber das ist ein Setup fuer ziemlich missbraeuchliche Marktmanipulation. Legal? Wahrscheinlich. Ethisch? Definitiv nicht.&quot;&lt;/p&gt;&lt;p&gt;Was ihr tun koennt: Wenn ihr betroffen seid, schaut euch eure ETF-Bestaende an. Lest die Indexregeln. Macht euch klar, dass auch passive Investments politischen Entscheidungen unterworfen sind.&lt;/p&gt;&lt;p&gt;Dieser SpaceX-IPO wird die Boersengeschichte schreiben. Bleibt nur die Frage, auf welcher Seite ihr stehen wollt... und das war hier uebrigens keine Aufforderung dieses Kartenhaus zu shorten!&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;em&gt;Dir hat diese Ausgabe gefallen? Dann teile diese doch mit deinem Netzwerk.&amp;nbsp;MeTacheles ist kostenlos, extrem zeitaufwendig &amp;amp; genau deshalb spiele ich jetzt auch ein wenig Staubsaugervertreter 😎&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Zum Podcast&lt;/strong&gt;:&amp;nbsp;&lt;a href=&quot;https://podcasts.apple.com/de/podcast/metacheles-tonspur/id1615163239?ref=metacheles.de&quot;&gt;Apple&lt;/a&gt;&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://open.spotify.com/show/1u9cHXItGCXCKzjGqTCANH?ref=metacheles.de&quot;&gt;Spotify&lt;/a&gt;&amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://music.amazon.de/podcasts/cfd2d49c-efd7-4152-8c7c-9e283a94dff8/metacheles-tonspur?ref=metacheles.de&quot;&gt;Amazon&lt;/a&gt;&amp;nbsp;oder&amp;nbsp;&lt;a href=&quot;https://t.ly/MeTaRSS?ref=metacheles.de&quot; rel=&quot;noreferrer&quot;&gt;RSS-Feed&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Bleibt gesund!&lt;/p&gt;&lt;h2 id=&quot;sascha&quot;&gt;Sascha&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; Meine Infografiken wurden durch eine KI erstellt, ich frage mich aber wirklich, ob ich dies einzeln angeben muss? Wenn ich was mit Canva mache, dann erklaere ich das ja auch nicht!&lt;/p&gt;&lt;p&gt;Bei der Recherche kam vor allen Dingen Perplexity, aber auch Claude AI zum Einsatz. Der Text wurde jedoch zu 100% von einem in Taiwan lebenden Europaaer mit nem deutschen Pass geschrieben aka mir!&lt;/p&gt;&lt;h2 id=&quot;quellen&quot;&gt;Quellen&lt;/h2&gt;&lt;h2 id=&quot;primaerdokument&quot;&gt;Primaerdokument&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;SpaceX S-1 Filing (SEC, 20.5.2026)&lt;/strong&gt; – Bewertung, Finanzen, Risikofaktoren, Governance, Related-Party-Transaktionen, Compensation-Package, Mars-Klausel, Orbital-AI-Risk-Disclosure, Anthropic-Compute-Deal, Cybertruck-Kaeufe &lt;a href=&quot;https://www.sec.gov/Archives/edgar/data/1181412/000162828026036936/spaceexplorationtechnologi.htm?ref=metacheles.de&quot;&gt;https://www.sec.gov/Archives/edgar/data/1181412/000162828026036936/spaceexplorationtechnologi.htm&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;hr&gt;&lt;h2 id=&quot;pressequellen&quot;&gt;Pressequellen &lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;strong&gt;Reuters&lt;/strong&gt; – &quot;SpaceX says unproven AI space data centers may not be commercially viable, filing shows&quot;  – &lt;a href=&quot;https://www.reuters.com/world/spacex-says-unproven-ai-space-data-centers-may-not-be-commercially-viable-filing-2026-04-21/?ref=metacheles.de&quot;&gt;https://www.reuters.com/world/spacex-says-unproven-ai-space-data-centers-may-not-be-commercially-viable-filing-2026-04-21/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Reuters&lt;/strong&gt; – &quot;SpaceX posted nearly $5 billion loss in 2025, The Information reports&quot; – Verlustzahlen 2025 &lt;a href=&quot;https://www.reuters.com/science/spacex-posted-nearly-5-billion-loss-2025-information-reports-2026-04-10/?ref=metacheles.de&quot;&gt;https://www.reuters.com/science/spacex-posted-nearly-5-billion-loss-2025-information-reports-2026-04-10/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Fortune&lt;/strong&gt; – &quot;Rollout complete: SpaceX files IPO prospectus&quot; &lt;a href=&quot;https://fortune.com/2026/05/21/rollout-complete-spacex-files-ipo-prospectus/?ref=metacheles.de&quot;&gt;https://fortune.com/2026/05/21/rollout-complete-spacex-files-ipo-prospectus/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Fortune&lt;/strong&gt; – &quot;SpaceX IPO targets $28.5 trillion total addressable market&quot; – TAM-Marketing &lt;a href=&quot;https://fortune.com/2026/05/20/spacex-ipo-filing-s1-total-addressable-market-make-life-multiplanetary/?ref=metacheles.de&quot;&gt;https://fortune.com/2026/05/20/spacex-ipo-filing-s1-total-addressable-market-make-life-multiplanetary/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;CNBC&lt;/strong&gt; – &quot;SpaceX&#039;s historic IPO plans: Billions in losses and Musk&#039;s massive ownership&quot; – Governance, Voting-Struktur &lt;a href=&quot;https://www.cnbc.com/2026/05/20/spacex-ipo-live-updates.html?ref=metacheles.de&quot;&gt;https://www.cnbc.com/2026/05/20/spacex-ipo-live-updates.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;New York Times&lt;/strong&gt; – &quot;Elon Musk&#039;s SpaceX IPO&quot; &lt;a href=&quot;https://www.nytimes.com/2026/05/20/technology/elon-musk-spacex-ipo.html?ref=metacheles.de&quot;&gt;https://www.nytimes.com/2026/05/20/technology/elon-musk-spacex-ipo.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;TechCrunch&lt;/strong&gt; – &quot;Anthropic will pay xAI $1.25B per month for compute&quot; (20.5.2026) – Anthropic-Compute-Vertrag &lt;a href=&quot;https://techcrunch.com/2026/05/20/anthropic-will-pay-xai-1-25-billion-per-month-for-compute/?ref=metacheles.de&quot;&gt;https://techcrunch.com/2026/05/20/anthropic-will-pay-xai-1-25-billion-per-month-for-compute/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Axios&lt;/strong&gt; – &quot;Anthropic is paying SpaceX $15 billion per year&quot; – Annualisiertes Volumen Anthropic-Deal &lt;a href=&quot;https://www.axios.com/2026/05/20/anthropic-spacex-compute?ref=metacheles.de&quot;&gt;https://www.axios.com/2026/05/20/anthropic-spacex-compute&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tagesschau&lt;/strong&gt; – &quot;SpaceX Boersengang&quot; – NASDAQ-Index-Regelaenderung aus deutscher Perspektive &lt;a href=&quot;https://www.tagesschau.de/wirtschaft/unternehmen/spacex-boersengang-100.html?ref=metacheles.de&quot;&gt;https://www.tagesschau.de/wirtschaft/unternehmen/spacex-boersengang-100.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Ars Technica&lt;/strong&gt; – &quot;As Grok flounders, SpaceX bets future on beating Big Tech at AI&quot; &lt;a href=&quot;https://arstechnica.com/ai/2026/05/as-grok-flounders-spacex-bets-future-on-beating-big-tech-at-ai/?ref=metacheles.de&quot;&gt;https://arstechnica.com/ai/2026/05/as-grok-flounders-spacex-bets-future-on-beating-big-tech-at-ai/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ComputerBase&lt;/strong&gt; – &quot;Grok und xAI am Scheideweg: Auf Musks Supercomputer laeuft kuenftig Anthropic Claude&quot; &lt;a href=&quot;https://www.computerbase.de/news/wirtschaft/grok-und-xai-am-scheideweg-auf-musks-supercomputer-laeuft-kuenftig-anthropic-claude.97240/?ref=metacheles.de&quot;&gt;https://www.computerbase.de/news/wirtschaft/grok-und-xai-am-scheideweg-auf-musks-supercomputer-laeuft-kuenftig-anthropic-claude.97240/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Storyboard18&lt;/strong&gt; – &quot;Anthropic to pay xAI $1.25 billion a month in massive compute deal&quot; &lt;a href=&quot;https://www.storyboard18.com/digital/anthropic-to-pay-xai-1-25-billion-a-month-in-massive-compute-deal-ws-l-98757.htm?ref=metacheles.de&quot;&gt;https://www.storyboard18.com/digital/anthropic-to-pay-xai-1-25-billion-a-month-in-massive-compute-deal-ws-l-98757.htm&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2024/02/Divider--1--9.jpg&quot; alt loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;40&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2024/02/Divider--1--9.jpg 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2024/02/Divider--1--9.jpg 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2024/02/Divider--1--9.jpg 1280w&quot; sizes=&quot;(min-width: 720px) 720px&quot;&gt;&lt;/figure&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2025/01/CleanShot-2025-01-30-at-08.25.02.png&quot; alt loading=&quot;lazy&quot; width=&quot;1305&quot; height=&quot;560&quot; srcset=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w600/2025/01/CleanShot-2025-01-30-at-08.25.02.png 600w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1000/2025/01/CleanShot-2025-01-30-at-08.25.02.png 1000w, https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/2025/01/CleanShot-2025-01-30-at-08.25.02.png 1305w&quot; sizes=&quot;(min-width: 720px) 720px&quot;&gt;&lt;/figure&gt;&lt;p&gt;Ja, es gibt ein Abomodell fuer MeTacheles und ja, 30% der Umsaetze helfen dabei verschieden Baumpflanzprojekte zu unterstuetzen… und verschafft mir mehr Luft, um solche Artikel zu bauen:&lt;/p&gt;&lt;figure&gt;&lt;a href=&quot;https://www.metacheles.de/stargate-project-analyse-ai-usa-trump/&quot;&gt;&lt;div&gt;&lt;p&gt;Stargate Project Analyse - $500 Mrd fuer die AI-Herrschaft!&lt;/p&gt;&lt;p&gt;Donald Trump, frisch wiedergewaehlter US-Praesident, zieht gleich zu Beginn seiner Amtszeit die ganz grosse Karte: Ein 500-Milliarden-Dollar-Fonds namens „Stargate“. Ziel? Ein landesweites Netzwerk an Rechenzentren fuer kuenstliche Intelligenz aus dem Boden stampfen. Klingt nach Science Fiction, koennte aber die Grundlage fuer Amerikas naechste Tech-Dominanz werden. 💡Aktuelle Ausgaben werden u.a.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/Copy-of-Copy-of-Copy-of-metacheles-9.png&quot; alt&gt;&lt;span&gt;MeTacheles&lt;/span&gt;&lt;span&gt;Sascha Pallenberg&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/StarGate-Project-1.jpg&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href=&quot;https://www.metacheles.de/deepseek-r1-im-faktencheck-ai-hype-aus-china/&quot;&gt;&lt;div&gt;&lt;p&gt;DeepSeek R1 im Faktencheck - AI Hype aus China?!&lt;/p&gt;&lt;p&gt;DeepSeek R1 heisst der neue Hype in der AI-Welt und laesst die Werte der US-Techfirmen an den Boersen abstuerzen. Aber warum eigentlich? Ich erklaere euch in dieser Ausgabe was es damit auf sich hat, warum der Hype und diverse Statements einfach kompletter Quatsch sind, aber auch, warum es sich dabei&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/icon/Copy-of-Copy-of-Copy-of-metacheles-10.png&quot; alt&gt;&lt;span&gt;MeTacheles&lt;/span&gt;&lt;span&gt;Sascha Pallenberg&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/thumbnail/Deepseek-R1.jpg&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href=&quot;https://www.metacheles.de/nachhaltigkeit-transformation-essay/&quot;&gt;&lt;div&gt;&lt;p&gt;Nachhaltigkeit ist keine Raketenwissenschaft&lt;/p&gt;&lt;p&gt;Weshalb wir die nachhaltige Transformation von Gesellschaft und Industrie nicht verkomplizieren sollten und warum wir bereits alle wichtigen Technologien haben, um uns klimaneutral aufzustellen!&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w256h256/2024/01/Copy-of-Copy-of-Copy-of-metacheles.png&quot; alt&gt;&lt;span&gt;MeTacheles&lt;/span&gt;&lt;span&gt;Sascha Pallenberg&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1200/2024/01/Cars--2-.png&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;figure&gt;&lt;a href=&quot;https://www.metacheles.de/bop-1-wir-brauchen-ein-bedingungsloses/&quot;&gt;&lt;div&gt;&lt;p&gt;Bedingungsloses Grundeinkommen - Zukunft oder Utopie?&lt;/p&gt;&lt;p&gt;Warum wir ein bedingungsloses Grundeinkommen brauchen. Ein flammendes Plaedoyer fuer mehr Gerechtigkeit, Sicherheit und Wohlstand fuer alle Gesellschaftsschichten.&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w256h256/2024/01/Copy-of-Copy-of-Copy-of-metacheles.png&quot; alt&gt;&lt;span&gt;MeTacheles&lt;/span&gt;&lt;span&gt;Sascha Pallenberg&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;p&gt;&lt;img src=&quot;https://storage.ghost.io/c/2f/3d/2f3d10ab-4dcc-4cc3-b018-1d37ac0e7f99/content/images/size/w1200/2024/01/b27684fc-4cff-42f7-91a4-e17fe2a61871_2560x1440.png&quot; alt onerror=&quot;this.style.display = &#039;none&#039;&quot;&gt;&lt;/p&gt;&lt;/a&gt;&lt;/figure&gt;&lt;p&gt;Wenn ihr meint, dass euch dies den Gegenwert eines Kaffees, Kaesekuchens oder ner Currywurst im Monat wert ist, dann koennt ihr entweder&amp;nbsp;&lt;a href=&quot;https://www.metacheles.de/youtube-zensur-kritische-kanaele-stuerzen-ab/#/portal/signup&quot; rel=&quot;noreferrer&quot;&gt;&lt;strong&gt;» HIER «&lt;/strong&gt;&lt;/a&gt;&amp;nbsp;oder auf den unteren Button klicken und aus den verschiedenen Abo-Modellen waehlen bzw. ihr koenntet ja auch ein Abo verschenken:&lt;/p&gt;
      &lt;/div&gt;</description>
            <pubDate>Mon, 01 Jun 2026 06:58:11 +0000</pubDate>
            <guid>https://www.metacheles.de/spacex-boersengang-der-groesste-bankraub-geschichte/</guid>
        </item>
        <item>
            <title>Open source was not ready for AI-speed contributions</title>
            <link>https://frenck.dev/open-source-was-not-ready-for-ai-speed-contributions/</link>
            <description>&lt;blockquote&gt;&lt;hr&gt;&lt;/blockquote&gt;&lt;div&gt;
                &lt;p&gt;If I rent an excavator to dig a hole for a swimming pool, I do not suddenly become a professional.&lt;/p&gt;&lt;p&gt;I become a person with a very powerful tool and a very real chance of making a much bigger mess. I will probably hit something I should not hit. The hole will not be level. The shape will be wrong. And after a few hours of pretending I know what I am doing, someone who actually knows this stuff has to come in and fix my garden. 🙈&lt;/p&gt;&lt;p&gt;That is how I think about AI-assisted software contributions right now.&lt;/p&gt;&lt;p&gt;AI is a tool. A powerful one. In the hands of a good developer, it can amplify output in genuinely useful ways. It can help explore code, write tests, spot patterns, draft boring glue, explain unfamiliar APIs, and remove a lot of friction. I use it that way myself.&lt;/p&gt;&lt;p&gt;But a powerful tool does not replace understanding. It amplifies whatever is already there. If there is judgment, it amplifies judgment. If there is confusion, it amplifies confusion. If there is no ownership, it creates work for someone else.&lt;/p&gt;&lt;p&gt;Open source is now feeling that very hard.&lt;/p&gt;&lt;h2 id=&quot;the-pull-request-is-not-the-finish-line&quot;&gt;The pull request is not the finish line&lt;/h2&gt;&lt;p&gt;I want to be very clear about one thing first: contributions are good. That is the whole point of open source. Someone taking the time to report a bug, improve documentation, fix an integration, or add support for a device is a good thing. &lt;strong&gt;A pull request usually means someone cared enough to try.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;That part matters. I never want maintainers, including myself, to forget it.&lt;/p&gt;&lt;p&gt;But a contribution is not finished when the pull request is opened. That is where a different kind of work starts. Someone has to understand the change, review the code, check the behavior, think about the edge cases, look at the user impact, verify tests, consider long-term maintenance, and eventually own the result after it is merged.&lt;/p&gt;&lt;p&gt;AI changes the cost of creating the first version. It does not make that second part disappear.&lt;/p&gt;&lt;p&gt;That is the asymmetry we are dealing with. Contributors are being amplified. Maintainers are still the verification bottleneck.&lt;/p&gt;&lt;h2 id=&quot;security-is-already-showing-the-shape-of-this&quot;&gt;Security is already showing the shape of this&lt;/h2&gt;&lt;p&gt;Anthropic published an initial update on &lt;a href=&quot;https://www.anthropic.com/research/glasswing-initial-update?ref=frenck.dev&quot;&gt;Project Glasswing&lt;/a&gt;, their effort around AI-assisted vulnerability discovery. The headline number is huge: more than 10,000 high- or critical-severity vulnerabilities found across important software stacks.&lt;/p&gt;&lt;p&gt;That number gets attention, of course. Big numbers always do. But the more interesting line is this one:&lt;/p&gt;&lt;blockquote&gt;“Progress on software security used to be limited by how quickly we could find new vulnerabilities. Now it’s limited by how quickly we can verify, disclose, and patch the large numbers of vulnerabilities found by AI”.&lt;/blockquote&gt;&lt;p&gt;That is the whole problem in one sentence.&lt;/p&gt;&lt;p&gt;Finding work got faster. Verifying work did not become free. Patching did not become instant. Coordinated disclosure did not become easier. Maintainers did not suddenly get more hours in a day.&lt;/p&gt;&lt;p&gt;The open-source part of that update is especially interesting. Anthropic says they scanned more than 1,000 open-source projects and identified thousands of potential high- or critical-severity vulnerabilities. At the time of their update, only a much smaller number had been patched. Some of that is expected because disclosure windows exist, and not every patch is public immediately. Still, the shape is obvious: AI can create a huge amount of legitimate-looking work faster than the ecosystem can absorb it.&lt;/p&gt;&lt;p&gt;And that is with an organized program that includes verification steps. Now imagine the same dynamic spread across normal issue trackers, pull requests, vulnerability reports, and well-meaning contributors who have access to increasingly capable tools.&lt;/p&gt;&lt;h2 id=&quot;curl-has-been-living-this-in-public&quot;&gt;curl has been living this in public&lt;/h2&gt;&lt;p&gt;Daniel Stenberg, a fellow GitHub Star and curl’s long-time maintainer, has written a lot about this from the maintainer side, and I think those posts should be required reading for anyone who thinks this is a simple “AI good” or “AI bad” discussion.&lt;/p&gt;&lt;p&gt;In &lt;a href=&quot;https://daniel.haxx.se/blog/2025/07/14/death-by-a-thousand-slops/?ref=frenck.dev&quot;&gt;Death by a thousand slops&lt;/a&gt;, he described the flood of low-quality AI-generated security reports hitting curl. The problem was not just that the reports were wrong. The problem was that every report still needed human attention. Security reports cannot simply be ignored because they look annoying. Someone has to check. Someone has to spend the time.&lt;/p&gt;&lt;p&gt;curl eventually &lt;a href=&quot;https://daniel.haxx.se/blog/2026/01/26/the-end-of-the-curl-bug-bounty/?ref=frenck.dev&quot;&gt;ended its bug bounty program&lt;/a&gt;. That changed the incentives and reduced the worst of the slop. But then Daniel wrote &lt;a href=&quot;https://daniel.haxx.se/blog/2026/04/22/high-quality-chaos/?ref=frenck.dev&quot;&gt;High-Quality Chaos&lt;/a&gt;, which is a much more interesting phase of the story. The obvious junk went down. The quality went up. Almost every report seemed to use AI in some way. The reports were better.&lt;/p&gt;&lt;p&gt;But the volume was still a problem.&lt;/p&gt;&lt;p&gt;That is the part I keep coming back to. Better AI-assisted work is still work. Higher-quality reports are much better than slop, obviously, but they still need triage, discussion, patches, releases, advisories, and judgment.&lt;/p&gt;&lt;p&gt;A few weeks later, Daniel wrote another post with the very direct title &lt;a href=&quot;https://daniel.haxx.se/blog/2026/05/26/the-pressure/?ref=frenck.dev&quot;&gt;The pressure&lt;/a&gt;. That one is harder to read because it is not really about tools anymore. It is about people. About work hours, responsibility, health, and a project that is installed almost everywhere trying to keep up with an avalanche of security work. That is the part the “AI found more bugs” headline usually misses. Finding more is only useful if the humans on the other side can still verify, fix, disclose, release, and breathe.&lt;/p&gt;&lt;p&gt;Open source has spent years optimizing for getting more people to contribute. That was the right goal. But now we are entering a phase where “more” is not automatically the answer. We need better paths from contribution to maintainable outcome.&lt;/p&gt;&lt;h2 id=&quot;the-answer-is-not-banning-ai&quot;&gt;The answer is not banning AI&lt;/h2&gt;&lt;p&gt;Some projects have responded by restricting or banning AI-generated contributions. I understand why they get there. When a project is drowning in questionable contributions, the fastest visible lever is to say “no AI”.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://www.netbsd.org/developers/commit-guidelines.html?ref=frenck.dev&quot;&gt;NetBSD’s commit guidelines&lt;/a&gt; say LLM-generated code is presumed tainted and must not be committed without prior written approval. &lt;a href=&quot;https://wiki.gentoo.org/wiki/Project:Council/AI_policy?ref=frenck.dev&quot;&gt;Gentoo’s AI policy&lt;/a&gt; forbids contributions created with the assistance of natural language processing AI tools, citing copyright, ethical, and quality concerns.&lt;/p&gt;&lt;p&gt;Those are not silly concerns. But I do not think trying to detect AI use, police it, and fight contributors over whether a tool touched their work is where open source should spend its limited maintainer energy.&lt;/p&gt;&lt;p&gt;That energy is better spent on the thing we actually need anyway: clear contribution paths, stronger review boundaries, better tests, reproducible reports, smaller changes, and maintainers feeling safe to say “no” when something is not ready.&lt;/p&gt;&lt;p&gt;AI-assisted work is not one thing. A drive-by contributor asking an agent to “fix this issue” and pasting the result is very different from an experienced developer using AI to write tests for code they understand. A security report generated by a model and never verified is very different from a report where the researcher used AI as part of their workflow and then reproduced the issue properly. A maintainer using AI to find repeated review feedback and turn it into a lint rule is different again.&lt;/p&gt;&lt;p&gt;The useful question is not “did AI touch this?”. The useful question is: &lt;strong&gt;does the person submitting this understand it, validate it, and take responsibility for it?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;That is the professional line. Not whether an excavator was used, but whether the person operating it knows how to dig the hole without destroying the garden.&lt;/p&gt;&lt;p&gt;Home Assistant will likely adopt an AI policy soon as well. Not to ban AI, but to give maintainers the tools and the permission to say “no” when someone shows up after absolutely obliterating their garden with that machinery.&lt;/p&gt;&lt;p&gt;That is the point for me. A policy should not become an AI detector game. It should make the expectations clear: if you submit the work, you own the work.&lt;/p&gt;&lt;figure&gt;&lt;img src=&quot;https://storage.ghost.io/c/ab/ad/abad1d9c-f8be-46a0-a7d1-8d10cb861cfa/content/images/2026/05/photo-1630885610104-1f17e5509457.jpeg&quot; alt=&quot;Yellow and black excavator near green trees during daytime.&quot; loading=&quot;lazy&quot; width=&quot;1200&quot; height=&quot;837&quot; srcset=&quot;https://storage.ghost.io/c/ab/ad/abad1d9c-f8be-46a0-a7d1-8d10cb861cfa/content/images/size/w600/2026/05/photo-1630885610104-1f17e5509457.jpeg 600w, https://storage.ghost.io/c/ab/ad/abad1d9c-f8be-46a0-a7d1-8d10cb861cfa/content/images/size/w1000/2026/05/photo-1630885610104-1f17e5509457.jpeg 1000w, https://storage.ghost.io/c/ab/ad/abad1d9c-f8be-46a0-a7d1-8d10cb861cfa/content/images/2026/05/photo-1630885610104-1f17e5509457.jpeg 1200w&quot; sizes=&quot;(min-width: 720px) 720px&quot;&gt;&lt;figcaption&gt;&lt;span&gt;Still useful machinery. Still capable of making a mess. Photo by &lt;/span&gt;&lt;a href=&quot;https://unsplash.com/photos/yellow-and-black-excavator-near-green-trees-during-daytime-LXYRLFnigng?utm_source=frenck.dev&amp;amp;utm_medium=referral&quot;&gt;&lt;span&gt;Erik Mclean&lt;/span&gt;&lt;/a&gt;&lt;span&gt; on &lt;/span&gt;&lt;a href=&quot;https://unsplash.com/?utm_source=frenck.dev&amp;amp;utm_medium=referral&quot;&gt;&lt;span&gt;Unsplash&lt;/span&gt;&lt;/a&gt;&lt;span&gt;.&lt;/span&gt;&lt;/figcaption&gt;&lt;/figure&gt;&lt;h2 id=&quot;home-assistant-is-feeling-this-too&quot;&gt;Home Assistant is feeling this too&lt;/h2&gt;&lt;p&gt;At Home Assistant, we are not watching this from a distance. We are in it.&lt;/p&gt;&lt;p&gt;The number of pull requests is high. The number of merged contributions is high too, and that part is genuinely good news. Every release includes more work from people who cared enough to contribute. New integrations, fixes, cleanups, documentation improvements, tests, translations, small quality-of-life improvements. That is open source working.&lt;/p&gt;&lt;p&gt;But the queue is growing. And that is the hard part.&lt;/p&gt;&lt;p&gt;We are not winning yet.&lt;/p&gt;&lt;p&gt;That does not mean contributions are bad. It means the system around contributions has to evolve. If contributors are amplified, the project needs to amplify the path around them as well: the docs, the checks, the review process, the feedback loops, and yes, the AI instructions that shape what people and agents produce.&lt;/p&gt;&lt;p&gt;This is an important distinction: these improvements do not only help humans. AI uses them too.&lt;/p&gt;&lt;p&gt;When we improve documentation, humans read it, but AI tools also retrieve it, summarize it, and use it as context. When we tune AI instructions because we notice weird repeated patterns, we are not just helping the next person. We are shaping the next generated contribution. When human reviewers keep leaving the same comments, that is a signal. Maybe the documentation is unclear. Maybe a static check should catch it. Maybe a linter rule should exist. Maybe our own tooling needs to become more opinionated.&lt;/p&gt;&lt;p&gt;That is where I think the real adaptation happens.&lt;/p&gt;&lt;p&gt;Not by pretending AI is not part of software development now. Not by accepting every AI-shaped pile of code because “contributions are good”. And not by believing AI review can fully replace human judgment, because verification is the slower, more careful part for a reason.&lt;/p&gt;&lt;p&gt;The path forward is to turn repeated human judgment into better systems.&lt;/p&gt;&lt;h2 id=&quot;maintainers-need-leverage-too&quot;&gt;Maintainers need leverage too&lt;/h2&gt;&lt;p&gt;Developers are getting leverage from AI. Maintainers need leverage as well.&lt;/p&gt;&lt;p&gt;Some of that leverage is boring, which usually means it is useful. Better documentation. Clearer contribution guidelines. Stronger tests. More static checks. Linters that encode project-specific expectations. CI that catches common mistakes before a reviewer spends time on them. Templates that ask for the right information. Review tooling that summarizes the risk areas instead of pretending to make the decision.&lt;/p&gt;&lt;p&gt;Some of it can be AI-assisted too. AI can help analyze review history and find repeated patterns. It can help draft documentation for common mistakes. It can suggest where a check might replace a repeated review comment. It can help maintainers navigate a large queue and group similar problems together.&lt;/p&gt;&lt;p&gt;But the goal is not “let AI review AI”. That sounds neat until you remember that review is not only pattern matching. Review is judgment. It is taste. It is understanding the project’s direction. It is knowing why something that works technically may still be wrong for the project.&lt;/p&gt;&lt;p&gt;AI can help prepare the review. It cannot be the maintainer.&lt;/p&gt;&lt;p&gt;That is why I do not think the battle is won by fighting AI. It also will not be won by surrendering to it. Open source has to become more explicit about what good contribution looks like, more automated around the parts that should not require human attention, and more protective of the scarce human judgment that remains.&lt;/p&gt;&lt;h2 id=&quot;open-source-has-to-adapt&quot;&gt;Open source has to adapt&lt;/h2&gt;&lt;p&gt;Open source was not ready for AI-speed contributions. Honestly, I am not sure any of us were.&lt;/p&gt;&lt;p&gt;We built a lot of our workflows around a world where creating a pull request took effort. That effort acted as a filter. Not a perfect one, but a real one. If someone had to understand the code, write the change, run the tests, and explain the result, there was some friction before the maintainer ever saw it.&lt;/p&gt;&lt;p&gt;AI removes a lot of that friction. Sometimes that is wonderful. Sometimes it means a good contributor can do more good work. Sometimes it means a confused contributor can produce a much larger confused contribution. Sometimes it means a maintainer gets a useful report. Sometimes it means they lose an afternoon proving that a confident report is nonsense.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The answer cannot be nostalgia for the old friction. &lt;/strong&gt;That world is not coming back. The answer is to build better friction in the right places.&lt;/p&gt;&lt;p&gt;Make the easy path the good path. Make the repeated mistakes fail before review. Make the documentation good enough for humans and machines. Make AI instructions part of the project’s contribution surface. Make tooling catch what tooling can catch. Save human attention for the parts that actually need humans.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;The best open-source contribution is not the one that arrives fastest. It is the one that can be merged, maintained, and trusted.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;AI can help us get there. But only if we stop treating it as magic and start treating it like the excavator it is.&lt;/p&gt;&lt;p&gt;Very useful. Very powerful. Very capable of making a massive hole in the garden.&lt;/p&gt;&lt;p&gt;../Frenck&lt;/p&gt;
            &lt;/div&gt;</description>
            <pubDate>Sun, 31 May 2026 16:00:42 +0000</pubDate>
            <guid>https://frenck.dev/open-source-was-not-ready-for-ai-speed-contributions/</guid>
        </item>
        <item>
            <title>ripgrep/AI_POLICY.md at master</title>
            <link>https://github.com/BurntSushi/ripgrep/blob/master/AI_POLICY.md</link>
            <description>&lt;blockquote&gt;&lt;hr&gt;&lt;/blockquote&gt;&lt;div data-hpc=&quot;true&quot; aria-labelledby=&quot;file-name-id-wide file-name-id-mobile&quot;&gt;&lt;article itemprop=&quot;text&quot;&gt;&lt;p dir=&quot;auto&quot;&gt;&lt;h2 tabindex=&quot;-1&quot; dir=&quot;auto&quot;&gt;AI Policy&lt;/h2&gt;&lt;a id=&quot;user-content-ai-policy&quot; aria-label=&quot;Permalink: AI Policy&quot; href=&quot;#ai-policy&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;Using AI (i.e., LLMs) as tools for coding is welcome. A high bar is held for
all contributions to this project. Moreover, the project maintainers remain
responsible for any code that is published as part of a release. Contributors
are expected to be responsible for any code they publish.&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;&lt;strong&gt;AI should not be used to generate comments when communicating with
maintainers&lt;/strong&gt;. Comments are expected to be written by humans. Comments that are
believed to be written by AI may be hidden without notice.&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;If you are opening an issue, you should be able to describe the problem in your
own words.&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;If you are opening a pull request, you are expected to be able to explain the
proposed changes in your own words. This includes the pull request body and
responses to questions. &lt;strong&gt;Do not copy responses from the AI when replying to
questions from maintainers.&lt;/strong&gt;&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;This project requires a human in the loop who understands the work produced by
AI. &lt;strong&gt;Autonomous agents are not allowed to be used for contributing to this
project&lt;/strong&gt;. Pull requests that appear in violation of this will be closed,
perhaps without notice.&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;If you wish to include context from an interaction with AI in your comments, it
must be in a quote block (e.g., using &lt;code&gt;&amp;gt;&lt;/code&gt;) and disclosed as such. It must be
accompanied by human commentary explaining the relevance and implications of
the context. Do not share long snippets.&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;AI is useful when communicating as a non-native English speaker. If you are
using AI to edit your comments for this purpose, please take the time to ensure
it reflects your own voice and ideas. If using AI for translation, we recommend
writing in your native language and including the AI translation in a quote
block.&lt;/p&gt;
&lt;p dir=&quot;auto&quot;&gt;This policy was adapted from &lt;a href=&quot;https://github.com/astral-sh/.github/blob/c5187e200db51bfe11d56e13053d29bd3793fdd8/AI_POLICY.md&quot;&gt;uv&#039;s AI policy&lt;/a&gt;.&lt;/p&gt;
&lt;/article&gt;&lt;/div&gt;</description>
            <pubDate>Thu, 28 May 2026 04:52:21 +0000</pubDate>
            <guid>https://github.com/BurntSushi/ripgrep/blob/master/AI_POLICY.md</guid>
        </item>
    </channel>
</rss>
