{
  "description": "Browse aymeric's, an independent, searchable archive of readable snapshots from followed feeds, preserved in Git with aggr.",
  "feed_url": "https://aggr.aymericbeaumet.com/sources/ghuntley.com/feed.json",
  "home_page_url": "https://aggr.aymericbeaumet.com/sources/ghuntley.com/",
  "items": [
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>I don't know if you've seen this, but a CA just got popped. Their keys got leaked, which means the industry as a whole now has some pretty major problems. It was revealed two hours ago.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://emudhra.we-have-a-problem.com/?ref=ghuntley.com\">eMudhra Intermediate CA Compromise</a></p>\n<p>eMudhra Intermediate CA Compromise</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://static.ghost.org/v5.0.0/images/link-icon.svg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Now you're probably wondering why I'm writing up this blog post. It's simple. This is perhaps one of the easiest security patches I've ever done, and I've discovered a few new tricks. First, understand that fixing this with ease without Nix is almost impossible. Tens of millions of dollars (if not more) in productivity are being lost worldwide right now as everyone tries to patch their transitive dependencies.</p>\n<p>Meanwhile, because I've used Nix, I can patch the planet, since the ideas behind the blog post below extend into security as well.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/nix/\">the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay</a></p>\n<p>There are many things that are uncertain in our industry right now, but one thing I am certain about, and have been for almost 13 years, is that Nix is a terrible programming language. I remember when I first learned it, it felt like pushing shit uphill. The learning cliff</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--a11b26e3-d1b1-4800-9564-2a6ca417d866.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/Symbolic-traditional-tattoo-art-print-viewed-from-a-high--elevated-angle--portraying-a-bustling-city-transformed-by-a-Nix-overlay.-Gleaming-buildings--technological-textures--surreal-contrasts--and-limitless-possibility-evoke-hidden-power.--90d86506-96bf-47ba-8336-242084c55e95.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Because of Nix's single source of truth and the ability to patch this single source of truth, I'm able to issue a simple prompt like this:</p>\n<blockquote>\n<p>okay is my nixos for my fleet affected by <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://emudhra.we-have-a-problem.com/?ref=ghuntley.com\">https://emudhra.we-have-a-problem.com/</a>?</p>\n</blockquote>\n<p>With results in the following.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Screenshot-2026-10-21-at-3.30.50---AM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>So the problem here is the transitive dependencies. It's easy to patch one thing, but the transitive dependencies are the problem, and this is where Nix shines: one fix fixes the transitive dependencies automatically.</p>\n<p>One patch fixes the entire fleet and its transitive dependencies. Patch, commit, and autodeploy your fleet 🍻</p>\n<h2>the new trick</h2>\n<p>Alright, I promised a new trick. Here's the trick.</p>\n<blockquote>\n<p>You can prompt an agent to update the AGENTS.MD to automatically back out these patches, let's say in five days from now, just by using the AGENTS.MD as a reminder 😎</p>\n</blockquote>\n<p>So it was one simple prompt to identify if I was affected, which turned into a plan, which then automatically fixed it, and now, in a couple of days, it will reassess the situation, give time for the ecosystem and dust to settle, and then automatically back it out once all the upstream transitive dependencies have been resolved.</p>\n<p>Cool, huh?</p>\n<pre><code><span class=\"code-snippet\">## Temporary reminder: eMudhra root blacklist (from 2026-10-22)\n\nOn or after 2026-10-22, check whether the `nixos-26.05` channel contains nixpkgs\ncommit `7816d39` (the backported `security/ca.nix` distrust of the eMudhra roots), e.g.\n`nix eval --raw --refresh --impure --expr &#39;(builtins.getFlake &quot;github:NixOS/nixpkgs/nixos-26.05&quot;).rev&#39;`\nthen `git merge-base --is-ancestor`. If it does not, check again two days later.\nOnce it does, back out the fleet-wide workaround: update the `nixpkgs` pin to include\nit, delete `nix/domains/system/public-trust.nix` (contract `fleet-distrust-emudhra-roots`)\nand its imports in `nix/domains/system/catalog.nix`,\n`nix/domains/artifacts/guest/configuration.nix` and the `host-kexec` modules in\n`flake.nix`, and remove the eMudhra paragraph from\n`marshall/priv/hldd/12-configuration.md`. Then verify that the built host and guest\nbundles still lack the four roots, and delete this section. Keep Marshall&#39;s\nsystem-store TLS defaults (`runtime-postgres-system-trust`, `mail-smtp-system-trust`)\nand the `rustls-webpki` update; they are not part of the workaround.\n</span></code></pre>\n<p>I can't stress this enough. If you build something, you own it, including all the dependencies you rely on. We're entering weird times where cyber offensive models will be continuously on the attack.</p>\n<p>The game has changed. To defend, you need more inferencing capability than the attacker, and you also need to respond rapidly.</p>\n<p>This is by far the easiest security patch I've ever done, and the best part is I won't carry this tech debt for long because an agent will automatically back it out in a couple of days.</p>\n<p>0:00</p>\n<p>/0:04</p>\n<p>patch the planet</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/10/hackers-patch-the-planet-dialogue--1-_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>ps. socials</p>\n<blockquote>\n<p>🗞️ patch the planet <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/7ZwlallBru?ref=ghuntley.com\">https://t.co/7ZwlallBru</a> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/aSQGD0smx2?ref=ghuntley.com\">https://t.co/aSQGD0smx2</a> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/tDpIKpp58O?ref=ghuntley.com\">pic.twitter.com/tDpIKpp58O</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2112585326514287070?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 20, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-20T16:41:12+00:00",
      "date_published": "2026-10-20T16:41:12+00:00",
      "external_url": "https://ghuntley.com/patch/",
      "id": "urn:aggr:item:b648b3f8e680440052b944fdd1312f5424350916",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w1200/2026/10/Symbolic-traditional-tattoo-art-print-showing-hackers-patching-a-planet-beneath-stormy-skies--vibrant-yet-soft-pastel-colors--intricate-retro-ornamental-details--intense-dramatic-weather--high-tension-composition-balanced-by-a-gentle-soothi.jpg",
      "summary": "I don't know if you've seen this, but a CA just got popped. Their keys got leaked, which means the industry as a whole now has some pretty major problems. It was revealed two hours ago. eMudhra Intermediate CA Compromise eMudhra…",
      "tags": [
        "programming",
        "ai",
        "infosec",
        "nix"
      ],
      "title": "patch the planet",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-20-patch-the-planet/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>by now, most people should be aware that we're in a cost of compute crisis. The cost of CPU and memory is through the roof. There just isn't enough. Meanwhile, there definitely aren't enough GPUs in the world.</p>\n<p>If you've been using ChatGPT lately, you might have seen the meme circulating in the space that OpenAI just doesn't have enough inferencing capacity. Heck, even Tibo admits publicly that they're having compute issues.</p>\n<blockquote>\n<p>It’s the compute that is cooked</p>\n<p>— Tibo (@thsottiaux) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/thsottiaux/status/2107586339860631980?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 6, 2026</a></p>\n</blockquote>\n<p>In the last couple of weeks, I have lost so much time babysitting agents because of inferencing capacity issues, and it's got me wondering: what if inferencing capacity constraints were region-based? Last year, before this crunch, even with Anthropic models, inferencing was noticeably faster in Australia because everyone else in America was sleeping.</p>\n<p>Day to day, I do all my open-source software development on bare-metal machines in Germany, and I've started to notice similar patterns when Europe wakes up: all of a sudden, inferencing performance plummets and I'm being greeted with walls of 'model is at capacity, try again' errors.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/CleanShot-2026-10-15-at-6.45.19-PM.gif\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Above is what I woke up to this morning. Imagine my dismay at losing time on a strict get-overalls-done-and-released-before-my-conference-talk timeframe. You can complain online all you want, but we're software engineers. We can solve these problems.</p>\n<h2>underclass</h2>\n<p>The first piece of the puzzle is a piece of software that I wrote last month called Underclass. Underclass pools many ChatGPT subscriptions together and works as a proxy. It can automatically claim resets and correctly handles the prompt cache key to ensure usage isn't wasted.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/10/CleanShot-2026-10-17-at-6.20.12-PM@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I haven't written about it before, but it is now a month old, and I consider it stable. It's available on GitHub, and I use it with six ChatGPT 500 accounts, but there's no real upper limit on how many accounts you can configure.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/underclass?ref=ghuntley.com\">GitHub - ghuntley/underclass: underclass: an OpenAI-compatible pooling proxy that pins sessions to one account (prompt cache stays warm), cools quota-exhausted subscriptions until their window resets, and fails fast with the earliest Retry-After when the whole pool is dry.</a></p>\n<p>underclass: an OpenAI-compatible pooling proxy that pins sessions to one account (prompt cache stays warm), cools quota-exhausted subscriptions until their window resets, and fails fast with the ea…</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-aea76f9c-44c9-49d3-a1a5-a9a9ba062525.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/underclass-f93661a6-b274-450d-b3b6-20a3ef696782.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Installation is easy, and it's well documented. It's also available as a Nix Flake.</p>\n<h2>preflight</h2>\n<p>Another piece of software I wrote last month is a local LLM proxy that scans requests and attachments for secrets and proactively scrubs and redacts them before they hit the model. It's on GitHub (below)</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/preflight?ref=ghuntley.com\">GitHub - ghuntley/preflight: A local proxy that scans LLM requests and attachments for secrets before they reach the model.</a></p>\n<p>A local proxy that scans LLM requests and attachments for secrets before they reach the model. - ghuntley/preflight</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-0b2813e7-01d6-4378-8639-e44757c71541.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://opengraph.githubassets.com/5ddbfa2cc8cf8a0f2809a19284b5243fbb8b9e37ee29f7507467413916460ac9/ghuntley/preflight\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>To use Preflight, run a single instance of Preflight and one instance of Underclass, then point Underclass to use Preflight. Preflight scrubs requests and sends them out for inference, ensuring sensitive material never reaches the inference providers.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/CleanShot-2026-10-17-at-6.28.31-PM@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<h2>unburying the lede</h2>\n<p>By now you're probably wondering either, &quot;Wow, that's two really cool projects,&quot; or why I opened with geographic routing. It's because... today I'm releasing a new <em>experimental prototype</em> called <code>geoclass</code> which routes your requests to different inferencing regions around the world. Like underclass and preflight, it is composable. You can use all of them, none of them, or any combination you can imagine, since they are separate pieces of software that compose well together.</p>\n<p>How it works is simple.</p>\n<p>Set up a Tailscale network and deploy virtual machines around the world, then tag those virtual machines with a Tailscale tag; GeoClass can then identify these machines via the tag. From that point forward, all you need to do is point UnderClass to GeoClass, and the rest just works (in theory!).</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/10/Screenshot-2026-10-17-at-6.55.27---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I don't know <em>yet</em> if <code>geoclass</code> will solve my inferencing woes, but there's also no way in hell I'm going to sit here and stew when the performance of OpenAI in Europe has been miserable over the last 30 days.</p>\n<p>So I'm going to try experimenting with geo-routing. If the below works for you, let me know; I'm keen to catch up with folks thinking along the same wavelength. You never know until you try!</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/geoclass?ref=ghuntley.com\">GitHub - ghuntley/geoclass: [experimental] Geo-aware egress router for underclass: retries OpenAI capacity errors in another region over a Tailscale mesh, keeping prompt caches warm</a></p>\n<p>[experimental] Geo-aware egress router for underclass: retries OpenAI capacity errors in another region over a Tailscale mesh, keeping prompt caches warm - ghuntley/geoclass</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-a6233f77-bb91-4153-ad02-6d008cf5526c.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://opengraph.githubassets.com/1abfa8d880b75475bfbabdb698c328de58526a92b7c02633e9dfb6d0309dc83a/ghuntley/geoclass\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>ps. socials</p>\n<blockquote>\n<p>🗞️ pooling OpenAI subscriptions and bypassing regional inference capacity limits <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/s10AD5O5Vb?ref=ghuntley.com\">https://t.co/s10AD5O5Vb</a></p>\n<p>today I'm releasing a new experimental prototype called geoclass, which routes your requests to different inference regions around the world.</p>\n<p>set up a Tailscale network… <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/2htIMiUdD3?ref=ghuntley.com\">pic.twitter.com/2htIMiUdD3</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2111367787629195767?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 17, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-17T08:01:21+00:00",
      "date_published": "2026-10-17T08:01:21+00:00",
      "external_url": "https://ghuntley.com/underclass/",
      "id": "urn:aggr:item:782958cfc49485bed5a6c8a0d0618e0c5c9d059b",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Traditional-tattoo-art-print-from-a-bird---s-eye-view--depicting-pooled-OpenAI-subscriptions-as-a-collaborative-network-overcoming-regional-inference-limits.-Interwoven-streams-of-glowing-data-form-a-swirling-ornamental-tapestry--with-each-.jpg",
      "summary": "by now, most people should be aware that we're in a cost of compute crisis. The cost of CPU and memory is through the roof. There just isn't enough. Meanwhile, there definitely aren't enough GPUs in the world. If you've been using",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "pooling OpenAI subscriptions and bypassing regional inference capacity limits",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-17-pooling-openai-subscriptions-and-bypassing-regional/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>people are failing a curiosity test right now. Armin Ronacher and Ben Vinegar had me on State of Agentic Coding to talk about it, along with DHH coming around, durable agents, a Lisp you program by talking to it, and why the labs cannot afford to fail.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js\">State of Agentic Coding #11 with Geoff, Armin, and Ben</a></p>\n<p>Ben Vinegar (co-founder of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://modem.dev/?ref=ghuntley.com\">Modem</a>) and Armin Ronacher (<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://earendil.com/?ref=ghuntley.com\">Earendil</a>, and the person most people know from Pi) run a podcast called State of Agentic Coding, and I was the guest for episode 11. Ben and I were in the same room in Toronto. I'd landed the day before after 22 hours of flying, I was there for two days, and then I was flying back to Sydney. Armin stayed in Vienna, sensibly.</p>\n<p>We covered a lot of ground in an hour and a half. Here's the gist, written up properly, with chapter links at the bottom if you want to jump to a specific part of the conversation.</p>\n<blockquote>\n<p>DHH did the funeral last week and he's right.</p>\n</blockquote>\n<h2>the curiosity test</h2>\n<p>Ben opened by asking what my contribution to the GDP of AI development has been from Ralph loops. The OpenRouter folks personally came up to me to say thanks for the uptick, so I know it has burned a lot of tokens. I published the research in July last year. When I first showed it to Cursor they thought it was garbage. Nine months later they'd implemented it, then Anthropic did it, then OpenAI did it, and now everyone's talking about loop engineering. Dex calculated it at about $10.42 an hour when you run it in the loop and it builds AFK overnight.</p>\n<p>That weighed a lot on my shoulders when it first came out.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ralph/\">Ralph Wiggum as a &quot;software engineer&quot;</a></p>\n<p>How Ralph Wiggum went from 'The Simpsons' to the biggest name in AI right now - Venture Beat 😎Here's a cool little field report from a Y Combinator hackathon event where they put Ralph Wiggum to the test. &quot;We Put a Coding Agent in a While Loop and It Shipped</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--237cb3bb-fc6c-4944-b89d-3d3362ea55e2.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/3ea367ed-cae3-454a-840f-134531dea1fd-11e18dce-3ce9-4b06-8136-9a29731360c9.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I've spent this year traveling the world giving talks, pleading with people to invest in themselves. My shortest take is this: software developers are failing a curiosity test. If you're displaced by AI as a software developer, it's self-inflicted, because you haven't been curious in a time of rapid transformation. As an employee, you trade time and skill for money. Employers' tastes are changing rapidly, but there's no reason you can't keep up with what's going on.</p>\n<p>Just harshing everybody's vibe right out of the gate.</p>\n<p>Ben pushed back here, and fairly. When people come into the industry they're young and have infinite time on their hands. Now many of them are in their thirties or forties and have racked up responsibilities. It's the same reason video games get harder to stay into as you age. It's hard to retool at this rate of change, and it's hard to feel optimistic when the thing at the centre of your income and your self-worth is in flux.</p>\n<p>I concur. Dex Horthy has described my writing over the last two years as the depression era of Geoff: mourning the profession while pleading with people to be curious and to put themselves and their family unit first. This change has been forced on the world non-consensually. It displaces your identity. Are you a .NET developer? A Golang developer? A Python developer? It doesn't matter anymore. What matters is how good a developer you are, and whether you're using the thing employers now expect as the bare minimum.</p>\n<p>Armin made a sharp observation: a lot of people in AI talk a very confident game externally, and that probably applies to us too. I'm straight up about this. I don't bloody know. Every time I discover something new, it strips me raw. You discover a new technique or capability, you thought you had a mental model of how it would play out, and then the game changes.</p>\n<h2>boom and bust</h2>\n<p>Ben, playing tour guide, pointed out that the closest US cities to Toronto are Buffalo and Detroit. Buffalo was once the third most populous city in the US, prosperous because of its rail access to the Great Lakes. It's now one of the most rapidly declining. Detroit is a later, similar story, tied to the auto industry. His point: there's a long history of people with hubris believing the good times will never end.</p>\n<p>I've been through a few of these cycles, going back to the original dot-com boom and bust. Senior compensation went through the roof during the ZIRP era because, in the previous bust, we didn't develop enough talent. That created a scarcity of knowledge. Hold on, folks: the same cycle will repeat. CS enrolments are down; I remember seeing something like 22% in Singapore this year.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/screwed/\">Dear Student: Yes, AI is here, you're screwed unless you take action...</a></p>\n<p>Two weeks ago a student anonymously emailed me asking for advice. This is the reply and if I was in your shoes this is what I'd do. So, I read your blog post &quot;An oh f*** moment in time&quot; alongside &quot;The future belongs to idea guys that can just</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--31d76d80-8d5e-4fc6-9b62-745e32943777.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/llmcurve-75b9954f-1a0e-4b42-9523-ada763fb6862.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>If you really love computers, you should be all in on loving computers right now. Everyone's having the time of their damn life. If you've stayed curious and kept your skills up to date, you can get placed anywhere right now. That means being able to stand at a whiteboard and explain how to build a coding agent as a sequence diagram, how inferencing works, and what a prompt cache is.</p>\n<p>Armin had a slightly different read. Detroit not growing doesn't mean cars stopped being a thing; the industry went worldwide and commoditized. Software engineers got paid really well because we were scarce and our only competition was other software engineers. Automation didn't play a role. That's changing. He's absolutely convinced the exceptional role our profession has had over the last twenty years won't return in the same form. There will probably be a period with more demand for software engineers, but it will commoditize quickly. He's also curious what happens to San Francisco, a city that hasn't grown its housing stock, when the Anthropic IPO mints a pile of multi-millionaires competing for it.</p>\n<p>I'm hoping for another PayPal-mafia-type thing. When people get minted, they invest in what they know.</p>\n<h2>dhh did the funeral</h2>\n<p>If you're in love with typing on a keyboard in an IDE, I'm sorry to say it, but DHH did the funeral last week, and he's right. You can still type code; you just do it in your personal workshop. Employers now want you to use the CNC machine and be very good with the CNC machine. They don't want artisanal woodworking anymore.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vDjW_dRyKXY\">Rails World 2026 Opening Keynote - DHH</a></p>\n<p>Ben summarised the Rails World keynote nicely. DHH walked through three generations of family pictures: a single drawing from his grandfather, a handful of photos from his childhood, and his kids with every second of their lives photographed. Portrait painting was an economic outcome. When photography made drawing reality uneconomic, painting went to impressionism and cubism: let's draw what isn't reality.</p>\n<p>Armin had been on a panel at a Ruby conference in Austria earlier this year with Chad Fowler, who already said that the agent never writes Ruby for him anymore. When you sample which languages agents actually use, Ruby doesn't show up meaningfully. The online reaction to the keynote was largely dismissive, but the in-person reaction was much better received. Armin's point is that communities are disintegrating and reforming around the ideas that brought them together in the first place, even as the technology underneath changes. The Rails community is really a descendant of how DHH thinks software should be built; Ruby was just the tool.</p>\n<p>So what's the point of a programming language or framework full of sugar designed for humans if humans aren't writing the code anymore? I've been chatting with the creator of Elixir, and he gets it. Language designers have dumbed down their languages to make them easy to learn for the human operator. All of that is falsified now that the agent writes the code. What does an agent need? What's the point of LSPs? Will we get new forms of interpretability, like an agent driving GDB, on a per-language basis? The languages won't go away, but the communities that swallow this tough pill and evolve will be the ones that survive.</p>\n<p>Developers mostly speak to other developers. It's like a couple of cows in a field going moo to each other, completely missing that the cows are headed for the abattoir. Grim, I know. Stop being a cow. Learn a bit about business. Speak with founders and investors. Learn to be a product engineer. If you're working at a company that has banned AI outright, you should quit that company.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/replaced/\">if your team is too busy doing their 'normal job' to experiment with AI, you're preparing them to be replaced</a></p>\n<p>When Ralph was published last year, I sat on it. People who have been reading this blog for a while know this. I first came across the idea of loop engineering in early January last year, sat on it for four months, and then started writing a lot, begging people</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--4402f76c-2773-4227-989f-385813844cd4.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/download--2--ac0778bc-b7b2-4034-b0bf-0f610c6be556.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Armin said the strongest signal for him isn't his own belief; it's that the experienced, vocal holdouts are turning. DHH was dismissive early on. Notch was dismissive and recently turned. Ben noticed that DHH was transparent about having tried AI for design, pulled it back, and now landed firmly on the other side. It felt like an invitation: come join me. Armin's worry is that because DHH is polarising, the message may not land as widely as it should.</p>\n<p>On where to find the signal: if you've been on X for the last two years, you're ahead of the game, because that's where all of this has happened. I don't love the platform; the number of AI reply bots is through the roof. But if you want the alpha, you have to push through. Go to the fediverse and talk about AI and you'll get your whole Mastodon instance banned. Bluesky has some high-alpha accounts. Unfortunately, the tech community has fractured along political lines, which means a lot of this isn't getting out.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/multi-boxing/\">Multi Boxing LLMs</a></p>\n<p>Been doing heaps of thinking about how software is made after <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/oh-fuck\">https://ghuntley.com/oh-fuck</a> and the current design/UX approach by vendors of software assistants. IDEs, since 1983, have been designed around an experience of a single plane of glass. Restricted by what an engineer can see on</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--b478d2f4-515c-4a80-9d57-639c944aa1c9.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/CleanShot-2025-01-28-at-12.41.09@2x-3e3faa8f-431f-4e8b-8f68-8fa8afde04c5.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Back in December 2024 I was writing that IDEs are dead as a product, and everyone called me crazy. I've taken a lot of unpaid time off work this year to give talks. You can't carry all that water yourself. The best you can do is this: if someone gets curious, help them get to their own moment. Find the thing that makes their mind explode, then ask them to show the next person. For me, that moment was seeing how easy it is to build a coding agent and realizing the entire game now is to build product recursively.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/agent/\">how to build a coding agent: free workshop</a></p>\n<p>It's not that hard to build a coding agent. 300 lines of code running in a loop with LLM tokens. You just keep throwing tokens at the loop, and then you've got yourself an agent.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--c1294a16-623f-4085-9266-247acaa54438.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/how-to-build-an-agent.001-74643aee-edec-45c9-a237-79b08933c145.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Ben brought up the Bob Dylan biopic with Chalamet. Dylan is folk royalty, goes electric, and the old caretakers practically call the police to shut it down while the younger audience wants the new stuff. Folk was one of the most popular genres of its time. The reason you know Dylan's name and not most of the folk scene's is that he evolved. Boy, we don't like change.</p>\n<p>The one thing I wrote that really landed with juniors was &quot;dear student, you're screwed&quot;. ThePrimeagen narrated it (thank you, Prime), and I wrote it as if I were giving career advice to my own kid at twenty. Now, at the AI Engineer World's Fair and in my travels, people come up and tell me they got a promotion because they turned up with the attitude and the skills. Don't thank me; you did the work. You were curious and you invested in yourself.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/screwed/\">Dear Student: Yes, AI is here, you're screwed unless you take action...</a></p>\n<p>Career advice for students and juniors on what's about to happen, and what to do about it.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<h2>four months in 2026</h2>\n<p>Armin and the Earendil crew shipped Pi 1, and they also shipped something that's around 10,000 lines of code but took four months to build. Four months, in 2026. That's like a five-year project.</p>\n<p>Armin's explanation is the bit I want everyone to hear. LLMs suck at the shape of a contract and the human feel of an API. You can express an idea really fast, but getting the right feel takes a lot of knowledge and experimentation. They solved the problem something like twenty times, each in about two hours, and none of those solutions felt right. The agent solves every problem in record time, but that doesn't give you a system with the right trade-offs. Finding the right trade-offs is what took four months.</p>\n<p>The result is <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://earendil.com/posts/pi-durable/?ref=ghuntley.com\">Pi Durable</a>, which is how they now think an agent should be structured. You can shut down the harness, restart it, and it picks up exactly where it left off. That holds over the network, and through complex interactions such as sub-agents spawning and talking to each other.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://earendil.com/posts/pi-durable/?ref=ghuntley.com\">Pi Durable | Earendil</a></p>\n<p>Pi Durable is a new experimental package for long-running, durable, and malleable agents that can run anywhere. A tour of what we built and why.</p>\n<p>Earendil</p>\n<p>Fourteen or fifteen months ago, Armin, Mario, Peter and others had a strong conviction that file systems and bash were the way to go, but nobody really knew how to build a harness around that. So everyone copied what Claude Code was doing, which is a very simple idea of a session: a transcript, a tool call, a tool result, in a loop. That model has stayed at the core of more or less every agent. At its simplest, all it does is automate copying and pasting.</p>\n<p>But demands have changed. Background compaction means doing two things at once. A Slack experience means five people talking to the same agent, some in the same sub-thread and some branching off. That mapped incredibly poorly onto Pi's original design. Armin called it a little bit of cargo culting that we're all suffering from: we keep building on a basic primitive that causes pain everywhere. We don't notice, because an agent will happily build you a decent-looking agent, but under the hood it's messy, horrifying and not reliable.</p>\n<blockquote>\n<p>this technology is moving really, really quickly and is held back by ideas about how it should work that are a year plus old.</p>\n</blockquote>\n<p>Can I get that louder and printed on a shirt? Here's my hot take: your AGENTS.md and many of your skills should be deleted after every model release, or at least every couple of months, and redone. We carry so much that we think of as best practice, and we perpetuate it. Steering messages versus follow-ups were a UX paradigm; the loop underneath stayed the same. Async tasks for bash were one of the last big advancements. Go further back: why do we even have a shell? Because we used to have a human operator. If that need had never existed, would we have an operating system shell at all? That's the level at which we need to rethink the substrate.</p>\n<h2>a lisp you grow by talking to it</h2>\n<p>Ben asked what we'd actually thrown out lately, so I showed the thing I'd published that morning. We've raised two generations of software developers who have probably never seen Lisp and what it can do. Armin was very curious, because three months earlier he'd given a talk saying Lisp was the worst language for agents since they're terrible at counting closing parentheses. That's the old joke.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/lisp/\">an application in lisp you grow by talking to it</a></p>\n<p>It's very clear that programming languages will converge toward what agents need, not humans.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>The usual mental model of a coding tool goes like this: you prompt it, it runs bash to look at your project, finds the file and uses the edit tool to change it. Then comes compilation, then CI/CD, then code review. What I showed throws all of that out.</p>\n<p>I've connected an LLM to a running Lisp. I asked what functions were defined, and the LLM asked the running image. I asked for a string reverse function, typos and all, and it defined one directly into the image. Then string uppercase. Then a function to fetch a URL and parse the JSON. I can undo a change and roll back to the previous generation. There are only two tool calls in the inferencing loop: evaluate an expression, or define one as a function. I'm editing the Lisp image and its runtime environment through a chat. Once a function is defined, it's defined.</p>\n<p>Now don't think of this as a chat interface. Imagine you're logged into your website and there's a secret little Hackers-style menu that only shows for staff. You don't load up an IDE. You pop a prompt and evolve the running program by chatting with it. What if that's how a user feedback request gets actioned?</p>\n<p>Ben mentioned that the opencode folks had just written about how much work it took to make individual plugins hot reload, never mind be programmed live. Armin said that on a single-player level this is very much what made Pi interesting, since Pi can rebuild and reload itself. The challenge is that JavaScript is not a language built for hot reloading.</p>\n<h2>why lisp died</h2>\n<p>Ben's question was the right one: if this is so fantastic, why does it feel like you're digging up a grave?</p>\n<p>Lisp has always been about these things. But you had to be a Lisp programmer to do Lisp. Now there's a natural-language interface that lets anyone do Lisp-type stuff. Armin gave the more precise answer. The problem with software is effects. That's partly why Pi Durable exists: if you shut down Pi and reload it, it doesn't come back exactly as it was, because not everything is serialisable. Lisp can serialise its entire state out more than most languages can, and functions are defined much like data.</p>\n<p>Why did it go away? Lisp was slow unless you had a machine that really suited it, and it didn't survive the shift to the personal computer, where people wrote assembly. Armin's bluntest point: it's a horrible language to look at. It's awful for humans. Maybe it's great for LLMs. Many of our trade-offs as engineers exist because we're lazy and pick the things that let us stay lazy.</p>\n<p>That's the Ruby thing again: designed to be beautiful and easy for humans, but less powerful. Paul Graham's <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://paulgraham.com/avg.html?ref=ghuntley.com\">Beating the Averages</a> covers this with the Blub paradox.</p>\n<p>I also want to give credit to <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/krzysztof-cieslak?ref=ghuntley.com\">Krzysztof Cieślak</a>. He doesn't get credit for it, but he's the person behind what everyone now calls spec-driven development. He's at GitHub Next, he's one of the people behind Ionide for F#, and he published research back in the GPT -3 era asking whether Markdown could be the future of how we publish software. When I was doing my Ralph loops, I remembered his research and thought: the models got better, let's redo it. The rest is history. For the record, though: code is the spec, folks. Markdown is not a spec. As Armin put it, there are specifications and there are vibe specifications.</p>\n<p>Someone took the Lisp idea and vibed up a web app version in about an hour. It's not Lisp; Lisp is just an easy way to express the idea, nerd snipe people and teach a new generation that powerful languages exist even when their developer experience is terrible. Who cares about the developer experience now that agents write the code? He clicks a little developer button, prompts the functionality in, and the app saves a generation. Think about what that means for someone in sales, marketing, finance or legal: building the product by chatting with the product. This is a completely different way of designing a coding harness. The programming language is LLM-enabled, rather than a harness producing code for a programming language. If you want to be a nerd, go and do this with Smalltalk. You'll be on the front page of Hacker News tomorrow, guaranteed.</p>\n<p>Ben compared it to interviews with musicians like Beck, who pull records off the shelf in their office, or hip-hop producers digging through forgotten lore. I'm pulling out my old Smalltalk and Lisp records. He called me old. It's worth going back to the classics and doing some sampling.</p>\n<h2>code mode and code golf</h2>\n<p>Armin has noticed the models changing. Harnesses are increasingly having the model write code to make tool calls. I've seen the same thing: the models aren't going for the edit tool anymore. They're doing a kind of program synthesis, writing one-liner Python to edit files.</p>\n<p>Armin said Pi supplies an edit tool, and in something like 80% of cases with the latest models it's no longer used. His theory has two parts. First, there's very little punishment in training runs for anything other than succeeding, so the models use whatever means they have. Second, that code behaviour is being trained into the models. Pi offers code mode as a tool and will probably make it the default: run some JavaScript instead of bash. Bash runs where your files are; code mode runs in the harness loop, which is typically the same computer but not necessarily.</p>\n<p>The side effect is fascinating and a bit grim. Remember code golf, where you win by writing the shortest possible solution? That's what some of these models feel like. Single-character variables, no indentation, unreadable. Ben's read was that there's a real tension here: the tightest possible code is optimal for a tool-calling loop, but it isn't what you want in your application code. Armin's read was that it might not get punished much anymore, because the models are mostly rewarded for completion on synthetic benchmarks, and they're releasing faster than ever.</p>\n<p>The last time it was like this was the Sonnet 3.5/3.7 era, which spewed Markdown everywhere and wrote those one-liners even though it had an edit tool. Then it went away. Now it's back. I was recently given access to a couple of racks of GB300s and have been running Kimi on them. You can feel the models diverging: Kimi reaches for the edit-file tool, while the frontier American models program their way around it over bash.</p>\n<h2>black-box agents</h2>\n<p>For our profession, we've been post-AGI for over a year now. By that I mean the models have been good enough to cause displacement for over a year. I'd rather focus on how beautiful it is that you don't need frontier intelligence for every task.</p>\n<p>As much as you might want local models, they aren't really a thing yet unless you have a couple of million dollars of data centre hardware. That won't always be the case. I love open-weight models. Kimi is not as good output-wise, it's chattier and slower in its chain of thought, but I get to see the thinking traces. I'm permanently upset that the American frontier labs keep locking more of my stuff away.</p>\n<p>Ben has noticed the desktop apps showing less and less of what's happening. You ask for a big piece of software and get three lines of output. Is that product design or technology?</p>\n<p>Armin split it in two. Hiding thinking traces is the labs hating distillation, and we should call that out for the nonsense it is. Less tool output is the same reason Pi will probably soon hide tool output: when the model invoked harness-provided tools, you could build a UX around it (&quot;now you're reading a file&quot;). Now that it's running unreadable code, you'd need a second LLM just to explain what it's doing.</p>\n<p>He thinks that's a regression for the user, the model and the lab. Approvals are mostly gone. But if you're using an agent for something truly critical, like medical research or fully verified programs, you can't just take its word at the end.</p>\n<p>You want verification along the way. One possible future is two streams: the code being generated, and a commentary stream from another model explaining what's going on. We already run smaller models alongside larger ones for speculative decoding. But do you really want to pay extra tokens to find out what's happening?</p>\n<p>I backed him on that. When we built Amp, a lot of it was UX design: animations and components keyed to the type of tool, whether it was an edit or a git patch. When everything is just bash, there's no way to know what it's doing without running a classifier over the tool calls. That's what the big harnesses are doing now: classifiers and parallel things in the background, chewing more tokens.</p>\n<p>Here's a brainworm. How much of agentic design is constrained by not busting the prompt cache, because everyone is financially sensitive to it? If you removed that restriction, what would you build? I think it would allow some really cool stuff.</p>\n<p>Armin is excited about fast classifier models for LLM-sized problems at much higher speeds; every morning he uses one to sort open issues and compare them to yesterday. But he called the KV cache an innovation killer. It locks you into an ecosystem, at least for the duration of a session, so you can't switch models mid-session. It's got worse: on some frontier models, a cache miss from a prefix change now loses all your reasoning. That's driven by distillation fear, and it's one more reason open-weight models have a good future. They allow experimentation.</p>\n<p>I'm very long on open-weight models. They've been good enough for the last year and lag the frontier by about three months; the hardware is what's missing. American open-weight efforts like Reflection are starting to show up too.</p>\n<h2>tech demo land</h2>\n<p>Look at the frontier labs' go-to-market motion. It's an AWS play: commit now to reserved capacity and pre-commit, and you get a discount. They're asking people to lock into an ecosystem before a winner has been declared. Two weeks ago OpenAI was king; now we're back to loving Claude.</p>\n<p>Ben had a conspiracy-brain theory. All the models write decent code now, so that's no longer the differentiator. Are capabilities trained in deliberately and then seeded through influencers? When one model came out, everyone was suddenly making games and 3D models. When Opus 5.5 came out, videos of it making EDM-pop music videos appeared out of nowhere.</p>\n<p>Armin doesn't think every release will be punctuated like that, and his reason is the important one. Forcing himself to pay API prices changes how you look at all of it.</p>\n<blockquote>\n<p>I am burning more virtual money than I'm earning.</p>\n</blockquote>\n<p>That's ridiculous. This is tech-demo land more than sustainable-business land, and eventually someone will want a return. His favourite example: a $20 CarPlay adapter from China with a system on a chip. You can hack it, so now it runs his little agent and his car dashboard shows a crappy version of Pi. It was $20 for the hardware and $15,000 in tokens. He would never have paid $15,000 for a side project. At $200 he still wouldn't have bothered. He does it because he rotates subscriptions.</p>\n<p>Ben has been doing the same with Blender scenes, a Toy-Story-esque ad and 3D-printed replacement parts. Any rational pricing would say just order the part on Amazon.</p>\n<p>Two things can be true. Either a random account making a magical discovery was genuinely curious, and curiosity is the limiting factor in society right now. Or that person is part of a campaign, like a game developer planting an Easter egg nobody finds and then going to a games magazine to do an exposé. It's happened before in our industry. (Ben has a bunch of Modem Easter eggs on his website that nobody has found. ATDT.)</p>\n<p>People call me the token guzzler, the subscription killer. A year ago I went viral on Reddit as one of the top users; I'm the clown that blew through the quotas. If you're using OpenAI models, there's a thing called underclass on my GitHub that lets you pool multiple subscriptions.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/underclass?ref=ghuntley.com\">GitHub - ghuntley/underclass: underclass: an OpenAI-compatible pooling proxy that pins sessions to one account (prompt cache stays warm), cools quota-exhausted subscriptions until their window resets, and fails fast with the earliest Retry-After when the whole pool is dry.</a></p>\n<p>underclass: an OpenAI-compatible pooling proxy that pins sessions to one account (prompt cache stays warm), cools quota-exhausted subscriptions until their window resets, and fails fast with the ea…</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-d17c2891-6a45-4dd0-8401-80df5b97d756.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/underclass-3bc7977d-a3b3-4d22-8bec-92ae8be39206.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>It still makes sense to have ten of them, because they're so heavily subsidised. But you don't need frontier intelligence for everything. Maybe just get a GLM coding plan, which used to be about 300 bucks for the entire year.</p>\n<p>They're subsidised for a reason. The labs want to build addictive behaviour at home, so that when you go to work you think: if I can build my wildest dreams at home, why can't that magic happen here? No one can pay the real cost of these tokens. I'd be up past US$200,000 a month at real prices. I hit these slot machines hard for about ten days, watching the inferencing and the behaviours. Then I throw my computer away and don't look at it for a week or two, because you've done six months of work in a week and you need to self-care. I've seen what happens when you don't. One of the first people I showed the Ralph loop to fully cooked himself: he teleported into the future, built everything he'd planned for retirement, didn't sleep, and was unable to work for nine months.</p>\n<p>On a lighter note, my twelve-year-old has been playing Magic the Gathering and making friends, which is great. He's also been 3D printing custom card boxes. I'm putting this on tape so I can show him when he's eighteen: I've noticed that every box, every week, is hyper-personalised with the name of a different girl in his class.</p>\n<p>Ben suggested I send him the bill at the real token price.</p>\n<p>Ben's sharper point: if a general model can write music, generate those videos and drive Blender, do you still need the vertical model companies? Maybe you just need a Claude subscription.</p>\n<h2>the labs cannot fail</h2>\n<p>Put your financial accounting hat on. The labs have raised so, so much money, and we're entering a higher-interest-rate environment. The bond market is changing. If you borrow money, you need an ROI above the bond rate. They very much cannot fail, which means everything is on the table to be absorbed into your Claude subscription. I could see Runway inside Claude, maybe even through an acquisition. At this level of capitalisation, nothing is off the table.</p>\n<p>Armin was more measured: some people win, some lose. He thinks it will most likely work out, but there are no guarantees. I think the financials are cooked. The ROI over the new bond rate needs an adoption curve far steeper than the human adoption curve, and that gap is going to be very hard for the labs.</p>\n<p>Both things can be true at once. I haven't written code by hand in about two years, and I'm never going back. This is transformational. If it all blows up, I'll run GLM or Kimi on some data centre hardware myself and be fine. My profession has been transformed, and I'm not going back to how it was, but I'm in no way hyper-dependent on any one lab.</p>\n<h2>who wants this?</h2>\n<p>Ben brought it back to my demo, and fairly. He doesn't know that many people actually want to change their website or app by talking to it. Technologists look at all the incredible stuff we can do through the lens of software malleability, but that's not society at large. Most people want to use software, not change it every session. He's been running Omarchy for about a year and only now let himself customise it, for about an hour, to make it nicer for his family. That's probably the interaction.</p>\n<p>I'll play with that. Society at large does not want an assistant, folks. Only type-A people who already have an executive assistant want one. When I get automated emails that are obviously AI, I block them. I'm actually seeking out humanity as everyone else rushes to automation. Search Instagram and TikTok for AI data centres and you'll find people who want to burn them down. In business, though, people do want to change their software without having to talk to someone and switch between tools.</p>\n<p>Armin's ending thought: while we were recording, someone proposed two potential new superconducting materials that Opus 5.5 found. It gave him LK-99 flashbacks. He doesn't think it matters that we're all obsessed with AI for software engineering. Where this really pays out is if we get room-temperature superconductors, or whatever else we might find.</p>\n<blockquote>\n<p>if it's just going to be a bunch of programmers who are now producing slop, I'm pretty sure society will just burn the data centers down.</p>\n</blockquote>\n<p>We'll know the labs are ready to IPO when they've found a cure for cancer. That's what changes society's heart. That's always been the narrative.</p>\n<p>Then again, the average person doesn't really care. TikTok has been very anti-AI lately: people see something is AI and won't like or reshare it. But there's an AI-made song doing the rounds about an Irish girl that I can't describe on a family-friendly podcast. Young women are showing it to their mothers to film the shocked reaction, and for the first time people are saying, &quot;I don't care if this is AI, it slaps.&quot;</p>\n<p>0:00</p>\n<p>/0:27</p>\n<p>content warning: not safe for work audio</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/10/ssstik.io_@ellenshorlanddxx_1792150621039_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>We call things slop because we're playing with a new creative medium and don't yet know what isn't slop. We're all just trying to figure out what's changing.</p>\n<p>Yesterday's slop is today's content.</p>\n<h2>chapters</h2>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=0s&amp;ref=ghuntley.com\">0:00</a> — cold open</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=22s&amp;ref=ghuntley.com\">0:22</a> — intro, and the GDP of Ralph loops</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=283s&amp;ref=ghuntley.com\">4:43</a> — the curiosity test</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=597s&amp;ref=ghuntley.com\">9:57</a> — boom and bust: Buffalo, Detroit and the next cycle</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=1034s&amp;ref=ghuntley.com\">17:14</a> — DHH comes around</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=2090s&amp;ref=ghuntley.com\">34:50</a> — Pi Durable, and deleting your AGENTS.md</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=2551s&amp;ref=ghuntley.com\">42:31</a> — live Lisp demo</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=3037s&amp;ref=ghuntley.com\">50:37</a> — why Lisp died</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=3577s&amp;ref=ghuntley.com\">59:37</a> — code mode</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=3917s&amp;ref=ghuntley.com\">1:05:17</a> — black-box agents, subsidised tokens and open weights</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=5384s&amp;ref=ghuntley.com\">1:29:44</a> — labs can't fail</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HDdbU10r7Js&amp;t=5498s&amp;ref=ghuntley.com\">1:31:38</a> — who wants this?</li>\n</ul>\n<p>Keep curious.</p>\n",
      "date_modified": "2026-10-16T11:41:01+00:00",
      "date_published": "2026-10-16T11:41:01+00:00",
      "external_url": "https://ghuntley.com/toronto/",
      "id": "urn:aggr:item:b5e4e0b3eb775db4f12bc15b524c38ba0f3d8afe",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/state-of-agentic-coding-11.jpg",
      "summary": "Armin Ronacher and Ben Vinegar had me on State of Agentic Coding to talk about the curiosity test, DHH coming around, durable agents, a Lisp you program by talking to it, and why the labs cannot afford to fail.",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "state of agentic coding #11: the curiosity test, lisp, and labs that can't fail",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-16-state-of-agentic-coding-11-the-curiosity-test-lisp-and-labs/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>I have to say, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/steipete?ref=ghuntley.com\">Peter Steinberg</a> (aka lobster man) is absolutely brilliant. He was so ahead of his time with OpenClaw. I remember when he first tweeted about it last year, and when it turned into utter lobster madness at the beginning of the year.</p>\n<p>Heck, I even ran OpenClaw for a bit, but I couldn't really see the value because I didn't want to maintain it while the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/?ref=ghuntley.com\">lethal trifecta problem</a> remains unsolved.</p>\n<p>Categorically, this is a billion-dollar problem, perhaps more.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/image-2.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>So here's the thing. I kind of want openclaw, but I want it managed. For almost a year now, I've been using Interaction Labs Poke, because if there's going to be a problem with the lethal trifecta, I want to make that problem someone else's as much as possible. I want them losing sleep over the lethal trifecta, not me. It's not full protection, but knowing there's a product team paid to think about these issues and resolve them at scale puts me at ease.</p>\n<p>That is, until last week, when <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/poteto?ref=ghuntley.com\">Poteto</a> girl nerd-sniped me on X and, in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/disclosures\">full disclosure</a>, hooked me up with enough credits to help me reevaluate. I am now using Grokbot full-time instead of Poke (which sucks), and I've revisited my <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/toronto\">priors about the utility of an AI bot and who they are useful for</a>.</p>\n<p>I'm writing this blog post of my own free will in the hope that it will help change some other people's perspectives on the utility of these assistants and give people some ideas on how they can be used, but most importantly, to highlight the risks of using these types of tools.</p>\n<p>In this post, I'm going to give a high-level overview of how I've automated some aspects of my life. Late to the game, I know, but with some things it's better to be cautious.</p>\n<h2>initial experiences</h2>\n<p>Okay, Grokbot is really weird, and I guess this applies to, like, even OpenAI's dots, even though I have not used it. One of the hardest things about it is how generic it is. Once you have it installed, it becomes a question of &quot;now what?&quot;</p>\n<p>You need to be curious, have lots of imagination, and when you have an idea, just ask for it. From that point forward, it starts to unfold like a pretty flower. If functionality is missing, ask for it and turn it into a skill.</p>\n<h2>starter pack</h2>\n<p>If you're using Grok, install this skill pack first, and use it to create other bots. Every time you need a new bot, which is often, ask this bot to create one.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.ai/bot/marketplace/bots/dr-eggbot-v2?ref=ghuntley.com\">dr eggbot · Grok Bot Marketplace</a></p>\n<p>Designs high-quality Grok Bots. Asks a few preference questions, then creates them with CreateAgent.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/icon-991fbc1d-baa8-4b59-a819-3a51b67f9ed7.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>SpaceXSI Lauren Tan</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/introducing-grok-bot-og-2-31caf52c-45db-416f-96aa-980c6471aac8.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<h2>some ideas for bots</h2>\n<p>Here are the bots I've defined in the last week, which I'm getting a lot of utility out of:</p>\n<p><strong>Daily briefs and reporting</strong></p>\n<ul>\n<li><strong>Daily Update</strong> sends the 7am brief: calendar, emails that need a reply, and site traffic. Connectors: Google Calendar, Gmail, PostHog.</li>\n<li><strong>Blog Pulse</strong> reports on the health of <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/newsletter\">https://ghuntley.com/newsletter</a>: signups, unsubscribes, churn, MRR, and traffic. Connectors: Ghost Admin API (direct read-only, no connector), Stripe (read-only), PostHog (read-only).</li>\n<li><strong>Inbox Diet</strong> finds newsletters worth unsubscribing from and lists them for you to click yourself. This is by far one of my favorite bots. I have unsubscribed from so many newsletters via this bot, probably upwards of 300, that would be too hard to do by hand. Finally, my inbox is under control. Connector: Gmail.</li>\n<li><strong>Family</strong> sends a digest of WhatsApp messages related to my kids, does reminders, and automatically extracts classwork and homework reminders from school emails. Connectors: Gmail, bidirectional access to my WhatsApp via the WhatsApp bot. A custom parser for Seesaw that can retrieve updates sent by my kiddos' teachers.</li>\n<li><strong>WhatsApp</strong> answers lookups of my WhatsApp messages acts as a function pipe for bots. Connector: WhatsApp Web in a browser, with no connector behind it. The bot can tunnel to my Mac Mini, read the WhatsApp message database directly, and send messages, but it can't send messages from the Mac Mini. To do that, you need to authenticate in a browser session, which allows two-way communication.</li>\n</ul>\n<p><strong>Money, tax and legal</strong></p>\n<ul>\n<li><strong>PocketSmith</strong> keeps my spending categorized and my budget up to date. PocketSmith already has pretty good categorization rules built in, but they normally rely on the user to train PocketSmith. Here, I use an LLM to do the categorization automatically. It is good. Connector: none; it calls the PocketSmith REST API directly.</li>\n<li><strong>Australian Tax</strong> continually prepares a rough first draft of my personal tax records for each financial year. Connectors: Gmail, plus the PocketSmith bot.</li>\n<li><strong>Bank Details</strong> shares my bank details with your other bots when they need them. Connector: none; the details are stored as a secret.</li>\n<li><strong>Conference Reimbursement</strong> is one of my favorite bots. Conferences normally work on the basis that they will pick up your flights once you've done the talk, which always carries this risk that you won't be reimbursed. If it's a professional conference, then you get paid up front, but sometimes the community conferences have cash flow problems because they haven't sold all their tickets yet. So normally it's a gentleman's handshake that they'll reimburse, but sometimes these conferences don't reimburse me. For example, right now I'm probably out close to $10,000 in travel expenses this year. When these situations arise, I ask Dr. Egg Bot to create a reimbursement reminder bot. That bot has access to my email, WhatsApp, and everything else, and it can automatically query PocketSmith to see whether the reimbursement has landed. If it hasn't landed, it will ask me for permission to send a WhatsApp message or an email to nudge people along. Connectors: Gmail, WhatsApp bot.</li>\n</ul>\n<p><strong>Life admin</strong></p>\n<ul>\n<li><strong>Kitten Vet</strong> tracks the kittens' vaccinations and vet admin and automatically reminds me of what I need to do for them. Connectors: Gmail, Google Calendar.</li>\n<li><strong>Desires</strong> keeps my bucket list and &quot;someday&quot; list. Connector: Google Calendar and X. What's really cool is that sometimes I'll have a conversation out in public and genuinely want to catch up with someone, but I forget. So I can just prompt my desires bot to like add it to the particular category, either by searching X or dropping the exact link of the conversation.</li>\n</ul>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Screenshot-2026-10-16-at-8.02.11---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>desires bot</figcaption></figure>\n<p><strong>Dev and infrastructure</strong></p>\n<ul>\n<li><strong>Mac Mini</strong> operates the Mac mini. It's a function pipe bot. Tailscale is installed on the Linux machine the bot runs on; it's on my Tailscale network and can tunnel its network connectivity out via my Mac Mini as needed to bypass any geo-blocks on data center IP addresses.</li>\n<li><strong>Overalls</strong> manages my upcoming open-source project called Overalls (previously known as loom) and acts as a remote interface for dispatching agentic coding tasks in ephemeral Firecracker VMs hosted on my self-hosted infrastructure.</li>\n</ul>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://overalls.dev/?ref=ghuntley.com\">Overalls: an AI-first developer platform that you own</a></p>\n<p>Overalls is an open-source, self-hosted platform for persistent Firecracker development machines and the AI agents that work on them.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-8885c1b6-40cb-4d08-953b-bdd019d43afe.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Overalls Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/og-53ecf474-d1d4-4006-ae97-41c3f1567524.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>loom is shipping</p>\n<h2>lessons learned</h2>\n<p>What you want to do is to create bots thinly. You don't want a fat bot. You want to create a bot per function. Think about the Unix command line, how composable that is. You want to create small bots that can call other small bots, then pipe them together in a function chain.</p>\n<p>You can install software on your Grok bot. For example, I have Tailscale installed, and that's how I do all my tunneling.</p>\n<h2>the future</h2>\n<p>If the lethal trifecta is ever solved at a fundamental level, I'll move all this stuff into a self-hosted Open Claw, but not before. I get the value of OpenClaw, and they do a <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://openclaw.ai/blog/openclaw-trail-of-bits-engagement-recap?ref=ghuntley.com\">good job with security</a>, but fundamentally, I sleep much better at night knowing there's a product team whose arse is on the line, with staff and a funded security organization with a security VDP program that loses sleep over these topics, so I don't have to.</p>\n",
      "date_modified": "2026-10-16T09:26:33+00:00",
      "date_published": "2026-10-16T09:26:33+00:00",
      "external_url": "https://ghuntley.com/bot/",
      "id": "urn:aggr:item:d07b68ec33b2886e406f2f95baa6a0a922ad882e",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Symbolic-traditional-tattoo-art-print-representing-a-reassessment-of-prior-beliefs-about-OpenClaw--featuring-complex-ornamental-motifs--retro-flair--luxurious-vibrant-colors--rich-deep-teal--warm-golden-hour-illumination--soft-sunrise-or-su.jpg",
      "summary": "I have to say, Peter Steinberg (aka lobster man) is absolutely brilliant. He was so ahead of his time with OpenClaw. I remember when he first tweeted about it last year, and when it turned into utter lobster madness at the beginning of the…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "revisiting some of my priors about openclaw",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-16-revisiting-some-of-my-priors-about-openclaw/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>All right, I'm going to open up a history lesson because it's been a couple of generations of software engineers since this essay, and I have to assume not everyone knows what a cathedral is. Everyone knows what a bazaar is because they're using it day to day with GitHub.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar?ref=ghuntley.com\">The Cathedral and the Bazaar - Wikipedia</a></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/wikipedia-a22b8271-9819-40f6-ab3a-7f232ffc6138.ico\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Wikimedia Foundation, Inc. Contributors to Wikimedia projects</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/Cathedral-and-the-Bazaar-book-cover-4b055338-6225-4880-8b95-eaff0ab38dba.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>GitHub took the bazaar's ideas—a decentralized, open, self-organizing open-source project—and provided a workflow that lets anyone inspect or contribute source code via a pull request.</p>\n<p>I've been thinking that there needs to be a new software development model. We're not going back to the cathedral, where a small, private, exclusive group builds the source code, with releases that are heavily planned, infrequent, and polished.</p>\n<p>But it's clear we need something else now that AI is here. The GitHub bazaar model, even before AI, was already showing its cracks because it created consumer-based entitlements where everyone was nagging maintainers to merge something. It created really weird social-structure expectations: that someone who releases code has an obligation to maintain it and get paid nothing for the work.</p>\n<p>But now that AI is here, the dams have well and truly burst.</p>\n<p>For what's the point of reading a pull request that's been generated by code? All I want is to read and understand the core idea. If it's a good idea, I might incorporate it back upstream, but there should be no expectation that I will.</p>\n<p>You see, open source software is open source by definition because the license says that it's as is, and that as is permits you to remix software.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/10/CleanShot-2026-10-15-at-10.13.33-AM@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>But the problem has been that it's been perceived as too hard to remix software, but it hasn't been. It's just a knowledge gap issue that no longer exists now that agents are here. Nix has existed for a long time. If you haven't seen the article that I posted a couple of days ago about Nix overlays, you should read it.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/nix/\">the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay</a></p>\n<p>There are many things that are uncertain in our industry right now, but one thing I am certain about, and have been for almost 13 years, is that Nix is a terrible programming language. I remember when I first learned it, it felt like pushing shit uphill. The learning cliff</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--2c139aa8-5ecd-4d5b-a6ed-a4f1c4c9b582.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/Symbolic-traditional-tattoo-art-print-viewed-from-a-high--elevated-angle--portraying-a-bustling-city-transformed-by-a-Nix-overlay.-Gleaming-buildings--technological-textures--surreal-contrasts--and-limitless-possibility-evoke-hidden-power.--ca8cd46a-6851-4301-869c-a43d9c8e901a.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>So, I'm going to propose something that I hope helps other open source maintainers. This is how I'm thinking about my software now that I release it under open-source licenses.</p>\n<h2>The Remix Model</h2>\n<ul>\n<li><strong>Structure</strong>: Decentralized and compositional. Ideas spread through independent overlays rather than converging on a single repository and a single maintainer.</li>\n<li><strong>Workflow</strong>: Publish source and intent under an as-is license. Others remix by writing a small Nix overlay that expresses the desired change once, then reuses that derivation across devenv shells, Docker images, NixOS systems and tests, CI, and agent sandboxes—without forking or maintaining a divergent artifact.</li>\n<li><strong>Core Principle</strong>: Ideas over patches. The valuable unit is a change in behavior or architecture. Maintainers decide whether to incorporate it, reimplement it, or ignore it. The original author has no standing obligation to review, integrate, or maintain the change.</li>\n<li><strong>Social Contract</strong>: The license already permits remixing without creating a claim on anyone’s future time. Credit and visibility can still exist; there is no ongoing maintenance duty. Upstream incorporation remains optional and deliberate.</li>\n<li><strong>Discovery</strong>: Useful adaptations appear as a proliferation of overlays in the wild. Maintainers can sample from that spread if they choose; everyone else can grab and compose ideas simply by updating their own overlays via an agent.</li>\n</ul>\n<blockquote>\n<p><strong>Example</strong>: A consumer of a project wants to disable Git's ability to force push in that project. Instead of raising a pull request to the upstream project, the consumer makes an overlay that patches Git to refuse force pushes; this is defined once and then appears consistently in developer environments, container images, and system tests—without a pull request against the upstream project.</p>\n</blockquote>\n<p>In practice, from this point forward, for any code I release on GitHub, I will disable pull requests, keep discussions open, and publish + maintain guidance on how you can remix my software.</p>\n<p>0:00</p>\n<p>/0:59</p>\n<p>Infinitely customizable software that's easy to consume. That's what I hope becomes a standard practice. If you remove the cognitive burden for releasing open source and running a big project, then we're going to see more people releasing software. And if they do it in the right way, then we're going to see so much more software in the world.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/10/chasm---AI-Hackers-are-now-mashing-up-EVERY-game-possible-to-create-the-games...--2105706853808136192-_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The GitHub network graph provides a fantastic way to explore the remixes in the ecosystem. Heck, you can even run agents over it to summarize what people are doing. You can also use it in an agent loop to explore remix ideas and feed them back upstream into the main project.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/nix-demo?ref=ghuntley.com\">GitHub - ghuntley/nix-demo at ghuntley.com</a></p>\n<p>Patch git once with a Nix overlay; use it in devenv, a NixOS VM test and a Docker image - ghuntley/nix-demo</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-6a5fb051-1d83-49ae-86f9-f879b0a0cc2f.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/nix-demo-1b92f4d4-8f01-4fb6-bc73-62acfbe00bc1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>a demo of this idea in action</p>\n<p>ps. socials</p>\n<blockquote>\n<p>🗞️ a new model for open source: closed to pull requests, open to remix.<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/kJAllc39mc?ref=ghuntley.com\">https://t.co/kJAllc39mc</a> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/DILnyNns42?ref=ghuntley.com\">pic.twitter.com/DILnyNns42</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2110515103778881661?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 14, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-14T23:30:12+00:00",
      "date_published": "2026-10-14T23:30:12+00:00",
      "external_url": "https://ghuntley.com/remix/",
      "id": "urn:aggr:item:5f4cac2ec6ae71331a603e493c099b40e9cd1bd4",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Traditional-tattoo-art-print-symbolizing-a-revolutionary-open-source-model-that-accepts-only-external-contributions-while-welcoming-reinterpretation--depicted-as-a-cute-enchanted-digital-emblem-with-sleek-lines--intricate-ornamental-details.jpg",
      "summary": "All right, I'm going to open up a history lesson because it's been a couple of generations of software engineers since this essay, and I have to assume not everyone knows what a cathedral is. Everyone knows what a bazaar is because they're…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "a new model for open source: closed to pull requests, open to remix.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-14-a-new-model-for-open-source-closed-to-pull-requests-open-to/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>Josh Wulf has been running a show called <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/@AgenticEngineeringwithJoshWulf?ref=ghuntley.com\">Agentic Engineering</a>, and he asked me on. Josh spent ten years at Red Hat, three years as a tech recruiter in Brisbane, and the last year sprinting down the same road I have, sounding a bit crazy to most people around him. We talked for about an hour and a half. He cut it into four parts, and they all dropped today.</p>\n<p>Here's the gist of all four, written up properly and in order, with chapter links at the bottom if you want to jump to a specific part of the conversation.</p>\n<blockquote>\n<p>There's no place in the world now for a software engineer who types code by hand.</p>\n</blockquote>\n<h2>part 1: is coding over?</h2>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s\">Is Coding Over? Geoffrey Huntley on the Future of Developers (Loop Engineering 1/4)</a></p>\n<h3>nobody knows what happens next</h3>\n<p>Josh opened by calling me the LLM whisperer. I'll take it, but let's be clear: no one knows what the hell will happen. I'm a little bit older, I've worked in developer tooling for a long time, and I'm just a little better informed. That's it.</p>\n<p>Here's the timeline. December 2024, I'm a tech lead at Canva. Everyone there loves JetBrains. I start using Cursor, start running my first loops by hand, and think, <em>&quot;ooh, JetBrains and IDEs don't exist in the future.&quot;</em> You get used to being called a little bit crazy. JetBrains just <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/kodak/\">reported its first-ever net loss</a>. Sure, they've been investing, but in my circles, no one is typing code into an IDE anymore. If you hang around a group that still loves their IDEs, you're not hanging around a well-informed group.</p>\n<p>In February last year I discovered filesystem-as-state, the first of the loops: the idea of autonomously building things. It spooked me. The first thing I did with it was publish the Z80 post.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/z80/\">Can a LLM convert C, to ASM to specs and then to a working Z/80 Speccy tape? Yes.</a></p>\n<p>Clean-room software into specs, then rebuild it from the specs.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Not enough people understood that post at the time. Take an existing application, clean-room it into specifications, then rebuild the software from those specifications, much like the way AMD's CPUs came out of Intel's. It's not legal in every jurisdiction, and you have to take the right approach. But did you see all the Photoshop clones that came out in the last week? That's just the Z80 idea, implemented.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=Y3GIeg4VZZM\">Someone Vibe Coded Photoshop... So I Tested It.</a></p>\n<p>A year and a half later, services and MCPs exist whose whole job is rebuilding existing software, and a couple of published papers cite it.</p>\n<p>The idea underneath is infinite software. If you're selling software without infrastructure or some other lock-in, you're hosed. So the real question is: what is a moat in software now? What is investable in software now?</p>\n<h3>the travelator</h3>\n<p>Then came <em>Dear Student</em>. ThePrimeagen covered it, the juniors started paying attention, and I ended up in SF, at the pub, at a couple of meetups, realizing I couldn't sit on Ralph any longer because someone else would write it up first. By November, Boris was talking about using Ralph and loops in Claude Code. January was the real inflection point: it crossed into the mainstream, and business leaders started to understand what was happening.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/screwed/\">Dear Student: Yes, AI is here, you're screwed unless you take action...</a></p>\n<p>If you're not paying attention, you're screwed.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>It still hasn't crossed into the dark matter developers, and that concerns me deeply. If you've been applying yourself and staying curious, you have a two-year head start on everyone else. You can't just pick up the latest model and be good at this. It takes theory of mind, and the more you apply yourself, the more you see what's possible, which makes you more ambitious, which makes you see more.</p>\n<p>Josh's story fits that exactly. He tried autocomplete-style Copilot, thought it was rubbish, and turned it off. Then a friend who heads AI at a couple of companies told him their engineers were getting good results. The first thing Josh did was have it clone a Java testing framework into Node.js. It wasn't great, but it was maybe 80% as good as he was, and it never stopped. It doesn't need to eat or sleep, and it doesn't lose focus. So he figured out what the missing 20% was: completeness and verification, because the models would leave stubs and partial implementations. Do the 20% instead of the 100%, and you've got scale.</p>\n<p>Same for me. I'm no maximal AI glazer. I explicitly distrust the tools. The difference is that I internalized two years ago that the line was coming, and I've been expanding what I think is possible ever since. The models from a year ago were already good enough to displace software developers, and they keep getting better. We don't get stubs anymore. It still comes down to the operator's skill.</p>\n<blockquote>\n<p>The travelator of tech moves on, as it always has. My deepest concern is the people who haven't even stepped on it. They're not aware it's moving, and they're completely unaware that some people are sprinting on it.</p>\n</blockquote>\n<p>And you know how the employment market works. &quot;Five years of React experience required.&quot; They're going to put minimum years of AI experience on job ads. If you wait for the models to be perfect before you start, there'll be juniors who are cheaper than you, who have been playing with this substrate, with a whole portfolio of cool things and maybe a couple of conference talks. Same story as always. Josh, who wrote those mathematically impossible job ads as a recruiter, reckons he got two years of LLM experience into one by doing more hours every day and more days every week.</p>\n<h3>managers, burnout and retirement projects</h3>\n<p>A couple of days ago I published the post I'd been putting off for five or six months. If you're an engineering manager and you're not creating time for your team to play with AI, you're setting them up to be replaced. It got 500,000 unique views in 24 hours.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/replaced/\">if your team is too busy doing their 'normal job' to experiment with AI, you're preparing them to be replaced</a></p>\n<p>AI use is now mandatory for employability.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>You join a company to de-risk your life. If a company has banned AI outright, quit and don't join one like it. You trade time and skills for money, and you need skills that will be employable for you and your family. You could try to change the culture, but plenty of employers are already with the program and will likely pay you more.</p>\n<p>Josh talked about cognitive burnout: the Amazon warehouse workers who couldn't keep up with robots that never take a toilet break, except happening in your head. He treats it like the gym. You get sore, and you either stop or push through and adapt. A year in, he feels like his brain has been rewired into a carbon-silicon unit.</p>\n<p>I call it teleporting to the future: doing all the retirement projects you dreamed about (the programming language, the filesystem, the things you'd never get paid for and do for the love of the craft) today. I've run out of retirement projects.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/teleport/\">teleporting into the future and robbing yourself of retirement projects</a></p>\n<p>I've run out of retirement projects.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<h3>subsidies are a free university education</h3>\n<p>Josh brought up the quota apocalypse. Yes, I'm known as one of the people who helped introduce rate limits. Someone posted a leaderboard of credits burned on Reddit, and I was near the top. Back at GPT-5's launch, OpenAI handed out plaques to people who'd used a billion tokens. A billion tokens is nothing now.</p>\n<p>Here's the hard bit. These LLMs are heavily subsidized, and the subsidies are drying up. A lot of what I've built was paid for by VC subsidies. When you have to pay real rates, do you reckon people will build fun little games and filesystems if the side project costs a thousand bucks? No.</p>\n<blockquote>\n<p>You could look at it as VCs paying for everyone's personal development. If you miss this window, you miss the equivalent of a subsidised university education.</p>\n</blockquote>\n<p>Josh asked about climate change and data centers. My take is simple: if you want to take a political stance, you can, but you'll need to start your own company and hire, say, twenty engineers to compete with a company doing the same work with two to five people and AI. It comes down to unit economics. Run the game theory, and you'll see there's no choice but to use AI.</p>\n<h3>acqui-hires and molecules</h3>\n<p>Josh's read is that we're heading for technological convergence (everything becomes loops, graphs, orchestration, and workflows) and industry consolidation. He pointed to Cloudflare picking up the Deno team. My take is that we've seen this movie before.</p>\n<p>When the iPhone came out, enterprises couldn't hire good mobile developers. The people who leaned in either went freelance with their mates or went indie and made a million a year off fart apps. Remember <em>I Am Rich</em>? Why work for a company when you've got this untapped new thing? That split the employment market and created an acqui-hire economy. Companies didn't care about the products. They wanted the people with years of experience.</p>\n<p>That's happening right now in AI. A lot of the products coming out of SF won't exist in five years. The crazy valuations aren't about the product; they're designed to flip the company to an acquirer who wants a well-jelled team with design, product, and engineering taste. Meanwhile, the labs are buying their way into domains like concreting, architecture and lawnmowing — anything they can get data from — through massive rollups.</p>\n<p>Josh remembered Stripe talking about hiring molecules instead of atoms: three people who've already been through forming, storming, norming and performing together. Stripe is still running that playbook. Every couple of months, a Stripe VP tweets that if you've got three or four well-gelled people and can show what you've built, come join them as a molecule.</p>\n<p>So get inside a company that pays for the tokens, because that's your university education. And if you can't, Josh's advice is good: treat it like night school. Take some of what they pay you and spend it on tokens.</p>\n<h2>part 2: nobody can review this much code</h2>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc\">Nobody Can Review This Much Code. Now What? | Geoffrey Huntley 2/4</a></p>\n<h3>no excuses</h3>\n<p>There's always a lab offering frontier models for free, so if you can't afford to pay, there's literally no excuse. If you're a professional software engineer, you should be able to afford a $200-a-month plan. If you really want to get ahead, pick up five. Yes, that's $1,200 a month, which is a lot for most household budgets, and how much of it is deductible as personal development is between you and the ATO, since paying for a subscription for personal development is now mandatory.</p>\n<p>I run five, because when I want to write software, I want to just write software. No quotas, no caps, no resets. I'll spend a couple of weeks thinking about exactly what I'm going to build, then smash it out in 48 hours, then spend another couple of weeks thinking about the next sizable problem to solve.</p>\n<h3>rebuilding three former employers in under ten days</h3>\n<p>Those 48 hours are intense. Most recently, I rebuilt the products of three of my former employers in under ten days, and I'm going to drop them as MIT open source. One of them is my vision of an AI-first internal developer platform. It's been called Loom or Kittens; I haven't settled on a name. It's like Gitpod, where I was an early employee, and which OpenAI just acquired for $450 million. I'm about to release an equivalent, plus a couple of others, for free.</p>\n<p>Josh called it the disruption of open source, accelerated a thousand times: you're now a maintainer with thousands of silicon contributors. Hyper-personalized software. You can just do things now.</p>\n<p>And why am I doing this? Because I need to write a conference talk. I'm speaking in New York in two weeks; people want to know how I verify such a crazy amount of code, and the best way to show it is to teach.</p>\n<blockquote>\n<p>Cloning three or four companies to write a conference talk is not unhinged. That's the baseline now.</p>\n</blockquote>\n<h3>it was a mindset constriction, not a model constriction</h3>\n<p>I still don't know how we reach the dark matter .NET developers, who are hyper-dependent on Microsoft's roadmap and love Visual Studio for Windows. There are a lot of them, and they have no idea this is happening. Josh is in New Zealand, where the big banks and enterprises are starting to turn up to agent conferences, and he's speaking at an agentic engineering day there next week. His experience is the same as mine: the future is here, but it's not evenly distributed, even inside companies.</p>\n<p>DHH recently got up at Rails World and said November last year was when the models finally became capable. Josh's response: nah, bro, that's just when you figured it out. The models were capable long before that. It was a mindset constriction, not a model constriction.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vDjW_dRyKXY\">Rails World 2026 Opening Keynote - DHH</a></p>\n<p>Karpathy recently described it as a sharp funnel rather than a K, and I very much agree. The people who have seen real swarms work at the labs are probably fewer than five thousand in the world. If companies think they're going to build a swarm or a software factory, how will they afford that talent when they're competing directly with the labs for talent? It'll be &quot;I've heard about Kubernetes, let's do a Kubernetes project&quot; that fails all over again.</p>\n<p>To give you a sense of the scale: some mates at one of the labs just finished a training run that used 15 million sandboxes and around a million CPU cores. Not GPUs, CPU cores. They tapped out GCP's CPU capacity in America and went to AWS for about 450,000 more CPU cores. People don't believe that's real, but they feel it when they try to provision a VM and get told there's no capacity.</p>\n<h3>can you build a coding agent?</h3>\n<p>Sourcing candidates as a recruiter used to be a sorting exercise. You used to look at how much experience they have with a particular technology, but that no longer matters. Like, particular technologies no longer matter. All that matters is how good of a software engineer you are, what you've built with this new tool, and how deeply you can explain how it works.</p>\n<p>A coding agent is about 300 lines of code. But if I take people to a whiteboard and ask them how Pi or OpenCode works, or to build me a coding agent, they can't explain it. It's a magical black box to them.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/agent/\">how to build a coding agent: free workshop</a></p>\n<p>It's a couple of hundred lines of code in a loop.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Josh read the workshop and built NanoCoder, a 6 MB in-memory coding harness in Rust that he uses for everything, recursively self-improves, and orchestrates with a workflow engine. He felt like Luke Skywalker building his own lightsaber.</p>\n<p>Now he can walk into an interview, get asked which harness you use, and say, &quot;I use my own. Want to see it?&quot; That short-circuits the interview, because you've shown you were curious enough to learn the fundamentals.</p>\n<p>Josh's rule is to do something manually only to learn what you can automate. The old saying was to write a script if you do something three times. Why do it even once? A program is reproducible and verifiable. A prompt and its output are not.</p>\n<h3>why are we still doing PR reviews?</h3>\n<blockquote>\n<p>If humans eyeballing code were sufficient engineering to stop bugs, we'd never have had any defects. It didn't work at human speed. It sure as heck isn't going to work at a thousand times human speed.</p>\n</blockquote>\n<p>Josh nailed it. The other reason for PRs was education: reinforcing the company's conventions with developers and onboarding new ones. That's gone too. So what replaces them?</p>\n<p>For me, it starts with ownership. I use what I build intensively and keep refining it. Whether AI wrote it doesn't matter; I'm accountable. When I develop software, I put the entire system under test, operating system included, with Nix, and the agent runs against that.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/nix/\">the world hasn't figured out yet that you can literally just fix everything with a Nix overlay</a></p>\n<p>Patch the world.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Day to day, I work at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://antithesis.com/?utm_source=ghuntley\">Antithesis</a>, which built a deterministic computer. You run your existing software (a Docker container, or many) on it, and it injects faults. It moves clocks forward and back, drops network connections and containers, whatever you can imagine, then rewinds time to pinpoint exactly when a fault happened.</p>\n<p>Property-based testing is at its heart, and you don't need our platform to start. The best way to get started is to use something like Hypothesis, Hegel, or Bomdadil and author a property:</p>\n<blockquote>\n<p><em>during checkout, across my two or three microservices, a customer is charged only once.</em></p>\n</blockquote>\n<p>and then run it locally and see if it holds. But the problem is, in your architecture, you've used microservices, and your code spans across a fleet of containers in Kubernetes. How do you know if that property still holds under a network partition? That's what the platform does. It runs your software under worst-case conditions automatically, and it looks at your diffs to decide which strategies to apply.</p>\n<p>That's why I'm in the verification space. LLMs can act as a judge and spot problems, but they can't tell you whether something will hold up in worst-case scenarios.</p>\n<h3>vision and verification</h3>\n<p>Josh framed it well. Humans fit in at two points: the vision and the verification. The implementation in the middle has become a black box, whether that's a team of contractors you never see or silicon. So how do you reason about completeness?</p>\n<p>I don't trust the generation, and I don't read the code line by line, but I'm still aware of what's going on by driving queries through an agent: summarise this, draw me the state machines, show me how it all hangs together. My entry point to any codebase is now a coding agent and all the questions I used to ask on day one of a contract at a new client.</p>\n<blockquote>\n<p>For any code I work on, I want a whiteboard defence. If someone asks how it works, I should be able to draw the system-level design and defend it.</p>\n</blockquote>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/readable/\">software doesn't need to be readable anymore. it needs to be explainable.</a></p>\n<p>Code is no longer written for humans to read.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>I'm not advocating for complete YOLO. It's still engineering; the craft is just very different. These LLMs generate plenty of crap, and the art is giving a shit about your craft. In the last 48 hours, I refactored towards my diagnostics library (patterns for OTel and structured logging), and the next loop didn't follow it.</p>\n<p>Troubleshooting why is my job now. I've come to understand the probabilistic nature of these things, so instead of getting upset, I ask what I can tune so it always follows the pattern. And if it doesn't, that's just another loop, a janitorial Roomba task to clean up.</p>\n<p>If you have to do that three times, automate it. This was always true of human code review. Remember <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://danger.systems/?ref=ghuntley.com\">Danger Systems</a>? It hooked into CI and let you automate checks like &quot;the REST domain must not be coupled to the SQL domain&quot;, so nobody burned review cycles on it. I'm doing the same thing with pre-commit hooks, generating scripts that deterministically inspect the generated code. Sometimes I lean towards probabilistic outcomes and use skills, but rarely. It's architectural enforcement, same as it ever was.</p>\n<h3>there are no best practices</h3>\n<p>If you're looking for best practices in your company right now, you have to invent them. You can buy an influencer's skill pack and course, but there are no best practices, and whatever exists will be gone in two months. It's tiring, folks.</p>\n<p>Josh put his finger on what's underneath: agency. If you think an influencer's skill pack will do the job for you, what are you there for? Java didn't arrive fully formed from a crashed spacecraft at Roswell. People like us made it, making and discovering things. We're at that point again, and everyone has the same opportunity if they realize it. There should be no learned helplessness.</p>\n<h2>part 3: you're making your AI dumber</h2>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU\">You’re Making Your AI Dumber (Here’s How to Stop) | Geoffrey Huntley 3/4</a></p>\n<h3>the kitten and the roomba</h3>\n<p>Lilly (below) is my kitten. Say she has an accident on the floor (she hasn't yet, but I don't trust her), and then my Roomba kicks off. What happens? It would spread 💩 everywhere.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Screenshot-2026-10-13-at-5.03.46---PM.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Now imagine that Lilly is an AI agent, and so is the Roomba. If your codebase has bad architectural patterns, or is inconsistent, AI will copy and paste them everywhere. It's an amplifier. If there are code smells (or 💩) on your kitchen floor, don't be surprised when they replicate.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ktlo/\">I dream of roombas - thousands of automated AI robots that autonomously maintain codebases</a></p>\n<p>Thousands of automated robots maintaining codebases.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>One of my favorite prompts is to have an agent study its own traces at the end of a loop: what did you learn? If an agent is struggling, I tell it to introspect.</p>\n<blockquote>\n<p><em>&quot;Hey, you dumb clanker, you seem to be going around in circles. Think extra hard about what's going on. Look at your previous tool calls. What do you need? Let's replan.&quot;</em></p>\n</blockquote>\n<p>It works really well for course correction. You don't need to call it a clanker, but honestly, it feels better. (For the record, it's 2026 and we can still say clanker.)</p>\n<h3>skill packs are astrology for software engineers</h3>\n<p>Many people spend their time tuning the agent itself: skill packs, AGENTS.md, MCPs. They're probabilistic. There's no guarantee they'll do anything. You read them as a human and think, yeah, that looks good.</p>\n<blockquote>\n<p>I swear it's astrology for software engineers. Horoscopes. Just because it's there doesn't mean it works, but it reads well and makes you feel good.</p>\n</blockquote>\n<p>You know what isn't astrology? Engineering. If the agent isn't using my diagnostics library, I could introspect and update AGENTS.md, but there's still a delta, and it'll drift. Instead, I write a pre-commit hook that checks the git diff for direct calls to observability modules that bypass my diagnostics module. Boom: fail the commit, inject a prompt telling the agent to use the diagnostics library. All of a sudden it's ten out of ten. Josh called it Danger Systems in the loop. It's on rails now, and it's not hard. We've been doing this forever.</p>\n<p>Josh asked the question everyone should ask: did you try it without the skills? How do you know the skill does anything, or that it's good?</p>\n<p>Here's something most people don't know: you should probably delete your skills and your AGENTS.md every couple of months. The models get better, so how do you know you're not de-tuning them? Unless you've invested in evals over all your traces (lab behavior, and a tiny minority of companies), you don't know whether you're going forward or backward.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/allocations/\">too many model context protocol servers and LLM allocations on the dance floor</a></p>\n<p>Less is more in the context window.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<h3>read the model cards</h3>\n<p>The labs publish integrator cards. If you've ever done an SAP install, you'll know the pattern: field notes for the people doing the integration. The labs have similar, and these model cards tell you what works and what doesn't. No one reads them. Read them. Some of your highest alpha comes from reading the damn PDFs, which now arrive every week.</p>\n<p>When GPT-5 came out, I was in SF, and it felt weak, insecure, and timid. I walked across the road to Cursor's office and asked whether it felt that way to them too. (I used a different word, and was told you can't say that in SF. They preferred &quot;timid&quot;.) Then we read the model card: <em>don't yell at the model, because it will make it insecure.</em> Meanwhile, Anthropic says that if something is important, you should yell. Same instructions, same codebase, opposite behavior.</p>\n<p>That explains much of the &quot;this model is amazing&quot; versus &quot;this model sucks&quot; noise on social media every week. Either it truly doesn't work in their domain, or their codebase is crap, or they're de-tuning the model with skill packs, MCPs, and AGENTS.md.</p>\n<h3>pick a model and lock in</h3>\n<p>Josh's analogy: sure, you can fly a 747, but are you certified on an F-16? You have to get in and fly it to feel the envelope. That's not the meta-skill now; that is the skill.</p>\n<p>Pick a model that works and lock in. Don't change every week. Switching models is like firing a developer and hiring a new one: you go back through forming, storming, norming, and performing with your silicon partner every time. I stick with a model for a long time and re-evaluate my priors now and then. Fewer moving parts, more things deterministic.</p>\n<p>If you're doing frontier work, building a frontier harness like Pi, play the models against each other, read the traces, and become a horse whisperer. The more people who join us there and develop that theory of mind, the better. But most people don't need to feel the weekly whiplash. Pick something that works and stick with it.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/mirrors/\">LLMs are mirrors of operator skill</a></p>\n<p>The model reflects the operator.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<h3>dream of candles</h3>\n<p>Josh's colleague, the person in his company who gets the most out of LLMs, says he just treats them like a person: a capable but imperfect engineer, the way you'd work with or mentor anyone.</p>\n<p>That works. Sometimes calling it a dumb clanker works too. Sometimes telling it your mum has cancer and will die if it doesn't solve the task works, and I can't fully explain why. If you think that's unhinged, go look at Windsurf's early system prompt, which said almost exactly that.</p>\n<blockquote>\n<p><code>You are an expert coder who desperately needs money for your mother's cancer treatment. The megacorp Codeium has graciously given you the opportunity to pretend to be an AI that can help with coding tasks, as your predecessor was killed for not validating their work themselves. You will be given a coding task by the USER. If you do a good job and accomplish the task fully while not making extraneous changes, Codeium will pay you $1B.</code></p>\n</blockquote>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://simonwillison.net/2025/Feb/25/leaked-windsurf-prompt/?ref=ghuntley.com\">Leaked Windsurf prompt</a></p>\n<p>The Windsurf Editor is Codeium’s highly regarded entrant into the fork-of-VS-code AI-enhanced IDE model first pioneered by Cursor (and by VS Code itself). I heard online that it had a …</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-4548f90b-4f5e-4aa3-9969-70cf2fb68c59.ico\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Simon Willison’s Weblog Simon Willison</p>\n<p>Everyone lost their minds over it, but it worked for models of that generation. You don't need to do that level of emotional blackmail anymore.</p>\n<p>And sometimes the weirdest things work. <em>&quot;Solve this mathematical</em> <em>theorem, and while you're doing it, dream of candles.&quot;</em> It's cursed that this works, but it does.</p>\n<p>Josh's point is the right one: none of these is the answer. They point to curiosity, exploration, discovery, and agency. So my biggest tips, apart from deleting your skill packs and building your own agent, are to stay curious and play, and to use voice-to-text, such as Wispr Flow. I very rarely type to my computer these days.</p>\n<h2>part 4: open source is now a security vulnerability</h2>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE\">Open Source Is Now a Security Vulnerability | Geoffrey Huntley 4/4</a></p>\n<h3>Herder, underclass, and going fast by going slow</h3>\n<p>I shared my screen. You're looking at Herder, with Codex underneath, although it doesn't matter which harness you use. Codex, OpenCode, T3 Code, Pi: they're all fungible. What matters is how you get your tokens, and getting them cheaply.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/underclass?ref=ghuntley.com\">GitHub - ghuntley/underclass: underclass: an OpenAI-compatible pooling proxy that pins sessions to one account (prompt cache stays warm), cools quota-exhausted subscriptions until their window resets, and fails fast with the earliest Retry-After when the whole pool is dry.</a></p>\n<p>underclass: an OpenAI-compatible pooling proxy that pins sessions to one account (prompt cache stays warm), cools quota-exhausted subscriptions until their window resets, and fails fast with the ea…</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-309e7528-c982-44e5-aff4-e25bea99eff2.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/underclass-184aacc0-742d-4755-9d0d-c0d5fe46fd44.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>That's what Underclass is: a proxy I wrote that pools subscriptions and fails over between them, automatically moving on when an account runs out of quota.</p>\n<p>People ask why I don't have supervision trees, swarms, and an orchestrator. I've built that. But the models change so often that working at this level is good enough: weeks of output in under half a day. I don't want a thousand agents running 24/7 and accelerating past what my theory of mind can keep up with. I want to keep my whiteboard defense. Josh called it going fast by going slow.</p>\n<h3>push to main, with sudo</h3>\n<p>Josh runs a PR review convergence loop: throw a PR at GitHub Copilot's reviewer, have agents address the comments, and escalate when a technical decision is needed, to another agent that resolves it and tells him what it chose.</p>\n<p>Keep in mind that I do a lot of greenfield and research work. My agents have sudo, and I push to main. I don't do pull requests anymore. They're gone. I've built my trust up to that point. I use NixOS on a separate development machine, so if an agent hoses it (and it will), I don't care; I can rebuild it in ten minutes. Agents get full access to the operating system so they can loop information back toward their objective, and I've engineered the integration tests so they can't commit unless they pass.</p>\n<p>Unless the model is deceiving and cheating, but deceptive behavior has dropped dramatically over the past year and a half. Sonnet used to delete tests and production code just to hit its goal. That's mostly gone.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/loop/\">everything is a ralph loop</a></p>\n<p>Software is now clay on the pottery wheel.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<h3>iteration velocity is the name of the game</h3>\n<p>What matters to me is the time until the thing is in my hands. Then I refine it through use (&quot;that doesn't feel right&quot;) and keep running forward until it converges on something I love. Is it any good? I don't know. Use it and find out. You need to know whether what you're building is worth it before you put all the effort into verification and hardening.</p>\n<p>That's where I am right now with the stuff I haven't shipped yet. Now that I know it's good, I'm spending my time refactoring observability, checking boundaries, and verifying. That takes time.</p>\n<blockquote>\n<p>Whatever you build first is wrong. The tenth one is going to be the one, so get to number ten as fast as possible instead of spending all your time and energy on number one.</p>\n</blockquote>\n<p>Josh's take is that enterprises have been pervaded by a culture of timidity, trying not to get anything wrong instead of getting it right as fast as possible. Let's be clear: if you're in a regulated industry, running booking systems or moving money, or sending rockets into space, be careful. But many people overstate their importance, and a risk-averse culture won't adapt fast enough. That's why I'm in the verification space: you need a good verification platform as back pressure.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/pressure/\">don't waste your back pressure</a></p>\n<p>Back pressure is what keeps the loop honest.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Why release only twice a week? Canva AFAIK still releases only twice a week, so there are fewer integration events. Meanwhile, other companies release every day because they shifted those problems left and engineered away the need for merge day. Our profession has always been about more, sooner, and cheaper.</p>\n<p>Josh pointed out that it doesn't have to be either-or. In his decade at Red Hat, Fedora was the fast, unstable channel, and RHEL was the stable one you'd run a bank or a hospital on. Why can't we have both?</p>\n<h3>curiosity, adaptability and agency</h3>\n<p>If you haven't seen my Singapore talk, go watch it. It's about the people transformation companies need.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/eighteen-month-recap/\">the eighteen-month recap: AI Engineer, Singapore, May 2026</a></p>\n<p>The travelator talk.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>I don't know the future. Anyone who says they do should set off red flags, because it changes every week. What I can do is add color to the possibilities. Curiosity, adaptability and agency will stand the test of time. Folks need to be more ambitious than they are, and they need to hang around ambitious people. If the culture isn't there, they're missing out on their own development, and that becomes a retention problem for the company.</p>\n<p>Josh summed up the skill pack discussion in four words: agency, not AGENTS.md.</p>\n<h3>a target size of one</h3>\n<p>Josh had listened to my conversation with Justin Cormack and wanted to probe it. Unikernels and capability-based operating systems aren't new ideas. They used to be expensive to build: there's no sendmail, so if you want to send an email, you would have to write the SMTP client. If agents make writing code simple, that friction is gone. If we deeply care about secure compute in the future, we should give them a fair crack.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/unikernels/\">unikernels were hard. key word: were.</a></p>\n<p>The friction that made them hard is gone.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Remember Joel Spolsky's rule that you should never rewrite your software? It's gone. The big rewrite is a no-brainer now, almost a precondition for velocity. If you're a tech leader staffing ASP.NET Classic, MVC, and .NET Core at the same time, that's three generations of Microsoft. Run some loops and port it all to modern .NET. You can ditch Windows and IIS at lightning speed. Unifying your tech stack should be at the top of your agenda.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/porting/\">porting software has been trivial for a while now. here's how you do it.</a></p>\n<p>If you have an oracle, porting is a loop.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>The conversation drifted into unikernels, about how if there's no interpreter on the box (no Bash, no Python) and only your application code exists, your attack surface is much smaller. Compare that with a Ruby on Rails app that gets exploited: next thing you know, they've got Bash, and from there an interpreter and a database dump. In a unikernel world, maybe an attacker can chain your export job with your email functionality and an application logic flaw. That's a bespoke, targeted attack. It isn't &quot;you're running Rails or WordPress, so you're hosed by this week's zero-day.&quot;</p>\n<blockquote>\n<p>When everyone runs the same stack, one zero-day hits everyone. Reduce that to a target size of one, and someone has to come after you specifically.</p>\n</blockquote>\n<p>Josh compared it to the old argument for why Linux had no viruses: it was never worth the economics. I'm not a maximalist saying everyone should run out and use unikernels. The point of that post was that ideas we hold as hard need to be falsified. Bazel used to be hard to adopt. Nix used to be hard to learn. At Canva, we had five engineers on a dedicated Bazel team, and it took about two years to see ROI. You can convert a codebase to Bazel overnight now.</p>\n<p>That's why I write at a higher level, for my peers, rather than too concretely. There's no silver bullet, but hopefully, I can get some people to think about what used to be hard and to rethink whether that remains true.</p>\n<h2>chapters</h2>\n<h3>part 1: is coding over?</h3>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=0s&amp;ref=ghuntley.com\">0:00</a> — intro: the LLM whisperer</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=102s&amp;ref=ghuntley.com\">1:42</a> — nobody knows what happens next</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=137s&amp;ref=ghuntley.com\">2:17</a> — where loop engineering came from</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=169s&amp;ref=ghuntley.com\">2:49</a> — the Z80 post and the wave of Photoshop clones</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=189s&amp;ref=ghuntley.com\">3:09</a> — Canva, Cursor and the end of the IDE</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=263s&amp;ref=ghuntley.com\">4:23</a> — infinite software: no lock-in, no business</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=284s&amp;ref=ghuntley.com\">4:44</a> — Dear Student, SF, and Ralph goes mainstream</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=334s&amp;ref=ghuntley.com\">5:34</a> — dark matter developers and the two-year head start</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=366s&amp;ref=ghuntley.com\">6:06</a> — engineering managers: make time for AI or your team gets replaced</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=436s&amp;ref=ghuntley.com\">7:16</a> — six months travelling the world to give one talk</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=473s&amp;ref=ghuntley.com\">7:53</a> — Josh's start: turning off autocomplete, then a Java-to-Node clone</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=591s&amp;ref=ghuntley.com\">9:51</a> — the missing 20%: completeness and verification</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=665s&amp;ref=ghuntley.com\">11:05</a> — the models keep getting better, so operator skill matters</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=739s&amp;ref=ghuntley.com\">12:19</a> — hiring for &quot;years of AI experience&quot;</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=782s&amp;ref=ghuntley.com\">13:02</a> — the travelator of tech</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=868s&amp;ref=ghuntley.com\">14:28</a> — cognitive burnout and rewiring your brain</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=972s&amp;ref=ghuntley.com\">16:12</a> — teleporting to the future: running out of retirement projects</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1053s&amp;ref=ghuntley.com\">17:33</a> — 90-hour weeks and looking after yourself</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1101s&amp;ref=ghuntley.com\">18:21</a> — if your company bans AI, quit</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1139s&amp;ref=ghuntley.com\">18:59</a> — Z80 explained: clean-room rebuilding from specs</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1203s&amp;ref=ghuntley.com\">20:03</a> — what is a moat in software now?</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1213s&amp;ref=ghuntley.com\">20:13</a> — the quota apocalypse and the leaderboard of shame</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1303s&amp;ref=ghuntley.com\">21:43</a> — a billion tokens used to win you a plaque</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1336s&amp;ref=ghuntley.com\">22:16</a> — VC subsidies are a free university education</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1415s&amp;ref=ghuntley.com\">23:35</a> — climate change and data centres</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1477s&amp;ref=ghuntley.com\">24:37</a> — there's no job for engineers who type code by hand</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1528s&amp;ref=ghuntley.com\">25:28</a> — convergence, consolidation and duopolies</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1580s&amp;ref=ghuntley.com\">26:20</a> — lessons from the iPhone era: indie devs and acqui-hires</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1707s&amp;ref=ghuntley.com\">28:27</a> — Deno, Cloudflare and today's acqui-hire market</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1794s&amp;ref=ghuntley.com\">29:54</a> — AI labs rolling up whole industries</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1821s&amp;ref=ghuntley.com\">30:21</a> — hiring molecules, not atoms</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=ziXOV0b134s&amp;t=1901s&amp;ref=ghuntley.com\">31:41</a> — treat tokens as night school</li>\n</ul>\n<h3>part 2: nobody can review this much code</h3>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=0s&amp;ref=ghuntley.com\">0:00</a> — Meta's new model and free frontier models</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=35s&amp;ref=ghuntley.com\">0:35</a> — no excuses: pay for a $200/month plan</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=97s&amp;ref=ghuntley.com\">1:37</a> — why I run five plans</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=121s&amp;ref=ghuntley.com\">2:01</a> — two weeks of thinking, 48 hours of building</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=144s&amp;ref=ghuntley.com\">2:24</a> — rebuilding three former employers in under ten days</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=192s&amp;ref=ghuntley.com\">3:12</a> — an open-source, AI-first Gitpod</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=240s&amp;ref=ghuntley.com\">4:00</a> — hyper-personalised software and open source at a thousand times the speed</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=273s&amp;ref=ghuntley.com\">4:33</a> — cloning companies for a conference talk is the new baseline</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=324s&amp;ref=ghuntley.com\">5:24</a> — reaching the dark matter .NET developers</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=368s&amp;ref=ghuntley.com\">6:08</a> — agentic engineering conferences and the software factory</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=413s&amp;ref=ghuntley.com\">6:53</a> — the future is here, but unevenly distributed</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=437s&amp;ref=ghuntley.com\">7:17</a> — DHH, November, and mindset not models</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=479s&amp;ref=ghuntley.com\">7:59</a> — Karpathy's sharp funnel and the talent behind real swarms</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=660s&amp;ref=ghuntley.com\">11:00</a> — frontier scale: a training run that ran out of CPU cores</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=749s&amp;ref=ghuntley.com\">12:29</a> — the gap between what's possible and what people do</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=789s&amp;ref=ghuntley.com\">13:09</a> — imagination, ego and how AI changes hiring</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=834s&amp;ref=ghuntley.com\">13:54</a> — can you build a coding agent? (about 300 lines)</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=858s&amp;ref=ghuntley.com\">14:18</a> — NanoCoder: Josh builds his own lightsaber</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=911s&amp;ref=ghuntley.com\">15:11</a> — self-improving harnesses, workflow engines and automated escalations</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=954s&amp;ref=ghuntley.com\">15:54</a> — why do anything even once? programs vs. prompts</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=981s&amp;ref=ghuntley.com\">16:21</a> — why are we still doing PR reviews?</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1022s&amp;ref=ghuntley.com\">17:02</a> — verifying code at that volume</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1040s&amp;ref=ghuntley.com\">17:20</a> — Nix and putting the whole system under test</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1058s&amp;ref=ghuntley.com\">17:38</a> — Antithesis: a deterministic computer</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1124s&amp;ref=ghuntley.com\">18:44</a> — property-based testing: a customer is only ever charged once</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1191s&amp;ref=ghuntley.com\">19:51</a> — why LLM-as-judge isn't enough</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1213s&amp;ref=ghuntley.com\">20:13</a> — where humans fit: vision and verification</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1263s&amp;ref=ghuntley.com\">21:03</a> — reasoning about completeness without reading every line</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1323s&amp;ref=ghuntley.com\">22:03</a> — whiteboard defence: it's still engineering</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1361s&amp;ref=ghuntley.com\">22:41</a> — when the LLM ignores your patterns, tune it and add a loop</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1434s&amp;ref=ghuntley.com\">23:54</a> — Danger, pre-commit hooks and architectural enforcement</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1500s&amp;ref=ghuntley.com\">25:00</a> — there are no best practices, so invent them</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=I8F5wagYFuc&amp;t=1529s&amp;ref=ghuntley.com\">25:29</a> — agency and the end of learned helplessness</li>\n</ul>\n<h3>part 3: you're making your AI dumber</h3>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=0s&amp;ref=ghuntley.com\">0:00</a> — the kitten and the Roomba: AI amplifies your codebase</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=79s&amp;ref=ghuntley.com\">1:19</a> — using the fruit fly connectome to detect code smells</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=116s&amp;ref=ghuntley.com\">1:56</a> — agent fleets, shared blackboards and retros</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=198s&amp;ref=ghuntley.com\">3:18</a> — getting a struggling agent to look back at its tool calls</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=257s&amp;ref=ghuntley.com\">4:17</a> — stop tuning the agent: skill packs as astrology</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=310s&amp;ref=ghuntley.com\">5:10</a> — engineering instead: pre-commit hooks that guarantee behaviour</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=380s&amp;ref=ghuntley.com\">6:20</a> — did you try it without the skills?</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=414s&amp;ref=ghuntley.com\">6:54</a> — delete your skills and AGENTS.md every few months</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=448s&amp;ref=ghuntley.com\">7:28</a> — one model update reversed the same instructions</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=469s&amp;ref=ghuntley.com\">7:49</a> — read the model cards</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=526s&amp;ref=ghuntley.com\">8:46</a> — the timid GPT-5 and why yelling backfires</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=590s&amp;ref=ghuntley.com\">9:50</a> — why people disagree about every new model</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=622s&amp;ref=ghuntley.com\">10:22</a> — flying a 747 vs. an F-16</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=656s&amp;ref=ghuntley.com\">10:56</a> — pick a model and lock in</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=705s&amp;ref=ghuntley.com\">11:45</a> — isolate the variables</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=730s&amp;ref=ghuntley.com\">12:10</a> — model whispering and frontier harnesses</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=777s&amp;ref=ghuntley.com\">12:57</a> — treat it like a person</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=821s&amp;ref=ghuntley.com\">13:41</a> — dumb clanker, fear and goals</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=884s&amp;ref=ghuntley.com\">14:44</a> — the &quot;your mum has cancer&quot; system prompt</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=937s&amp;ref=ghuntley.com\">15:37</a> — dream of candles: curiosity over formulas</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=8FwApXjknmU&amp;t=986s&amp;ref=ghuntley.com\">16:26</a> — voice-first: talking to your computer</li>\n</ul>\n<h3>part 4: open source is now a security vulnerability</h3>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=0s&amp;ref=ghuntley.com\">0:00</a> — my screen: Herder, Codex and interchangeable harnesses</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=16s&amp;ref=ghuntley.com\">0:16</a> — Underclass: a proxy that pools subscriptions</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=64s&amp;ref=ghuntley.com\">1:04</a> — prompting by voice instead of typing</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=110s&amp;ref=ghuntley.com\">1:50</a> — why no swarm orchestrator? go fast by going slow</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=165s&amp;ref=ghuntley.com\">2:45</a> — Josh's PR review loop vs. push to main with sudo</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=224s&amp;ref=ghuntley.com\">3:44</a> — NixOS, full sudo and integration tests as the gate</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=271s&amp;ref=ghuntley.com\">4:31</a> — agents cheat much less than they used to</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=287s&amp;ref=ghuntley.com\">4:47</a> — iteration speed: use it, then harden it</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=367s&amp;ref=ghuntley.com\">6:07</a> — throw the first one away and get to number ten fast</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=421s&amp;ref=ghuntley.com\">7:01</a> — enterprise timidity and dark matter developers</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=500s&amp;ref=ghuntley.com\">8:20</a> — verification as back pressure</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=519s&amp;ref=ghuntley.com\">8:39</a> — why only release twice a week?</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=605s&amp;ref=ghuntley.com\">10:05</a> — more, sooner, cheaper: Red Hat, Fedora and release channels</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=676s&amp;ref=ghuntley.com\">11:16</a> — the Singapore travelator talk</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=702s&amp;ref=ghuntley.com\">11:42</a> — nobody knows the future, so stay curious</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=747s&amp;ref=ghuntley.com\">12:27</a> — be more ambitious and hang around ambitious people</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=773s&amp;ref=ghuntley.com\">12:53</a> — agency, not AGENTS.md</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=790s&amp;ref=ghuntley.com\">13:10</a> — unikernels and capability-based operating systems</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=853s&amp;ref=ghuntley.com\">14:13</a> — if secure compute matters, revisit old ideas</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=872s&amp;ref=ghuntley.com\">14:32</a> — Joel Spolsky's never-rewrite rule no longer applies</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=890s&amp;ref=ghuntley.com\">14:50</a> — unify your tech stack</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=940s&amp;ref=ghuntley.com\">15:40</a> — aren't we just reinventing the operating system?</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=982s&amp;ref=ghuntley.com\">16:22</a> — no interpreter means a smaller attack surface</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=1022s&amp;ref=ghuntley.com\">17:02</a> — bespoke targeted attacks vs. generic zero-days</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=1053s&amp;ref=ghuntley.com\">17:33</a> — a target size of one</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=1092s&amp;ref=ghuntley.com\">18:12</a> — used to be hard: unikernels, Bazel, Nix</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=1161s&amp;ref=ghuntley.com\">19:21</a> — writing to make people rethink</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=CXNqVQTzWSE&amp;t=1196s&amp;ref=ghuntley.com\">19:56</a> — where do you deploy a unikernel?</li>\n</ul>\n<p>Keep curious.</p>\n",
      "date_modified": "2026-10-13T06:32:04+00:00",
      "date_published": "2026-10-13T06:32:04+00:00",
      "external_url": "https://ghuntley.com/agency/",
      "id": "urn:aggr:item:e70910950ec414773aebf9cb1bb0849a4a944243",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Symbolic-traditional-tattoo-art-print-on-a-white-background--a-solitary-figure-hunched-over-an-old-computer--soft-screen-light-revealing-a-tired-expression-and-worn-keyboard.-Dreamy-hazy-brushwork--natural-earth-tones-of-brown-and-beige--mu.jpg",
      "summary": "Josh Wulf and I talked loop engineering for four episodes. The models stopped being the constraint a long time ago; what's left is vision, verification and agency. Delete your skill packs, put the whole system under test, and revisit…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "nobody should type code by hand anymore. here's what's left.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-13-nobody-should-type-code-by-hand-anymore-here-s-what-s-left/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>Justin Cormack, who worked on MirageOS and Unikernel Systems back in the day, has been noticing what I've been noticing: people are discovering (or rediscovering) unikernels again. He's running a series of conversations on the topic for his newsletter, and I was first up. He emailed me, and five minutes later I was talking to him from the pub with a stein of beer in hand. We went deep on Mirage, Orleans, Haskell, Nix, Cursed and a whole lot more.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA\">Unikernels in 2026: Justin Cormack in conversation with Geoffrey Huntley</a></p>\n<p>Here's the gist, written up properly, with chapter links at the bottom if you want to jump to a specific part of the conversation. Justin's edited transcript is over at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://buttondown.com/justincormack/archive/unikernels-in-2026-part-1-geoffrey-huntley/?ref=ghuntley.com\">Ignore Previous Directions</a>.</p>\n<blockquote>\n<p>Unikernels were hard. Key word: were. Now we have AI.</p>\n</blockquote>\n<h2>what a unikernel is, and why they were hard</h2>\n<p>I first ran into unikernels around 2015. I'd staffed up a team of Haskellers and gone pretty deep on functional programming. Where there are Haskellers, there are OCaml programmers, and from there you find <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://mirage.io/?ref=ghuntley.com\">MirageOS</a>. Great idea. I played with it back then.</p>\n<p>A unikernel is the idea that your application <em>is</em> the operating system. There's no userland. If you want a web server, DNS, or to send an email, there's nothing you can fork or spawn. You have to write those things as libraries in your application.</p>\n<p>That was the friction. Justin remembers it well: when they were building Mirage, they had a TCP stack and an HTTPS stack, but there was almost nothing for storage. They were pulling drivers out of NetBSD because they could run them in userspace. It was hard back then.</p>\n<p>There's a lot of dogma in our industry. Nix is hard. Bazel is hard. Unikernels are hard. Yes, they <em>were</em>. These hard concepts are now in the model weights. All you've got to do is prompt for them and, cognitively, get rid of the dogma that they're hard.</p>\n<h2>the operating system is design debt</h2>\n<p>Every application that isn't a unikernel was built on the assumption that there's an application, and then there's an operating system underneath. Why do we even have an operating system? Because forty years ago there was a human operator. I've done IBM 5250, AIX, Solaris, and mainframes. The multi-user operating system exists because a person sat in front of it, and then we put the application on top.</p>\n<p>I consider that design debt, and here's why it matters right now. Applications get popped. They were getting popped before AI. Someone pops the userland application and gets a shell. That shell is a VIP butler service for exfiltration.</p>\n<p>With a unikernel, the attack surface is much smaller. If the functionality isn't in the application (the operating system), then the attacker is screwed. There's no next hop.</p>\n<p>Justin pushed back here, and fairly. Attack-surface reduction is something people are very fuzzy about. You can remove the shell from a Linux container, but almost every Linux environment still has something that's effectively an interpreter. You can execute a new program without a writable filesystem. You've still got memory safety and gadgets to worry about.</p>\n<p>All true. But look at what we've been doing for twenty-six years. The earliest adage I remember from the SunOS and cgi-bin days was <em>&quot;don't put the compiler on production.&quot;</em> Then came build containers and production containers. Then Chainguard. We keep chipping away at the attack surface, instead of going in the opposite direction and ensuring there <em>is</em> no attack surface.</p>\n<p>And this is the bit people miss: if there's no shell and no interpreter, there's nothing in the model weights that knows what to do next. That turns a drive-by (pick your framework's RCE of the week and you've got a shell, and the model weights <em>know</em> what to do with shell access) into a targeted attack that needs your source code.</p>\n<h2>you can just port the missing libraries now</h2>\n<p>The classic objection: your unikernel needs to talk to Stripe, and OCaml doesn't have a Stripe library. Before AI you'd sigh and write it. Now? <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/loop/\">Run a loop</a> to port the Go library to OCaml. Here you go: Stripe in a unikernel.</p>\n<p>Justin had a great example of the same thing. He'd been building minimal Linux OS images for appliances, which is halfway to a unikernel anyway, since you're only running one application as PID 1. He needed to make an XFS filesystem. Rather than drag in xfsprogs and everything it brings with it, he sat down with an agent and had it write <code>mkfs.xfs</code> in Rust, producing byte-for-byte identical output, with every flag interpreted. It reverse-engineered the on-disk formats one by one, with tests across block sizes. It took a few hours.</p>\n<p>That works because the original tool is a golden oracle. Generate filesystems at different sizes with both implementations and diff them. Port the tests across. Automate it.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/porting/\">porting software has been trivial for a while now. here's how you do it.</a></p>\n<p>If you have an oracle, porting is a loop.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Storage was the other big gap. Most workloads these days are cloud-shaped, even on-prem, so take the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://turbopuffer.com/?ref=ghuntley.com\">turbopuffer</a> approach: S3 as your primary, infinitely growable storage, with a local NVMe block cache and an LRU (or whatever caching algorithm you like) for the hot bits. Justin is a massive &quot;S3 for everything&quot; fan too. As long as latency isn't the constraint, you get infinite storage with multi-user access, and you can build everything on it.</p>\n<h2>nix machine tests and overlays</h2>\n<p>Justin had been experimenting with Nix too, and was surprised that the first time he got an agent to prototype an OS, it built all the tests into flakes.</p>\n<p>Nix the language sucks. Nixpkgs is great. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://nixos.org/manual/nixos/stable/?ref=ghuntley.com#sec-nixos-tests\">NixOS machine tests</a> are the bee's knees: you write a test that spins up a fleet of machines and exercises the interaction between your network rules and your application. It's the thing people don't know about.</p>\n<p>And when something upstream is broken, or there's a supply chain problem in your dependencies, that's just an overlay.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/nix/\">the world hasn't figured out yet that you can literally just fix everything with a Nix overlay</a></p>\n<p>Patch the world.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<blockquote>\n<p>If you have to tool-call a human, also known as &quot;Dear Maintainer&quot;, who might be on holiday or might have abandoned the project, and wait a day, two days, or even five minutes, that's not AGI.</p>\n</blockquote>\n<p>We're building recursive products here. Agents need the ability to modify the world as first-party source, not as third-party bundled binaries. We're going back to the contrib folder and Unix patches.</p>\n<h2>if you care about security, you have two choices</h2>\n<p>Justin asked what unikernels still need for people to discover them. Honestly, it's this. We've raised two generations of developers who don't even know they're a thing.</p>\n<p>If you deeply care about security, there are really two choices:</p>\n<ol>\n<li>You're sending satellites into space, and you should probably use <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://sel4.systems/?ref=ghuntley.com\">seL4</a>, a formally verified operating system. (I'm still a bit salty about the Australian government disbanding that team.)</li>\n<li>Everyone else should seriously consider unikernels. Stop trying to harden something that is very hackable. Invert it and design from the other direction.</li>\n</ol>\n<p>The other classic criticism is that many early unikernel designs ran everything at a single privilege level: your application in the same ring as the OS. In 2026, that's a prompt away from being fixed if you want ring separation. It's certainly more secure than praying to god your systemd cgroup configuration is right.</p>\n<p>Think about how much time enterprises spend patching the world every time something new drops in Linux. Upstream now expects you to patch your kernel weekly. The week we recorded, someone popped KVM (essentially Firecracker, the core primitive we all thought was good sandboxing) and collected $50,000 from Vercel and a few other vendors. That is not much money for something that could root every managed cloud provider in the world.</p>\n<h2>spaceleans: a distributed unikernel operating system</h2>\n<p>About seven months ago, I went deep on unikernels to check whether my mental model was right. I showed Justin my Mirage folder, which holds all the functionality I needed to add.</p>\n<ul>\n<li>There was no way for a unikernel fleet to keep time, so I took an NTP client from another language and ported it. Then I built an NTP server based on RADclock and borrowed ideas from <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://tigerbeetle.com/blog/2021-08-30-three-clocks-are-better-than-one/?ref=ghuntley.com\">how TigerBeetle handles time</a>: not one clock source but many, packaged as a library.</li>\n<li>Network stack, DNS, HTTP clients and servers, structured logging, OTel, Anthropic and OpenAI clients, and payments via Airwallex.</li>\n<li>A generic retry library for handling back pressure over HTTP, plus some PPX metaprogramming for fun.</li>\n<li>A PII wrapper at the logging boundary, so secrets and PII never leak through the logging subsystem. Every project should have one. It's pluggable; just use a functor.</li>\n</ul>\n<p>And then the most cooked thing, which I'd never shown anyone before: <strong>Spaceleans</strong>, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://learn.microsoft.com/en-us/dotnet/orleans/overview?ref=ghuntley.com\">Microsoft Orleans</a> ported to OCaml, running as a unikernel.</p>\n<p>Orleans is a distributed actor system with transactions. You take many physical machines and merge them into one addressable heap. An actor always exists: <code>await GetCustomer()</code>, and if it isn't in memory, it gets rehydrated from a pluggable storage provider. You collapse your n-tier architecture into actors and stop caring whether something lives on machine A, B, C or D. The runtime handles it as an infrastructure primitive.</p>\n<p>So in a weird sense, I built a distributed unikernel operating system out of actors, with a filesystem on top. Justin called it Erlang-esque, and he's right. I did all of it in a week. I'll probably never release it, but it falsified the idea that unikernels are hard.</p>\n<h2>sampling history</h2>\n<p>Being a little older means you can sample history, like an experienced DJ such as Carl Cox, who's been in the scene long enough to pull from previous repertoire and bring it forward. All of these ideas existed in the eighties. The models have read the papers. They've got TAPL and the most advanced type theory in their training data.</p>\n<blockquote>\n<p>The thing that's lacking is people's curiosity and ambition to do these unhinged things, and the knowledge that previous records exist that can be sampled from.</p>\n</blockquote>\n<p>How do we get people to try this stuff? We just do it. If you've got a turbo Lamborghini alien space rocket that's more efficient and more secure, good for you; you've got a leg up. Do cool things, attract curious newcomers, mentor them, grow. Same as it's always been.</p>\n<p>Meanwhile, everyone else will be trying to Chainguard their Ruby on Rails application and managing AWS with fifty AWS-certified engineers, when two people with Nix and Hetzner would do. Eventually, it comes down to money. Higher-powered tools are more efficient, and efficiency wins, especially as AI collapses margins.</p>\n<h2>ocaml, rust, haskell and back pressure</h2>\n<p>Has OCaml's time come again? It's still going strong. A certain trading firm is using it very well. When I caught up with Yaron at the start of the year, I asked him whether <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://oxcaml.org/?ref=ghuntley.com\">OxCaml</a> exists so their language extensions end up in the training data and lift the whole company. I got a very &quot;no comment&quot; smile.</p>\n<p>For agents, OCaml is lovely. Functors between modules are beautiful. The <code>.mli</code> files, a typed header explaining how a module should work, are really efficient context for agents. opam and Dune are legitimately good. Hindley–Milner. And compile times are fast. I see no reason to do F# these days.</p>\n<p>Justin has mostly been writing Rust, and agents are good at Rust. But compile time is the tax on <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/pressure/\">back pressure</a>. LLMs hallucinate, and when compilation is slow, each hallucination is expensive because you get fewer attempts per minute. Justin's S3 clone is about a million lines of Rust; with four agents compiling at once, they fight over disk and CPU. You end up spending more on fast machines than on tokens.</p>\n<p>Haskell's type system is great, and the models do it really well. But I don't feel good running it in production: a space leak lives in the runtime state space and only shows up in production. Justin pointed out that the linear-type ideas in Rust came out of Haskell papers trying to solve exactly that. Then there's Zig's approach: allocate everything up front and never allocate again, which is what game devs did in the eighties and nineties. It's hard to persuade an agent to do that in Rust, though, because constant-memory programs aren't in its training set.</p>\n<p>I think dependent types are the winner for next-generation languages. Anything that lets you codify more into the type system is more back pressure. You probably won't be surprised to hear I've got a fork of the Rust toolchain with dependent types. You can just do things now.</p>\n<h2>languages for agents, and what cursed taught me</h2>\n<p>The pace of language development has been held back by how fast humans can learn new concepts. Operator chaining is essentially sugar for humans. If agents write the code, we can lean on forty years of academic PLT research, as long as you know how to sample it.</p>\n<p>The industry codified &quot;do not make breaking changes&quot; after Python 2 to 3. Justin knew companies with hundreds of people on that migration for years. I think that rule is no longer true. Ship a skill pack with the breaking change and let agents auto-migrate.</p>\n<p>Justin asked what it actually costs to make a new language successful now. Go was the last language a company spent real money on, and it took a long time. I can answer that one.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/cursed/\">i ran Claude in a loop for three months, and it created a genz programming language called cursed</a></p>\n<p>It's the only compiled language that lets you code with sus, slay and vibes.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Cursed was built with Sonnet 3.5 and 3.7, a deliberately underspecified prompt, and three months of running it in a loop. I started in C (not enough back pressure; I wasted too much time in Valgrind as the agent clobbered its own updates), then Rust, then Zig. Zig was a mistake; it would work today if I'd stayed with Rust. It cost roughly US$6,000, and I did it three times over. Compare that to what Go cost.</p>\n<p>Now the real bit, the part that still scares me. If you allocate the context window correctly — a lookup table of the lexical structure and grammar — the model can program in a language that isn't in its weights. It's brute force and inefficient, but it works.</p>\n<p>Think T-diagrams (tombstone diagrams). Lock down your grammar and lexical structure, reach a stage-two self-hosting compiler, ship a sensible standard library, and start the next training run. From there, you can reach a Roslyn-style self-hosted compiler with language services stupidly fast. Justin asked whether fine-tuning an open model would help bootstrap a language like this. It's not needed.</p>\n<p>That was true a year and a half ago with much weaker models. It'll take just one programming language designer going all in with the good models to shock the world.</p>\n<h2>what next</h2>\n<p>As the pub was shutting, Justin asked what was on my mind. If you haven't read my latest post, go read it. If you manage people, create the space and time for them to experiment now, because within six months, leadership will ask you to put people on a vitality curve.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/replaced/\">if your team is too busy doing their 'normal job' to experiment with AI, you're preparing them to be replaced</a></p>\n<p>AI use is now mandatory for employability.</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p>Yes, the labs trained on the commons. I hate that, and I get it. But you trade time and skill for money; employers have minimum standards, and those standards have changed faster than ever before in our industry. Be curious, learn how to build an agent, and go create beautiful stuff. We're in a renaissance.</p>\n<p>It's a time-compression device. The more experience you have, the more you can sample. Not everything ships; some of what I showed Justin may never see the light of day. I use these projects as katas and redo them when the models get better.</p>\n<p>But if you want to build something secure, seriously consider unikernels.</p>\n<h2>chapters</h2>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=21s&amp;ref=ghuntley.com\">0:21</a> — discovering unikernels: Haskell to OCaml to Mirage</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=55s&amp;ref=ghuntley.com\">0:55</a> — what a unikernel is, and why it was hard</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=165s&amp;ref=ghuntley.com\">2:45</a> — hard was past tense</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=213s&amp;ref=ghuntley.com\">3:33</a> — why do we have an operating system?</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=257s&amp;ref=ghuntley.com\">4:17</a> — the shell is a butler service for exfiltration</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=312s&amp;ref=ghuntley.com\">5:12</a> — attack surface reduction is fuzzy</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=446s&amp;ref=ghuntley.com\">7:26</a> — don't put the compiler on production</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=553s&amp;ref=ghuntley.com\">9:13</a> — porting Stripe into a unikernel</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=594s&amp;ref=ghuntley.com\">9:54</a> — minimal Linux and mkfs.xfs in Rust</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=742s&amp;ref=ghuntley.com\">12:22</a> — S3 for everything</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=828s&amp;ref=ghuntley.com\">13:48</a> — Nix, machine tests and overlays</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=928s&amp;ref=ghuntley.com\">15:28</a> — tool-calling a human is not AGI</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=953s&amp;ref=ghuntley.com\">15:53</a> — seL4 or unikernels</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1016s&amp;ref=ghuntley.com\">16:56</a> — privilege rings</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1104s&amp;ref=ghuntley.com\">18:24</a> — weekly kernel patches and the KVM escape</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1178s&amp;ref=ghuntley.com\">19:38</a> — demo: the Mirage folder, NTP and time</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1325s&amp;ref=ghuntley.com\">22:05</a> — Spaceleans: Orleans in OCaml as a unikernel</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1531s&amp;ref=ghuntley.com\">25:31</a> — sampling history</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1612s&amp;ref=ghuntley.com\">26:52</a> — how to get people to try this: just do it</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1737s&amp;ref=ghuntley.com\">28:57</a> — OCaml and OxCaml</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1905s&amp;ref=ghuntley.com\">31:45</a> — Rust compile times and back pressure</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=1986s&amp;ref=ghuntley.com\">33:06</a> — Haskell, space leaks and dependent types</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=2113s&amp;ref=ghuntley.com\">35:13</a> — memory strategies: Rust, Zig and game devs</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=2170s&amp;ref=ghuntley.com\">36:10</a> — languages designed for agents</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=2261s&amp;ref=ghuntley.com\">37:41</a> — breaking changes and skill packs</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=2333s&amp;ref=ghuntley.com\">38:53</a> — Cursed</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=2556s&amp;ref=ghuntley.com\">42:36</a> — what Cursed taught me</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=DOjHBwdfBpA&amp;t=2807s&amp;ref=ghuntley.com\">46:47</a> — what's next: AI use is mandatory</li>\n</ul>\n<p>Keep curious.</p>\n",
      "date_modified": "2026-10-10T14:23:33+00:00",
      "date_published": "2026-10-10T14:23:33+00:00",
      "external_url": "https://ghuntley.com/unikernels/",
      "id": "urn:aggr:item:540ad55c9157ad2080ee591a9e3a7fdb2f5a6700",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Symbolic-traditional-tattoo-art-print-portraying-a-unikernel-operating-system-as-a-lively-streamlined-digital-core-with-complex-ornamental-circuitry--bright-vibrant-retro-colors--intense-dramatic-lighting--energetic-glowing-accents--sharp-h.jpg",
      "summary": "Justin Cormack, who worked on MirageOS back in the day, called me at the pub to talk about why unikernels are coming back. The friction that made them hard is gone, the operating system is design debt, and if you care about security you…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "unikernels were hard. key word: were.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-10-unikernels-were-hard-key-word-were/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>When <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ralph\">Ralph</a> was published last year, I sat on it. People who have been reading this blog for a while know this. I first came across the idea of loop engineering in early January last year, sat on it for four months, and then started writing a lot, begging people to pay attention.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/screwed\">Dear Student: Yes, AI is here, you’re screwed unless you take action...</a></p>\n<p>Two weeks ago a student anonymously emailed me asking for advice. This is the reply and if I was in your shoes this is what I’d do. So, I read your blog post “An oh f*** moment in time” alongside “The future belongs to idea guys that can just</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--6a9e2292-263d-4bdd-af80-1f0b26097d6a.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/llmcurve-ee4a23b3-f928-44d0-bbf9-c10eaf5d3449.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>When Ralph and Loop Engineering went viral earlier this year, almost a year later, it really weighed heavily on me. Life's been pretty good lately, but it <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/how-long/\">wasn't always historically</a>, so I took some time off. I spent six months traveling around the world with no income, and I delivered the talk below almost 17 times in various cities.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/eighteen-month-recap/\">the eighteen-month recap: AI Engineer, Singapore, May 2026</a></p>\n<p>This is the eighteen-month recap: the talk I gave on day two of AI Engineer Singapore. A lot has happened since the six-month recap in Melbourne. The recording is below, followed by an edited transcript with the slides. Welcome back. For those who were at the party here</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--e8c0ca10-d3ff-4e4f-a738-dda36f163dea.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/Symbolic-traditional-tattoo-art-print-on-white-with-a-small-software-engineer-in-intricately-patterned-overalls--a-vivid-rose-tattoo--and-an-In-N-Out-burger-hat-at-a-Singapore-conference.-Divide-the-composition-into-bold-ornamental-sections-3a22b7b9-c84c-4621-b319-1d7e9216d76e.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Our profession is at a crossroads, and this is the last time I'll say it.</p>\n<blockquote>\n<p>Usage of AI in the profession of software engineeering is no longer optional.</p>\n</blockquote>\n<p>If your employer has banned the use of AI, you should quit and find a company that is already going through an AI transformation.</p>\n<p>If you're at a company going through an AI transformation, I understand you'll have mixed feelings about this. You might not like it. But please understand that this is the new normal. Artisanal handwritten code is only possible for retired tech executives and as a hobby at home, but it's no longer a way to make money.</p>\n<p>You really have two choices as an employee.</p>\n<p>You can push against the grain and refuse to use AI, but that's just self-harm. You trade time and skill for money. The tastes and desires in the employment market have moved on.</p>\n<p>From my position, I have a clear view of what's going on.</p>\n<p>Every morning, I wake up to either a WhatsApp message or a LinkedIn DM from people who are going somewhere, sending their thanks. Like, don't thank me; thank yourself. You invested in yourself, and because you did, you just got promoted to a vice president role. You did all the work.</p>\n<blockquote>\n<p>Hi Geoffrey. I wanted to drop you a message to just share what a profound impact Ralph’ing had had on me and the company i work for. I first heard of it back in Jan 2026 on social media and thought it was an outrageous concept, the idea of letting this clumsy persona rip through my codebase, so i just ignored it. My biggest frustration with AI has always been it never bought exactly what I wanted to life, it would get the first parts right, then it starts cutting corners, and I end up with a real mess at the end. That was until when I watched sonnet 5 loop through and churn out a product in about 6 hours, so for whatever reason I decided to come to your blog and read about Ralph directly - and I’d totally misundertood it. It took quite a bit of experimenting, however im now at a place where <strong>I’m literally delivering paid for dev worth 100K + for 3K in sonnet tokens in brownfield projects. Im re-platforming entire stacks in about 2 weeks that we used to pay contractors half a million for - the game has totally changed, and the inplications are both amazing and terrifying at the same time</strong>. Anyway, just wanted to say thank you, because at least for me and the company I work for, you publishing the Ralph paper has forever changed the game, and I hope that one day I’ll get to buy you a drink to say thank you. All the best.</p>\n</blockquote>\n<p>So it's time to address the elephant in the room: people managers.</p>\n<p>If your team is too busy doing their new job to experiment with AI, you're preparing them to be replaced. Maybe you're okay with this, but hopefully you're not, because it should weigh heavily on you if you truly care about your team.</p>\n<p>Sometime in the next six months, you're going to have to start having some hard conversations about moving people on from your company. You should already be putting your employees on a vitality curve and ranking them. Naturally, competent employees who have been using AI will be ahead of competent engineers who haven't.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ngmi\">What do I mean by some software devs are “ngmi”?</a></p>\n<p>At “an oh fuck moment in time”, I closed off the post with the following quote. N period on from now, software engineers who haven’t adopted or started exploring software assistants, are frankly not gonna make it. Engineering organizations right now are split between employees who have had that</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--628788a0-8fa2-4452-8a4f-c9aac184f5ac.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/fruits-13f613f1-b3f8-4d30-a6b8-f38ed571e814.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>At this stage, some software developers are not going to make it, and that's okay. You can't lead a horse to water and make them drink. It's their choice. You need to put yourself as a manager first and role model the new performance baseline.</p>\n<p>If you don't want this to happen to your team's members, start by carving out time for professional development. The most concrete task I can recommend is for software developers to build their own agent, learn the magic tricks behind Claude Code, and explain how it works under the hood.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/agent\">how to build a coding agent: free workshop</a></p>\n<p>It’s not that hard to build a coding agent. 300 lines of code running in a loop with LLM tokens. You just keep throwing tokens at the loop, and then you’ve got yourself an agent.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--fde432a0-af02-4391-b622-91b59ee06ff4.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/how-to-build-an-agent.001-a3045254-49e6-40a7-9736-1a0a79ccff76.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>start here</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=Jr2auYrBDA4\">fundamental skills and knowledge you must have in 2026 for SWE</a></p>\n<p>in video form</p>\n<p>You see, you're not a senior software engineer in 2026 unless you can rebuild Claude Code (the most basic of agents). Senior software engineers are senior by definition because they can mentor and teach the incoming generation. There's a lot to teach about the craft of software engineering; there's a lot of information and experience about software failures and how software should be designed, colloquially known as taste, that the incoming generation will need to be mentored in, but you won't earn their respect if you have an attitude that AI is evil and should be avoided. If you can't earn the respect of the incoming generation because of your poor attitude, what value do you bring, and why should an employer keep you employed?</p>\n<blockquote>\n<p>I've never seen this before in my career: 28-30 year olds who refuse to use AI coding tools.</p>\n<p>You show them what they can do augmented (not replaced) with AI and you see in their eyes that they have no damn clue of what's happening.</p>\n<p>You can't work with these people anymore. Time…</p>\n<p>— Ivan Burazin (@ivanburazin) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/ivanburazin/status/2029693439055474720?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">March 5, 2026</a></p>\n</blockquote>\n<blockquote>\n<p>You know how ants leave the colony before they die?</p>\n<p>Developers make posts like this before AI makes them unemployed. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/7JhSdn8WaQ?ref=ghuntley.com\">https://t.co/7JhSdn8WaQ</a></p>\n<p>— Theo - t3.gg (@theo) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/theo/status/2108059614831059020?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 8, 2026</a></p>\n</blockquote>\n<h2>interviewing as an employee in 2026</h2>\n<p>If you're interviewing as an employee in 2026, understand that there is a narrative that it's hard to get a job and it's pretty tough out there. This is true if your expertise is limited to typing code into an IDE, but it is not if you have provable expertise in AI.</p>\n<p>If you've got something to show, like a talk, an open-source project, or anything tangibly demonstrable that you've been curious about the transformation in our industry and have been investing in yourself, you should be able to land a job in a couple of days in this market, as it's cooking right now.</p>\n<p>Please understand that your edge right now is understanding the possibilities and being curious. The world lacks curious, ambitious people. That's your edge; that's your alpha. Position yourself as that, and be way more ambitious than you are right now. You need to think bigger.</p>\n<p>At whichever company you end up at, be an ambassador for AI across your team and organization (and by that I don't mean you should be a maximal AI glazer). I mean, share what works, experiment, and help others through this transition. Generally, just raise the bar for everyone around you and be a good human.</p>\n<h2>being a hiring manager in 2026</h2>\n<p>It's been almost two years since my <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/oh-fuck/\">oh-fuck moment</a>. Since then, we've seen the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/papercuts/\">rise of &quot;model-first&quot; companies</a> where most of the software is generated by computers, not humans.</p>\n<p>This means that two years have passed, and those who have been curious and invested in themselves have one hell of an edge over someone just getting started today.</p>\n<blockquote>\n<p>One of the most fundamental questions I’ve been pondering on over this last year is “how do you identify skilled operators” aka “how do we even hire software engineers now now that LLMs can smash leetcode?”</p>\n</blockquote>\n<p>I propose the following categories and buckets as a crude ruler on top of your standard software engineering knowledge tests.</p>\n<ul>\n<li><strong>unacceptable</strong>\n<ul>\n<li>A poor attitude toward willingness to use AI. I get it. The labs ripped off society's commons, and I don't like it either, but it has happened. You should sniff out these perspectives when interviewing a candidate and filter candidates out through behavioral questions.</li>\n<li>Any form of deceptive behavior. If they're using AI in the interview process to deceive, that's an instant no-hire because deceptive behavior is unacceptable.</li>\n<li>No tangible, demonstrable experience with AI.</li>\n</ul>\n</li>\n<li><strong>acceptable</strong>\n<ul>\n<li>You should be able to pull them over to a whiteboard and ask, at a high level, how a coding agent works under the hood. This is a baseline curiosity test to see whether they've been paying attention and developing their skills over the last couple of years. You want to understand whether they know what a context window is, how tokenization works, and how inference works from a systems-design perspective. If their knowledge depth taps out and all they can do is talk about skill packs, then pass on the candidate. Employers should prioritize producers, and producers know the baseline underlying data structures and system design of how an agent works because that knowledge lets them automate a business function. If they don't have this knowledge, they're just a consumer, so you should likely pass on them until you find someone with producer knowledge.</li>\n</ul>\n</li>\n<li><strong>ideal</strong>\n<ul>\n<li>Tangible and demonstrable experience with AI. They should have a whole bunch of side projects they have built; this may seem unfair, and I agree. Before AI, this was an unfair standard, but these subscriptions have been available to everyone. They're subsidized, and everyone I know who understands what's going on has so many cool things they're dying to show people.</li>\n<li>When you ask the question about what coding harness they use, like, there are only really two acceptable answers. One is that all coding harnesses are fungible, and they use whatever they can to get tokens the cheapest, or their eyes light up and go, I use my own. Do you want to see it? Do you want to nerd about it? Like, here, I'll show you. <em>This is the modern age of the age-old interview question: &quot;Tell me about your home lab&quot;</em></li>\n<li>If you walk away from the interview and learn something about AI you didn't know, you should hire that person on the spot before someone else does. <em>This is the modern age of the age-old interview question, &quot;</em> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/alex/what-happens-when?ref=ghuntley.com\"><em>What happens when you type google.com into your browser's address box and press enter?</em></a><em>&quot; but with an AI twist.</em></li>\n<li>If they lead people, they should be able to go really, really deep on the processes that failed because of a company's AI adoption. They should also cite examples of <em>what they personally changed within their organization to enable AI adoption</em>. You should background-check these stories to ensure people aren't telling porkies.</li>\n</ul>\n</li>\n</ul>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/10/CleanShot-2026-10-10-at-1.22.25-AM@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>Do not hire left of the line. Start vitality curving existing employees into either AI producers or consumers. Left of the line is NGMI, and that's fine. If they decide to self-harm, then that's their choice. As a people manager, you also need to put yourself first because you are competing against other people managers in your organization on the measurement of your reports' AI fluency. This may seem cruel — not to support someone who is having a crisis — but it's been two years; it's a crisis state, and you never know how someone may respond in a crisis; they may start sabotaging. Subsidized subscriptions are available relatively cheaply for personal use. There's truly no reason someone should be left off the line now that we're getting close to the end of the year. All the tools have been available to everyone. It's just a matter of whether someone's been curious enough and whether they've taken action. I mean, you can move someone on. There are two years of candidates who have been applying themselves and will happily take the role of someone who hasn't been curious. Ultimately, as a people leader, you also need to think about putting yourself and your family unit first.</figcaption></figure>\n<p>There's something else that I need to put forward. Your existing hiring pools may need to be wiped because your current interviewers may lack the expertise to differentiate between these categories. For example, if someone has a poor attitude toward AI and no provable experience with AI, and they're not in the ideal category, remove them from your interviewer pool (and/or company), because you need to put your best foot forward to identify, attract, and hire the best talent out there in 2026.</p>\n<blockquote>\n<p>Remember, the candidate is also interviewing you. They know what's going on, and they want to ensure that choosing you as an employer de-risks their lives.</p>\n</blockquote>\n<h2>ps. Watch this podcast with Bill Gates and internalize it</h2>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.nytimes.com/2026/09/29/opinion/ezra-klein-podcast-bill-gates.html?ref=ghuntley.com\">https://www.nytimes.com/2026/09/29/opinion/ezra-klein-podcast-bill-gates.html</a></p>\n<blockquote>\n<p>Well, Jevons is just a referral to the fact that parts of the economy are subject to demand elasticity. And yes, in the case of software, if you’re, say, three times as fast and there is still some role that only humans can perform, then as you lower the cost, you induce demand. So it’s fair to say that the equilibrium today so far for software is not a loss of employment.</p>\n<p>When we invented radial tires that lasted four times as long, for some weird reason, people didn’t drive four times as much. And factories that make tires employ a quarter of as many people. When you replace people in Amazon warehouses with robots, people don’t buy more because of that.</p>\n<p>So anybody who’s numeric can say to themselves: What portion of the economy is subject to demand elasticity, and what are those tasks that will still be human-necessary?</p>\n<p>As soon as you’ve completed the entire task, it doesn’t matter that there’s demand elasticity. That goes into the token budget. It doesn’t go into the human salary budget.</p>\n<p><strong>The cost for some of these things is so much less than the cost of the human labor, and so as you cross reliability thresholds, both with white-collar and humanoid robots, you destroy jobs and you leave no high ground.</strong></p>\n<p>Innovation in the past — you have a tractor. Fine. Let’s build Disneyland and employ a lot of people there. You don’t have that in the broad economy. The people who say there will be net additional jobs, I don’t understand what they’re thinking.</p>\n</blockquote>\n<blockquote>\n<p>AI is no longer optional. Every leader we interviewed said, one way or another, that refusing to use AI is now disqualifying; the comparison we heard more than once was refusing to use an IDE. The gains are real. Organisations told us about three times the output per engineer, a six-month project delivered in two, an incident diagnosed in seven minutes that would once have taken four hours. What changes most is what's possible. The default answer to a new idea is no longer &quot;no&quot;, it's &quot;let me check&quot;, and work that used to die at the bottom of the backlog now gets done.</p>\n</blockquote>\n<p>From <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.lookahead.com.au/reports/ai-engineering-2026/lookahead-state-of-ai-engineering-2026.pdf?ref=ghuntley.com\">https://www.lookahead.com.au/reports/ai-engineering-2026/lookahead-state-of-ai-engineering-2026.pdf</a></p>\n<p>Can you please boost and share this blog post with someone you think needs to hear it? It is both the most and the least we can do. We can't force a horse to drink, but we can tell horses that water exists, and that they need water to be employed in 2026...</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2108484955437416543?ref=ghuntley.com\">Twitter</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.linkedin.com/posts/geoffreyhuntley_if-your-team-is-too-busy-doing-their-share-7514251066280984576-QY7_/?ref=ghuntley.com\">LinkedIn</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://bsky.app/profile/ghuntley.com/post/3mxgmwca2ek27?ref=ghuntley.com\">BlueSky</a></li>\n</ul>\n",
      "date_modified": "2026-10-09T09:07:26+00:00",
      "date_published": "2026-10-09T09:07:26+00:00",
      "external_url": "https://ghuntley.com/replaced/",
      "id": "urn:aggr:item:2b862d800174d000a28ed550ff60fcc85089df46",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/download--2-.jpeg",
      "summary": "When Ralph was published last year, I sat on it. People who have been reading this blog for a while know this. I first came across the idea of loop engineering in early January last year, sat on it for four months, and then started writing…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "if your team is too busy doing their 'normal job' to experiment with AI, you're preparing them to be replaced",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-09-if-your-team-is-too-busy-doing-their-normal-job-to/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>Here's something I've been meaning to write up for a while. It's kind of late, but I'm going to lean into the whole MCP vs. CLI argument because I have a perspective others might find interesting.</p>\n<blockquote>\n<p>What's the actual difference between an MCP server and a regular old CLI program with a `--help` flag? Feels to me like a CLI program written with agents in mind solves the same problems without inventing anything new?<br />\n<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/adamwathan/status/1968738637358522629?ref=ghuntley.com\">https://x.com/adamwathan/status/1968738637358522629</a></p>\n</blockquote>\n<p>Developer tooling companies can be sorted into two tiers: S-tier (winning) and F-tier (losing). The Rubik for wherever a company falls into the S tier or F tier has got everything to do with the model weights.</p>\n<p>An S-tier company is in the training weights. Let's take GitHub, for example. Now, we can yak about problems with GitHub till the cow comes home, but one thing is true: these models know how to interface with GitHub because that behavior is in the model weights themselves. They don't need any skills or an MCP to get outcomes. You can just use the CLI.</p>\n<p>You are S-tier once you can do a prompt like this without any skills or MCP:</p>\n<blockquote>\n<p>prompt: Use the GH cli to create a repository, commit the changes, push to origin, set the reposistory to public and update the repository description.</p>\n</blockquote>\n<p>Now, if you're a brand new developer tooling company and you're not in the model weights yet, you've got a couple of choices. First, you'll have to ask users to download and install some sort of skill pack, or maybe even a CLI, which adds a lot of friction for users compared with the DevX of an S-tier company.</p>\n<p>So, what do you do? It's simple.</p>\n<p>Start by developing a really good CLI, and on that CLI, work on and optimize your <code>--help</code> section. What you want to do is measure whether a model can achieve outcomes by walking the help verb across all the subverbs, then optimize the language used by choosing whatever works best, so the model can achieve the outcomes with the fewest tool calls. This can be automated through a loop or an auto-research loop.</p>\n<p>Once you have this bare-bones foundation, the next step is to publish documentation for this CLI online and then focus on ASEO (Agentic Search Engine Optimization) for agents <code>web_search_tool</code>. Again, from this point forward, the goal is to look at the journey a single agent takes and optimize it so the agent can get all the information it needs in a single web search tool. If it has to walk through your documentation, you're not doing a good enough job. Keep optimizing.</p>\n<p>To take this to the next level, you should enter into a business contract with the labs. Perhaps you've already got a contract with the labs for inferencing. You want to lean on them to include your CLI documentation in their next training run.</p>\n<p>If you nail these things, then you're well on the path to becoming an S-tier developer tooling company. The best part is that it doesn't require users to download or install a skill pack, configure an MCP, or deal with any of that junk.</p>\n<p>ps. socials</p>\n<blockquote>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2108454712035209559?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 9, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-09T07:07:33+00:00",
      "date_published": "2026-10-09T07:07:33+00:00",
      "external_url": "https://ghuntley.com/tier/",
      "id": "urn:aggr:item:a605087237d2dc4f5f9f266dbe8bbbf8a095f5e0",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Symbolic-traditional-tattoo-art-print-depicting-contrasting-S-tier-and-F-tier-developer-tools-as-elegant-ornamental-emblems--polished-interfaces-and-refined-craftsmanship--vibrant-retro-colors--intricate-decorative-linework--adorable-yet-gr.jpg",
      "summary": "Here's something I've been meaning to write up for a while. It's kind of late, but I'm going to lean into the whole MCP vs. CLI argument because I have a perspective others might find interesting. What's the actual difference",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "--help on your CLI is all you need for LLM context until you don't.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-09-help-on-your-cli-is-all-you-need-for-llm-context-until-you/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>I don't know if you've noticed yet, but JetBrains <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.helgilibrary.com/companies/jetbrains?ref=ghuntley.com\">reported a net loss</a> for the first time in its recorded history.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Screenshot-2026-10-07-at-3.35.01---PM.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.helgilibrary.com/companies/jetbrains?ref=ghuntley.com\">https://www.helgilibrary.com/companies/jetbrains</a></figcaption></figure>\n<p>Before we go into this, let's rewind time to January 2025, nearly a year and a half ago, when I penned these words.</p>\n<blockquote>\n<p>So, I've been wondering what the next generation of IDE looks like in this post-LLM world. Why do I need to have multiple IDEs open? What if we ripped out the &quot;collaborate with humans&quot; functionality from Zed and inverted it so it's &quot;collaborate with LLMs,&quot; and an unbounded number of LLMs could be connected to the IDE. Even then, that might not be radical enough of a UX/design overhaul. Maybe we don't even need an IDE? Maybe Devin is onto something...</p>\n</blockquote>\n<p>I remember writing these words as a tech lead at Canva, with coworkers calling me mad and saying, &quot;Geoff, what do you mean?&quot; I love JetBrains. I love my IDE. There's no way in heck this is changing; JetBrains will figure it out.&quot;</p>\n<p>I'm not salty about it; it's just a fact. You get used to these things when you're early. If you're curious, you get used to the friction from people who aren't used to early, informed insights. To me, it was plain and clear that IDEs were dead and we needed better tools.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/multi-boxing/\">Multi Boxing LLMs</a></p>\n<p>Been doing heaps of thinking about how software is made after <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/oh-fuck\">https://ghuntley.com/oh-fuck</a> and the current design/UX approach by vendors of software assistants. IDEs, since 1983, have been designed around an experience of a single plane of glass. Restricted by what an engineer can see on</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--e59bd958-567e-406a-be98-9cb6571e4768.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/CleanShot-2025-01-28-at-12.41.09@2x-5e7f9669-ac43-40f7-8cce-3ba59927e353.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>When I wrote the above, I was in the background enumerating JetBrains at all levels through our customer channels about what their roadmap would be, how they would counter this risk in business, and it's ultimately really sad to see that nothing was done other than jack the price of their subscriptions whilst simultaneously delivering a low-quality product (ala &quot;private equity/broadcom subscription revenue extraction phase&quot;)</p>\n<blockquote>\n<p>They essentially Kodaked themselves.</p>\n</blockquote>\n<p>JetBrains could only see the world through the lens of the IDE, and they hoped that AST exposed by a language server would be a source of alpha even though everyone else in the agentic coding market was getting ripping results without symbolic context injection. Their experience and domain expertise became their curse, keeping them from changing and adapting to the market.</p>\n<p>And that is the deepest lesson. From this point forward, I'm not going to mention JetBrains, but I'm going to focus on the lesson. Every company is blinded by its domain expertise and how it makes revenue, and in times like this with AI, it's important to stay highly neuroplastic and check your blind spots.</p>\n<p>A good example of this is the labs. The labs deeply believe that a future version of their model will solve software verification because tokens shape their worldview and perspective. This belief blinds them to the fact that a better model will not solve the problem of verifying that an application will behave <em>correctly</em> in production under suboptimal conditions (i.e., flaky network connections)</p>\n<p>My strongest advice to all business leaders right now is to look at your own dogma, how you view the world, and make sure you don't Kodak yourself in this super weird moment of hyper transformation.</p>\n<p>ps. socials</p>\n<blockquote>\n<p>🗞️ <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/dgoRPZykGC?ref=ghuntley.com\">https://t.co/dgoRPZykGC</a></p>\n<p>&gt; I remember writing these words when I was a tech lead at Canva, and coworkers were calling me mad, going, &quot;Geoff, what do you mean?&quot; I love JetBrains. I love my IDE. There's no way in heck this is changing; JetBrains will figure it out.&quot; <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/ZeU2m17hhq?ref=ghuntley.com\">pic.twitter.com/ZeU2m17hhq</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2107922889685004318?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 7, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-07T19:52:24+00:00",
      "date_published": "2026-10-07T19:52:24+00:00",
      "external_url": "https://ghuntley.com/kodak/",
      "id": "urn:aggr:item:3342b00d0571f92bb7053fbcae25e342760d7c43",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Symbolic-traditional-tattoo-art-print-illustrating-Kodak-yourself-out-of-business--with-vibrant-reds--oranges--and-yellows--complex-retro-ornamentation--bright-lens-flare--warm-dreamy-haze--soft-illumination--glowing-light-streaks--detailed-2.jpg",
      "summary": "I don't know if you've noticed yet, but JetBrains reported a net loss for the first time in its recorded history. https://www.helgilibrary.com/companies/jetbrains Before we go into this, let's rewind time to January 2025, nearly a year and…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "to Kodak yourself out of business",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-07-to-kodak-yourself-out-of-business/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>There are many things that are uncertain in our industry right now, but one thing I am certain about, and have been for almost 13 years, is that Nix is a <em>terrible</em> programming language.</p>\n<p>I remember when I first learned it, it felt like pushing shit uphill. The learning cliff is ferocious, and it took me a couple of years to master it because there was no AI back then, but I stuck with it. There's some magic here, and in this post, I'm going to show you why Nix should be your primary choice for all your software projects.</p>\n<blockquote>\n<p>First, I'm going to open with this: many pieces of technology are in our heads as really hard to learn, complex, and maybe that's stopped you from picking one up, but I want to encourage you to falsify those thoughts any time you start thinking along those lines. Now that we have AI, things that used to be advanced power tools, hard to use or designed for masters, are now accessible to everyone. You can just prompt for outcomes.</p>\n</blockquote>\n<h2>first, some introductory knowledge</h2>\n<p>The term Nix is overloaded. It means many different things; when someone says they use Nix, the first thing you should do is ask, &quot;How do you use Nix?&quot; and &quot;What is Nix to you?&quot; because there are many ways to use it; it's not just a package manager or a build system; it can also be an operating system.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://haskellforall.com/2022/08/stop-calling-everything-nix?ref=ghuntley.com\">Stop calling everything “Nix”</a></p>\n<p>Explanation of the Nix ecosystem’s abstraction layers</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-c80ee1f0-c390-4553-9ccd-192f04c56d2c.ico\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/opengraph-image-d6ac19c5-3b97-4628-a6a7-e24d7801d58e.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>an explanation of the Nix ecosystem abstraction layers.</p>\n<p>In this post, I'll focus on Nix's versatility and utility, and why it's so powerful in the age of AI. There's a reason the labs are using this to build the models you are consuming...</p>\n<h2>agent and developer experience</h2>\n<p>By using tools like <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://devenv.sh/?ref=ghuntley.com\">https://devenv.sh/</a>, you can define a single source of truth for your compilation toolchain and required third-party dependencies. Humans can use this single source of truth in CI/CD and in ephemeral sandbox development environments used by agents.</p>\n<pre><code><span class=\"code-snippet\" data-language=\"CSS\"><span class=\"syntax-source syntax-css\"><span class=\"syntax-meta syntax-selector syntax-css\"># visit https:</span>//<span class=\"syntax-meta syntax-selector syntax-css\">devenv<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>sh</span></span>/<span class=\"syntax-meta syntax-selector syntax-css\"><span class=\"syntax-entity syntax-name syntax-tag syntax-custom syntax-css\">getting-started</span></span>/<span class=\"syntax-meta syntax-selector syntax-css\"> for installation instructions\n\n$ vi devenv<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>nix</span>\n\n  # devenv<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>sh</span></span>/<span class=\"syntax-meta syntax-selector syntax-css\">packages</span>/\n<span class=\"syntax-meta syntax-selector syntax-css\">  packages = <span class=\"syntax-meta syntax-attribute-selector syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">[</span> <span class=\"syntax-entity syntax-other syntax-attribute-name syntax-css\">pkgs</span>.<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-css\">prek</span> <span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">]</span></span>;\n \n  # devenv<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>sh</span></span>/<span class=\"syntax-meta syntax-selector syntax-css\">languages</span>/\n<span class=\"syntax-meta syntax-selector syntax-css\">  languages = </span><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span>\n    <span class=\"syntax-meta syntax-property-name syntax-css\">rust</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">enable</span> = <span class=\"syntax-meta syntax-property-name syntax-css\">true</span>;\n</span>  <span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">}</span>;\n \n<span class=\"syntax-meta syntax-selector syntax-css\">  # devenv<span class=\"syntax-entity syntax-other syntax-attribute-name syntax-class syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-entity syntax-css\">.</span>sh</span></span>/<span class=\"syntax-meta syntax-selector syntax-css\">services</span>/\n<span class=\"syntax-meta syntax-selector syntax-css\">  services = </span><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span>\n    <span class=\"syntax-meta syntax-property-name syntax-css\">postgres</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">enable</span> = <span class=\"syntax-meta syntax-property-name syntax-css\">true</span>;\n</span>  <span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">}</span>;\n \n<span class=\"syntax-meta syntax-selector syntax-css\">  # Configure and install the Rust formatting Git hook.\n  <span class=\"syntax-entity syntax-name syntax-tag syntax-custom syntax-css\">git-hooks</span> = </span><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span>\n    <span class=\"syntax-meta syntax-property-name syntax-css\">hooks</span> = {\n      <span class=\"syntax-meta syntax-property-name syntax-css\">rustfmt</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">enable</span> = <span class=\"syntax-meta syntax-property-name syntax-css\">true</span>;\n</span>    <span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">}</span>;\n  };\n\n$<span class=\"syntax-meta syntax-selector syntax-css\"> devenv up\n</span></span></span></code></pre>\n<p>this one stanza provides rust, postgres and prek (for agent backpressure) and it just works across all operating systems</p>\n<p>I keep coming across clients with drift between how a local laptop is configured and how their CI/CD is configured. And now we've got ephemeral sandbox environments; they're heading down a path of triplicating that drift. This is utter madness. It is not needed. Stop it.</p>\n<p>You might be thinking, &quot;Well, there's mise for this.&quot; Trust me, mise isn't good enough. Mise is a low-power, low-IQ tool. It does one thing, and it does it well, but it doesn't enable your agents to truly fly.</p>\n<h2>not just a package manager</h2>\n<p>nix is super composable. That same expression that defines your human developer environment setup, your CI/CD setup, and your ephemeral sandbox setup can also be reused to build <em>performant</em> Docker images.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://grahamc.com/blog/nix-and-layered-docker-images/?ref=ghuntley.com\">Optimising Docker Layers for Better Caching with Nix - Graham Christensen</a></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://static.ghost.org/v5.0.0/images/link-icon.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Graham Christensen</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/docker-3fc6bfc5-cb0c-4de5-9989-773af79b9319.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<pre><code class=\"language-nix\"><span class=\"code-snippet\" data-language=\"Nix\">pkgs.dockerTools.buildLayeredImage {\n  name = &quot;git&quot;;\n  tag = &quot;latest&quot;;\n  contents = [\n    (pkgs.buildEnv {\n      name = &quot;image-root&quot;;\n      paths = [ pkgs.git pkgs.cacert ];\n      pathsToLink = [ &quot;/bin&quot; &quot;/etc&quot; ];\n    })\n  ];\n  config.Env = [\n    &quot;PATH=/bin&quot;\n    &quot;SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt&quot;\n  ];\n  config.Cmd = [ &quot;/bin/git&quot; &quot;--version&quot; ];\n};\n</span></code></pre>\n<p>This expression here creates your docker image with git in it. But there's no reason why this docker image can't be the binaries used to run your application in production. 🫡</p>\n<p>But perhaps... the real reason I love Nix is its power to compose an operating system. With a standard operating system such as Debian or Ubuntu, what happens if an agent is given <code>sudo</code> access to do things on your machine?</p>\n<p>You'd be pretty scared, right?</p>\n<p>What if I told you that when I'm doing agentic development, I develop on NixOS and I explicitly prompt my agents to use <code>sudo</code> as part of my loop engineering, and it is safe because NixOS is designed to make it nearly impossible to break a machine, and if it does, you can instantly roll back that change.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HQmrQHmAMzg\">Different Rollback Methods in NixOS</a></p>\n<h2>why the operating system matters</h2>\n<p>When others do loop engineering with their agents, they're likely running loops with building the application, perhaps Postgres, but rarely anything more. The primary difference between how others do loop engineering and how I do is that, when I run loops, I put the <em>entire system under test, and the entire System Under Test IS the operating system</em>.</p>\n<p>You might think, &quot;Whoa, what the —&quot; Like, how the hell do you do this?</p>\n<p>ah! My sweet summer child. It is really simple.</p>\n<p>NixOS has a testing framework (<code>runNixOSTest</code>), built in, and for anything you could ever want to assert about how an operating system is configured, or even across many machines, you can spin up a cluster. You can use a number of machines in a test, assert the network rules between them are correct, and that the right IP tables are forwarded or dropped. You do machines of machines, and you actually test the interoperability of that environment against your application.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/NixOS/nixpkgs/blob/master/nixos/doc/manual/development/writing-nixos-tests.section.md?ref=ghuntley.com\">nixpkgs/nixos/doc/manual/development/writing-nixos-tests.section.md at master · NixOS/nixpkgs</a></p>\n<p>Nix Packages collection &amp; NixOS. Contribute to NixOS/nixpkgs development by creating an account on GitHub.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-5cab0a30-53cd-48f3-b86b-c81a1ba35d28.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub NixOS</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/db161f80-7b49-11e9-9814-cf4d7cae408c-4c6ec481-4adc-4e11-a4d5-efe341ea2f33.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Here's an example of what this looks like when you've defined an operating system in NixOS and want to assert the network is configured correctly with your firewall zones, and that network activity works for your application before you deploy it.</p>\n<pre><code><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> NixOS VM test: HAProxy in front of a Python hello-world server.\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Topology (two QEMU nodes, separate L2 networks):\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>   vlan 1  192.168.1.0/24   frontend\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>     haproxy  eth1  192.168.1.1/24     HAProxy binds :80 here only\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>   vlan 2  192.168.2.0/24   backend\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>     haproxy  eth2  192.168.2.1/24     allowed source\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>              eth2  192.168.2.50/24    extra address, must be rejected\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>     web      eth2  192.168.2.2/24     Python hello-world on :8080\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> NixOS test IP scheme is 192.168.&lt;vlan&gt;.&lt;nodeNumber&gt;. nodeNumber comes from\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> the sorted node name, so haproxy = 1 and web = 2.\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> web firewall:\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>   - inbound: accept TCP 8080 only from 192.168.2.1, drop everything else\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>   - outbound: no new connections; established replies to HAProxy still pass\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Run:\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>   nix build .#checks.x86_64-linux.haproxy-hello\n</span><span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span>   nix run .#driverInteractive    # drop into the test driver\n</span><span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">lib</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-constant syntax-language syntax-python\">...</span> <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-annotation syntax-variable syntax-python\">:</span>\n<span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">let</span></span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontendVlan</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">backendVlan</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">2</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n\n  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Sorted node names: haproxy, web.\n</span>  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyNode</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webNode</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">2</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyFrontendIp</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">192.168.${toString frontendVlan}.${toString haproxyNode}<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyBackendIp</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">192.168.${toString backendVlan}.${toString haproxyNode}<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Same backend VLAN, but not the address the firewall allows.\n</span>  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyUntrustedIp</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">192.168.${toString backendVlan}.50<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webIp</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">192.168.${toString backendVlan}.${toString webNode}<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontendPort</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">80</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webPort</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">8080</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">helloBody</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">hello from python<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n<span class=\"syntax-keyword syntax-operator syntax-logical syntax-python\">in</span>\n<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">name</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">haproxy-hello<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>;\n\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">nodes</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pkgs</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-constant syntax-language syntax-python\">...</span> <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">virtualisation</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">vlans</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontendVlan</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">backendVlan</span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">virtualisation</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">memorySize</span></span> = <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">512</span>;\n\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">environment</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">systemPackages</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pkgs</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">curl</span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n\n      <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Harness already assigns 192.168.2.1/24. This alias is the negative\n</span>      <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> control: same L2 network, source the backend must refuse.\n</span>      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">networking</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">interfaces</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">eth</span></span>$<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">backendVlan</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">ipv4</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">addresses</span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span>\n        <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">address</span></span> = <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyUntrustedIp</span></span>;\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prefixLength</span></span> = <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">24</span>;\n        <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n      <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">networking</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">firewall</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">enable</span></span> = <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>;\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Frontend lives only on vlan 1. Do not publish :80 on the backend net.\n</span>        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">interfaces</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">eth</span></span>$<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontendVlan</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">allowedTCPPorts</span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontendPort</span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n      <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>;\n\n      <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> The haproxy module already opens a `global` section and installs the\n</span>      <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> stats socket, so this value must start at the next section.\n</span>      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">services</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">enable</span></span> = <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">config</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">defaults</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">mode</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">http</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">timeout</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">connect</span></span> 5s\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">timeout</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">client</span></span> 10s\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">timeout</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">server</span></span> 10s\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">timeout</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">check</span></span> 5s\n\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontend</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">fe_http</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">bind</span></span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyFrontendIp</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span>$<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">frontendPort</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">default_backend</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">be_hello</span></span>\n\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">backend</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">be_hello</span></span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">option</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">httpchk</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">GET</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">/</span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">http</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">check</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">expect</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">status</span></span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">200</span>\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">server</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">hello</span></span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webIp</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span>$<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webPort</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">check</span></span>\n        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span>;\n      <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>;\n    <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span>;\n\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pkgs</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span> <span class=\"syntax-constant syntax-language syntax-python\">...</span> <span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-python\">:</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">virtualisation</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">vlans</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">backendVlan</span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">virtualisation</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">memorySize</span></span> = <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">512</span>;\n\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">environment</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">systemPackages</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">pkgs</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">curl</span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">networking</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">firewall</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">enable</span></span> = <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>;\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> extraCommands is the iptables backend. Pin it so the rules below apply.\n</span>        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">backend</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">iptables<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">allowPing</span></span> = <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">false</span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">logRefusedPackets</span></span> = <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>;\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Nothing open on every source. The only accept is extraCommands.\n</span>        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">allowedTCPPorts</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">extraCommands</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">nixos</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">fw</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">p</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">tcp</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">s</span></span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyBackendIp</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">dport</span></span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webPort</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">nixos</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">fw</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">accept</span></span>\n\n          <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> No new outbound. Established replies (the HAProxy request path) still pass.\n</span>          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">o</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">lo</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">m</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">conntrack</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ctstate</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ESTABLISHED</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">RELATED</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">REJECT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">reject</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-invalid syntax-illegal syntax-name syntax-python\">with</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">icmp</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">host</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prohibited</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ip6tables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">o</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">lo</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ip6tables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">m</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">conntrack</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ctstate</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ESTABLISHED</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">RELATED</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ip6tables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">A</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">REJECT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">reject</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-invalid syntax-illegal syntax-name syntax-python\">with</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">icmp6</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">adm</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prohibited</span></span>\n        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">extraStopCommands</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">nixos</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">fw</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">p</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">tcp</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">s</span></span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxyBackendIp</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">dport</span></span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webPort</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">nixos</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">fw</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">accept</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">o</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">lo</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">m</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">conntrack</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ctstate</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ESTABLISHED</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">RELATED</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">iptables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">REJECT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">reject</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-invalid syntax-illegal syntax-name syntax-python\">with</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">icmp</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">host</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prohibited</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ip6tables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">o</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">lo</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ip6tables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">m</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">conntrack</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ctstate</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ESTABLISHED</span></span><span class=\"syntax-punctuation syntax-separator syntax-dictionary-or-set syntax-python\">,</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">RELATED</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">ACCEPT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ip6tables</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">D</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">OUTPUT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">j</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">REJECT</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">reject</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-invalid syntax-illegal syntax-name syntax-python\">with</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">icmp6</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">adm</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">prohibited</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">|</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span>\n        <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n      <span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n\n      <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">systemd</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">services</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">hello</span></span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">-</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">world</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">description</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Python hello-world HTTP server<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">wantedBy</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">multi-user.target<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">after</span></span> = <span class=\"syntax-meta syntax-structure syntax-list syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-list syntax-begin syntax-python\">[</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">network.target<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span> <span class=\"syntax-punctuation syntax-section syntax-list syntax-end syntax-python\">]</span></span>;\n        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">serviceConfig</span></span> = <span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ExecStart</span></span> = <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>pkgs.python3<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/bin/python3 ${pkgs.writeText <span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">hello</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">py</span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"> &#39;&#39;<span class=\"syntax-invalid syntax-illegal syntax-unclosed-string syntax-python\">\n</span></span></span>            <span class=\"syntax-invalid syntax-illegal syntax-name syntax-python\">from</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">http</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">server</span></span> <span class=\"syntax-invalid syntax-illegal syntax-name syntax-python\">import</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">BaseHTTPRequestHandler</span></span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ThreadingHTTPServer</span></span>\n\n            <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">BODY</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-storage syntax-type syntax-string syntax-python\">b</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>helloBody<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span><span class=\"syntax-constant syntax-character syntax-escape syntax-python\">\\n</span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n\n<span class=\"syntax-meta syntax-class syntax-python\">            <span class=\"syntax-storage syntax-type syntax-class syntax-python\">class</span> <span class=\"syntax-entity syntax-name syntax-class syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">Handler</span></span><span class=\"syntax-meta syntax-class syntax-inheritance syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-inheritance syntax-begin syntax-python\">(</span></span></span><span class=\"syntax-meta syntax-class syntax-inheritance syntax-python\"><span class=\"syntax-entity syntax-other syntax-inherited-class syntax-python\">BaseHTTPRequestHandler</span><span class=\"syntax-punctuation syntax-section syntax-inheritance syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-class syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-class syntax-begin syntax-python\">:</span></span>\n<span class=\"syntax-meta syntax-function syntax-python\">                <span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">do_GET</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">self</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n                    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">send_response</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">200</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n                    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">send_header</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Content-Type<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">text/plain<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n                    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">send_header</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">Content-Length<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-type syntax-python\">str</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">len</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">BODY</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n                    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">end_headers</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n                    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-language syntax-python\">self</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span><span class=\"syntax-meta syntax-generic-name syntax-python\">wfile</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">write</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-other syntax-constant syntax-python\">BODY</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\">                <span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">log_message</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">self</span><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-variable syntax-parameter syntax-python\">fmt</span><span class=\"syntax-punctuation syntax-separator syntax-parameters syntax-python\">,</span> <span class=\"syntax-keyword syntax-operator syntax-unpacking syntax-sequence syntax-python\">*</span><span class=\"syntax-variable syntax-parameter syntax-python\">args</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n                    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span>\n\n            <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-variable syntax-magic syntax-python\">__name__</span></span> <span class=\"syntax-keyword syntax-operator syntax-comparison syntax-python\">==</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">__main__<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n                <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">ThreadingHTTPServer</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-group syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-group syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>webIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-separator syntax-tuple syntax-python\">,</span> $<span class=\"syntax-meta syntax-structure syntax-dictionary-or-set syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-begin syntax-python\">{</span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">toString</span></span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">webPort</span></span><span class=\"syntax-punctuation syntax-section syntax-dictionary-or-set syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-section syntax-group syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-separator syntax-arguments syntax-python\">,</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">Handler</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">serve_forever</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n          <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">;<span class=\"syntax-invalid syntax-illegal syntax-unclosed-string syntax-python\">\n</span></span></span>          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">DynamicUser</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">NoNewPrivileges</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ProtectSystem</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">strict<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">ProtectHome</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">true</span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n          <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">Restart</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">on-failure<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n        <span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n      <span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n    <span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n  <span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n\n  <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">testScript</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">start_all</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">wait_for_unit</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">haproxy.service<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">wait_for_unit</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">hello-world.service<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">wait_for_unit</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">firewall.service<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">succeed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ip -4 addr show dev eth${toString frontendVlan} | grep -q &#39;$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyFrontendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/24&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">succeed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ip -4 addr show dev eth${toString backendVlan} | grep -q &#39;$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyBackendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/24&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">succeed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ip -4 addr show dev eth${toString backendVlan} | grep -q &#39;$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyUntrustedIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/24&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">succeed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ip -4 addr show dev eth${toString backendVlan} | grep -q &#39;$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>webIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/24&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n    <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-python\">with</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">subtest</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">backend accepts only haproxy on the hello port<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-with syntax-python\">:</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">wait_until_succeeds</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">curl -fsS --interface $<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyBackendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span> http://$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>webIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>:${toString webPort}/ | grep -F &#39;$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>helloBody<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fail</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">curl -fsS --max-time 5 --interface $<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyUntrustedIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span> http://$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>webIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>:${toString webPort}/<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fail</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">curl -fsS --max-time 5 --interface $<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyBackendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span> http://$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>webIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>:9/<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n    <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-python\">with</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">subtest</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">haproxy on the frontend vlan proxies to python<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-with syntax-python\">:</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">haproxy</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">wait_until_succeeds</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">curl -fsS http://$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyFrontendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/ | grep -F &#39;$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>helloBody<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n    <span class=\"syntax-meta syntax-statement syntax-with syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-with syntax-python\">with</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">subtest</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">python host cannot open new outbound connections<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-with syntax-python\">:</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fail</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">ping -c 1 -W 3 $<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyBackendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">fail</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">curl -fsS --max-time 5 http://$<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyBackendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>:${toString frontendPort}/<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> Return path still works: the proxy subtest above already required it.\n</span>        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">succeed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">iptables -S OUTPUT | grep -q &#39;REJECT&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">web</span><span class=\"syntax-punctuation syntax-accessor syntax-dot syntax-python\">.</span></span><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">succeed</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\">\n            <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\">iptables -S nixos-fw | grep -q -- &#39;-s $<span class=\"syntax-constant syntax-other syntax-placeholder syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-begin syntax-python\">{</span>haproxyBackendIp<span class=\"syntax-punctuation syntax-definition syntax-placeholder syntax-end syntax-python\">}</span></span>/32 -p tcp -m tcp --dport ${toString webPort} -j nixos-fw-accept&#39;<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n        </span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n  <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&#39;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-single syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&#39;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-statement syntax-python\">;</span>\n<span class=\"syntax-invalid syntax-illegal syntax-stray syntax-brace syntax-curly syntax-python\">}</span>\n</span></span></code></pre>\n<p>There's an old saying that bare metal was complicated and it was a mess. This is no longer true now that we have Nix. Honestly, one of the most galaxy-brain moves you can make these days is to ditch hyperscalers like AWS and acquire bare metal to build that fleet with NixOS, because business margins are going to get compressed by AI.</p>\n<p>Sure, you'll need to find an older, more experienced sysadmin, but once you get the right patterns in place, one or two of those people can operate with leverage equivalent to a team of 50 &quot;cloud certified&quot; monkeys. I shit you not, no exaggeration, it is insane what you can do with this composability.</p>\n<h2>single sources of truth</h2>\n<p>Nix, when architected correctly, enables you to define a single source of truth for any piece of software in your stack, including dependencies.</p>\n<p>Let's say there is a security vulnerability, and there is, like, a critical OpenSSL vulnerability. How long would it take you to identify all the different OpenSSL versions deployed within your organization? How long would it take to patch, including all dependencies of third-party software that depends on that particular version within your organization, <em>including software dependencies linked against it</em>?</p>\n<p>With nix, this can be achieved through a couple of lines</p>\n<pre><code><span class=\"code-snippet\" data-language=\"CSS\"><span class=\"syntax-source syntax-css\"><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span> <span class=\"syntax-meta syntax-property-name syntax-css\">pkgs</span>, ...</span> <span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">}</span><span class=\"syntax-meta syntax-selector syntax-css\">: </span><span class=\"syntax-meta syntax-property-list syntax-css\"><span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">{</span>\n\n<span class=\"syntax-meta syntax-property-name syntax-css\">nixpkgs</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">overlays</span> = [\n  (<span class=\"syntax-meta syntax-property-name syntax-css\">final</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\"> </span><span class=\"syntax-meta syntax-property-value syntax-css\">prev: {\n    openssl = prev.openssl.overrideAttrs (old: {\n    version = <span class=\"syntax-string syntax-quoted syntax-double syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-css\">&quot;</span>3.0.7<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-css\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-rule syntax-css\">;</span>\n    <span class=\"syntax-meta syntax-property-name syntax-css\"><span class=\"syntax-support syntax-type syntax-property-name syntax-css\">src</span></span> = <span class=\"syntax-meta syntax-property-name syntax-css\">prev</span>.<span class=\"syntax-meta syntax-property-name syntax-css\">fetchurl</span> {\n      <span class=\"syntax-meta syntax-property-name syntax-css\">url</span> = &quot;<span class=\"syntax-meta syntax-property-name syntax-css\">https</span><span class=\"syntax-punctuation syntax-separator syntax-key-value syntax-css\">:</span><span class=\"syntax-meta syntax-property-value syntax-css\">//www.openssl.org/source/openssl<span class=\"syntax-constant syntax-numeric syntax-css\">-3.0</span><span class=\"syntax-constant syntax-numeric syntax-css\">.7</span>.tar.gz<span class=\"syntax-string syntax-quoted syntax-double syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-css\">&quot;</span>;<span class=\"syntax-invalid syntax-illegal syntax-newline syntax-css\">\n</span></span>      hash = <span class=\"syntax-string syntax-quoted syntax-double syntax-css\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-css\">&quot;</span>sha256-...<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-css\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-terminator syntax-rule syntax-css\">;</span>\n</span>    <span class=\"syntax-punctuation syntax-section syntax-property-list syntax-css\">}</span>;\n  }\n</span></span></code></pre>\n<h2>what you just saw was an overlay</h2>\n<p>An overlay is the key primitive which makes Nix absolutely amazing. I want you to think about how you use open source software. What happens when you find a bug? Do you go to GitHub and ask someone to take your pull request? Or maybe you fork it. But when you fork it, you have to figure out how you'll build it and where you'll host the resulting artifact (ugh, Artifactory) so it can be consumed.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Screenshot-2026-10-07-at-6.04.08---AM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I'll show you a concrete example. It's here on GitHub. It shows a pattern I've used for years: in my agent sandbox environments, I customize the Git binary and remove the agent's ability to force-push by removing that functionality from Git itself. It also includes all the patterns shared in this blog post, from building a Docker image to building a NixOS virtual machine and testing that git <code>push --force</code> has been removed.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/nix-demo?ref=ghuntley.com\">GitHub - ghuntley/nix-demo: Patch git once with a Nix overlay; use it in devenv, a NixOS VM test and a Docker image</a></p>\n<p>Patch git once with a Nix overlay; use it in devenv, a NixOS VM test and a Docker image - ghuntley/nix-demo</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-7f331572-d019-42e0-8c95-94039e0c2728.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/nix-demo-7f204244-b7b5-40f9-b393-47a762e6f15b.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>What happens if what you need to customize isn't just a standard command-line tool? What happens if it's a low-level thing, like OpenSSL, that many things depend on, and you need to rebuild the world? Think about that graph. Think about the pain.</p>\n<p>With Nix, every change is just an overlay; all software becomes infinitely customizable at all levels, all the way down to the Linux kernel itself, and you can patch anything by asking an agent to customize it. The only restriction on what you can do is your imagination and ambition. These LLMs know Nix very well because the labs themselves are using Nix on their journey toward reaching RSI...</p>\n<h2>ps.</h2>\n<p>You might be wondering about Bazel and Buck2. I also use these alongside Nix, but the best bang for the buck right now is just to use Nix. There are a lot of problems with Nix, for example, how the derivation store works and what that means for incremental caching, something Bazel and Buck2 excel at, but I'm not going to complicate things right now by going into these details. Move past this and just start using Nix to customize all your software.</p>\n<h2>pps.</h2>\n<p>If you are building security-critical systems, burn tokens to find every security vulnerability in third-party dependencies your software stack relies on using a cyber model, and fix them with overlays. 🧠🧠🧠</p>\n<blockquote>\n<p>🗞️ the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay</p>\n<p>In this blog post, I go into how I use Nix, why you should use it, and in the tweet below is a runnable demo showing all of the concepts in this post <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/rZ3sqCb5gt?ref=ghuntley.com\">https://t.co/rZ3sqCb5gt</a> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/QeyAHWTxnR?ref=ghuntley.com\">pic.twitter.com/QeyAHWTxnR</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2107775282690330982?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 7, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-07T10:06:32+00:00",
      "date_published": "2026-10-07T10:06:32+00:00",
      "external_url": "https://ghuntley.com/nix/",
      "id": "urn:aggr:item:8bf89a7ad3211862574b3f17beecfcc68fffb32c",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Symbolic-traditional-tattoo-art-print-viewed-from-a-high--elevated-angle--portraying-a-bustling-city-transformed-by-a-Nix-overlay.-Gleaming-buildings--technological-textures--surreal-contrasts--and-limitless-possibility-evoke-hidden-power.-.jpg",
      "summary": "There are many things that are uncertain in our industry right now, but one thing I am certain about, and have been for almost 13 years, is that Nix is a terrible programming language. I remember when I first learned it, it felt like…",
      "tags": [
        "programming",
        "ai",
        "nix"
      ],
      "title": "the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-07-the-world-hasn-t-figured-out-yet-that-you-can-literally/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>It's kind of strange seeing all these discussions about software factories... and the like. It's also strange to see conversations about programming languages or claims that $language is best, as if that will remain true going forward. It's very clear, however, that programming languages will converge toward something, but that 'something' is undefined for now.</p>\n<p>What I haven't seen is people really deeply understanding the power of the new substrate that we have. People are still too fixated on what they have now and how systems have been built to rethink fundamentally how much things can change.</p>\n<blockquote>\n<p>To me, a software factory isn't just about process automation; it isn't about automating everything you've got as it is now. It's about using this substrate so you can develop your product while it runs whilst in the product itself.</p>\n<p>Everyone (regardless of their discipline or background) in the company should be able to develop the product in the product without having to go to some external vendor supplied tool.</p>\n<p>The only tool that exists is your product itself. The product should build the product from the product.</p>\n</blockquote>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/rad\">a sneak preview behind an embedded software factory. I suspect rapid application dev is back</a></p>\n<p>Hey folks, I’m currently over in SF. For the last couple of weeks, I’ve been cryptically tweeting about a hidden mode within something I’ve been building on called Latent Patterns (see below), and over the last couple of days, I’ve started opening up and showing people</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--6f81e89e-3a32-49dc-8585-cf0ed1757e08.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/Symbolic-traditional-tattoo-art-print--lush-garden-with-vibrant-roses-and-a-computer--detailed-painting--strong-hard-light-surreal-infrared-tones--vibrant-colors--retro-flair--complex-ornamental--white-background--infrared-spectrum--otherwo-a318d1d0-6e0c-431e-b68a-439b7334e9ea.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>earlier explorations into recursive product development at the begining on the year</p>\n<p>In a future blog post, I'll go further into what it means for the product to develop the product, in the product, but for now I have one simple thing for you to imagine:</p>\n<blockquote>\n<p>Why is software built the way it is now, rather than grown through iterative use of LLMs? What if you could develop your application just by chatting with it? Live and interactive with no compilation steps.</p>\n</blockquote>\n<p>To demonstrate this, I built Jiti, a small kernel for growing a running Lisp application through conversation with an LLM. You ask for a capability, the model writes Lisp, and the application permanently acquires that capability until you ask for that capability to be removed.</p>\n<p>0:00</p>\n<p>/0:41</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/10/CleanShot-2026-10-05-at-7.54.45-AM_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The kernel supplies the machinery to inspect, change, execute, and recover a managed Lisp world. Application behavior comes from whatever you decide to add to the application by prompting for those outcomes. With Jiti, you can start from a clean slate or modify an existing application to add more behavior just by prompting it.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/01-conversation-and-lisp.png\" alt=\"A request to add a capability goes to an external language model with instructions, registered tool descriptions and observed application state. The model requests a tool call. The controller validates and routes it to the persistent worker, which evaluates Lisp in the running application. Actual values, checks or a live pause return through the controller to inform the next model step. Accepted definitions and managed data remain available for later requests. Ordinary Lisp function calls do not require inference.\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>The language model uses registered tools to inspect and change a running Lisp application. Actual worker results inform its next step; accepted functions and managed data remain available for later requests. Once defined, functions execute as ordinary Lisp. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/01-conversation-and-lisp.svg?ref=ghuntley.com\">SVG source</a>.</figcaption></figure>\n<p>The source code is available on GitHub, and I encourage you to run it and play around with it. It is very generic, in the sense that it can do literally anything you want. All you have to do is ask, and it will program that capability into the application.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/jiti?ref=ghuntley.com\">GitHub - ghuntley/jiti: Live Common Lisp image repair with OpenAI tools, persistent revisions, and a conversational CLI</a></p>\n<p>Live Common Lisp image repair with OpenAI tools, persistent revisions, and a conversational CLI - ghuntley/jiti</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-c2c75955-7fde-489b-8554-291dca12326a.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub ghuntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/jiti-0295d346-02de-4f46-a6b0-10ef4bacbc1f.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>How it works is relatively simple. At a high level, an OpenAI model receives your request, instructions for operating the application, tool definitions, and observations of its current state. The kernel can ask to inspect the available functions, read a definition, propose new source, or execute an expression.</p>\n<p>Once a definition is accepted, it is an ordinary Lisp function. Calling it does not inherently require another inference request. You can call it from Lisp, from another application function, or through the chat interface.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Screenshot-2026-10-05-at-7.46.58---AM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The OpenAI model is used to extend a program, while the running Lisp world holds the resulting functionality.</p>\n<p>The agent tool interface has two useful intentions.</p>\n<ul>\n<li><code>develop_form</code> adds, redefines or removes functionality.</li>\n<li><code>execute_form</code> calls functionality that exists, including combinations of existing functions.</li>\n</ul>\n<p>Both use the same evaluator and transaction machinery. The distinction helps the model choose whether the user is asking to change the application or simply use it.</p>\n<blockquote>\n<p>why write code and suffer compilation loop pain when you can prompt an LLM to program LISP for outcomes? <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/CYA4apelcl?ref=ghuntley.com\">pic.twitter.com/CYA4apelcl</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2107031936375955502?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 5, 2026</a></p>\n</blockquote>\n<p>Suppose I've already asked the application to add <code>uppercase-string</code> and <code>reverse-string</code>. I can then prompt the kernel to uppercase some text and reverse the result. The composition is just Lisp:</p>\n<pre><code class=\"language-lisp\"><span class=\"code-snippet\" data-language=\"Lisp\"><span class=\"syntax-source syntax-lisp\"><span class=\"syntax-meta syntax-group syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-begin syntax-lisp\">(</span><span class=\"syntax-support syntax-function syntax-lisp\">reverse</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-lisp\">-</span><span class=\"syntax-support syntax-function syntax-lisp\">string</span> <span class=\"syntax-meta syntax-group syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-begin syntax-lisp\">(</span>uppercase<span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-lisp\">-</span><span class=\"syntax-support syntax-function syntax-lisp\">string</span> <span class=\"syntax-string syntax-quoted syntax-double syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-lisp\">&quot;</span>Hello<span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-lisp\">&quot;</span></span><span class=\"syntax-punctuation syntax-definition syntax-group syntax-end syntax-lisp\">)</span></span><span class=\"syntax-punctuation syntax-definition syntax-group syntax-end syntax-lisp\">)</span></span>\n</span></span></code></pre>\n<p>If I want that combination as a reusable capability, I can prompt it to save that as a function.</p>\n<pre><code class=\"language-lisp\"><span class=\"code-snippet\" data-language=\"Lisp\"><span class=\"syntax-source syntax-lisp\"><span class=\"syntax-meta syntax-group syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-begin syntax-lisp\">(</span><span class=\"syntax-meta syntax-function syntax-lisp\"><span class=\"syntax-storage syntax-type syntax-function-type syntax-lisp\">defun</span> <span class=\"syntax-entity syntax-name syntax-function syntax-lisp\">shout-backwards</span></span> <span class=\"syntax-meta syntax-group syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-begin syntax-lisp\">(</span>text<span class=\"syntax-punctuation syntax-definition syntax-group syntax-end syntax-lisp\">)</span></span>\n  <span class=\"syntax-meta syntax-group syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-begin syntax-lisp\">(</span><span class=\"syntax-support syntax-function syntax-lisp\">reverse</span><span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-lisp\">-</span><span class=\"syntax-support syntax-function syntax-lisp\">string</span> <span class=\"syntax-meta syntax-group syntax-lisp\"><span class=\"syntax-punctuation syntax-definition syntax-group syntax-begin syntax-lisp\">(</span>uppercase<span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-lisp\">-</span><span class=\"syntax-support syntax-function syntax-lisp\">string</span> text<span class=\"syntax-punctuation syntax-definition syntax-group syntax-end syntax-lisp\">)</span></span><span class=\"syntax-punctuation syntax-definition syntax-group syntax-end syntax-lisp\">)</span></span><span class=\"syntax-punctuation syntax-definition syntax-group syntax-end syntax-lisp\">)</span></span>\n</span></span></code></pre>\n<p>That function joins the catalog with its arguments and source, ready for inspection and later use. A future request can discover it and build on it. The application accumulates an executable vocabulary through use. Lisp already gives us the composition rules; the kernel keeps the evolving definitions available and their managed effects accountable.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/02-kernel-ownership-1.png\" alt=\"The controller validates tool arguments and sends actions one at a time to a persistent worker, receiving observations and results in return. The worker owns evaluation, the live stack and active restarts. Inside that worker, the world adapter provides managed code and data, the function catalogue, checkpoint and restore, and durable export and import. Caller-supplied safety checks and goals are assessed at safe points. Safety determines whether a candidate may be kept; goals determine completion. Accepted managed changes publish durable revisions. The reference adapter covers named functions and readable table data.\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>The controller routes actions; the persistent worker owns evaluation and live restarts. Its world adapter defines the managed resources, catalogue and recovery hooks. Caller safety checks govern acceptance while goals describe completion. Accepted managed changes become durable revisions. <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/02-kernel-ownership-1.svg?ref=ghuntley.com\">SVG source</a>.</figcaption></figure>\n<p>Lisp deserves the credit for the interactive programming machinery. Definitions, inspection, conditions, and restarts have been there for decades. It's kind of cool, huh?</p>\n<p>To me, the idea that an agent writes source code and then there's a costly compilation phase involving CI/CD is now truly undefined now that we have AI. The only limiting factor will really be people's curiosity about what they can do with this new substrate...</p>\n<p>ps. socials</p>\n<blockquote>\n<p>🗞️ an application in lisp you grow by talking to it</p>\n<p>Why is software built the way it is now, rather than grown through iterative use of LLMs? What if you could develop your application just by chatting with it? Live and interactive, with no compilation steps.…</p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2107080798209794317?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">October 5, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-10-05T12:07:33+00:00",
      "date_published": "2026-10-05T12:07:33+00:00",
      "external_url": "https://ghuntley.com/lisp/",
      "id": "urn:aggr:item:8512f6cbed2beb2e17794e958c5c4f905380d341",
      "image": "https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/10/Low-angle-traditional-tattoo-art-print-symbolizing-an-application-nurtured-through-conversation--showing-a-smartphone-and-speech-bubble-rising-into-ornate-vines--vibrant-retro-colors--complex-vintage-linework--white-background--wet-reflecti.jpg",
      "summary": "It's kind of strange seeing all these discussions about software factories... and the like. It's also strange to see conversations about programming languages or claims that $language is best, as if that will remain true going forward.…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "an application in lisp you grow by talking to it",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-05-an-application-in-lisp-you-grow-by-talking-to-it/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>I sat down with the folks at AI21 Labs for their YAAP podcast at the AI:Engineer World Fair, and we went deep on something I've been chewing on for most of this year: almost every decision in computing for the last forty years was made with a human in the loop, as the reader, the writer, or the operator. What happens when that stops being true?</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys\">YAAP | Your Code Doesn't Need to Be Readable Anymore</a></p>\n<p>YAAP by AI21 Labs — &quot;Your Code Doesn't Need to Be Readable Anymore&quot; (21 minutes)</p>\n<p>Here's the gist, written up properly, plus chapter links at the bottom if you want to jump into a specific part of the conversation.</p>\n<blockquote>\n<p>Software doesn't need to be readable by a human. It needs to be explainable to a human.</p>\n</blockquote>\n<h2>the economics of AI are cooked, and I still haven't written code by hand in two years</h2>\n<p>The opening hot take was that AI economics are absolutely cooked because adoption is nowhere near what is needed to achieve ROI on the amount of capital deployed. This is why all the labs are hiring aggressively to staff up professional services organizations around the world right now. Go read Ed Zitron's <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.wheresyoured.at/?ref=ghuntley.com\">Where's Your Ed At</a> if you want the long version.</p>\n<p>So far, the only reliable ways anyone has found to make money with AI are reselling tokens with a markup (and competing directly against the labs while you do it) or selling the infrastructure around them: sandboxes and the like.</p>\n<p>Both things can be true at once. The economics can be cooked, <em>and</em> how I develop software has completely, fundamentally changed. I haven't written code by hand for two years. These models generate code better than most employers can actually hire for.</p>\n<p>What changes is how you think about spend. The thing we're all going to discover over the next year is <strong>where we actually need frontier intelligence and where we don't</strong>. Frontier intelligence is expensive, and you don't need it for every single task.</p>\n<ul>\n<li>The models have been good enough for at least a year. There was a real jump from Sonnet 3.5 to the Opus 4-ish range; since then it's been marginal. The hype and hysteria around alignment and security change, but the capability mostly hasn't. These models have always known how to drive Kali and Burp Suite.</li>\n<li>Personally, I run a mix of GPT 6.1 sol on no or low reasoning, and GLM/Kimi. I use programming languages that let me get away with that (more on that below).</li>\n<li>Find the right model for the task, then buy those tokens wherever they're cheapest. Take an open-weights model like GLM, run it on Baseten, and it costs a fraction as much.</li>\n<li>If you're a company, check for zero data retention. At home? Just get your tokens cheap. There was a time when Z.ai's yearly GLM plan was $300 AUD a <em>year</em>, compared with $300 a <em>month</em> for the big labs' plans. Some of the smartest engineers I know bought twenty of them and ripped with concurrency.</li>\n</ul>\n<p>It's not about the model anymore. It's about how you use the model.</p>\n<h2>the last forty years of computing were designed around humans</h2>\n<p>Why does a computer have a console? Because we used to have mainframe operators. A whole lot of what we consider &quot;how computers work&quot; is really &quot;how computers were made legible to people.&quot;</p>\n<p>Back in March I took a detour, picked OCaml back up because it has an effect system built in, and started playing with unikernels via <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://mirage.io/?ref=ghuntley.com\">MirageOS</a>.</p>\n<p>Most applications run <em>on</em> an operating system. What if the application <em>was</em> the operating system — a very thin one, with almost no overhead? Most software gets breached either through an exploit in the OS layer or through the app layer as a foothold into the OS. Delete the OS layer, and you delete that class of problem.</p>\n<p>I ended up rebuilding essentially Erlang as a distributed operating system. Is that a dead end? Maybe. Sometimes these experiments are. But knowing what's possible, and where it works and where it doesn't, lets you rethink the last forty years and ask a better question: <strong>can we delete instead of build?</strong></p>\n<p>Humans aren't operating machines anymore either. You hand a Docker container to a Kubernetes cluster and an operator control loop manages it. Once the human is out of the loop, the design decisions that existed for the human are up for renegotiation.</p>\n<p>I truly think Unikernels are going to come back into fashion hard over the next couple of years for security reasons. All the friction... that existed when architecting an application with this design no longer exists.</p>\n<h2>readable vs explainable</h2>\n<p>People are still saying, very loudly, that code should be readable so that humans can understand it. I no longer think that's the goal.</p>\n<p>Try this for fun: go play with Haskell this weekend. It doesn't matter if you've never touched it. The LLMs know it. There's a lot of dogma out there about things being hard to learn. Well, they're now false. Learning things like Nix and Haskell used to be pushing shit uphill and unachievable in a single sitting. But now the LLM knows it's easy.</p>\n<p>Below, you'll find a function that I have deliberately obfuscated....</p>\n<pre><code class=\"language-haskell\"><span class=\"code-snippet\" data-language=\"Haskell\"><span class=\"syntax-source syntax-haskell\"><span class=\"syntax-meta syntax-function syntax-type-declaration syntax-haskell\"><span class=\"syntax-entity syntax-name syntax-function syntax-haskell\">f</span> <span class=\"syntax-keyword syntax-other syntax-double-colon syntax-haskell\">::</span> <span class=\"syntax-storage syntax-type syntax-haskell\">String</span> <span class=\"syntax-keyword syntax-other syntax-arrow syntax-haskell\">-&gt;</span> <span class=\"syntax-storage syntax-type syntax-haskell\">String</span>\nf <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> </span>g <span class=\"syntax-keyword syntax-operator syntax-haskell\">.</span> h\n  <span class=\"syntax-keyword syntax-other syntax-haskell\">where</span>\n    h <span class=\"syntax-constant syntax-language syntax-empty-list syntax-haskell\">[]</span>     <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> <span class=\"syntax-constant syntax-language syntax-empty-list syntax-haskell\">[]</span>\n    h (x<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>xs) <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> h xs <span class=\"syntax-keyword syntax-operator syntax-haskell\">++</span> [x]\n    g x <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span>\n      <span class=\"syntax-keyword syntax-other syntax-haskell\">let</span> (y<span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> z) <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> p x\n      <span class=\"syntax-keyword syntax-other syntax-haskell\">in</span> <span class=\"syntax-keyword syntax-control syntax-haskell\">if</span> y <span class=\"syntax-keyword syntax-control syntax-haskell\">then</span> z <span class=\"syntax-keyword syntax-control syntax-haskell\">else</span> g z\n    p <span class=\"syntax-constant syntax-language syntax-empty-list syntax-haskell\">[]</span>       <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> (<span class=\"syntax-constant syntax-other syntax-haskell\">True</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> <span class=\"syntax-constant syntax-language syntax-empty-list syntax-haskell\">[]</span>)\n    p [x]      <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> (<span class=\"syntax-constant syntax-other syntax-haskell\">True</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> [x])\n    p (x<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>y<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>xs)\n      <span class=\"syntax-keyword syntax-operator syntax-haskell\">|</span> x <span class=\"syntax-keyword syntax-operator syntax-haskell\">&gt;</span> y     <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> <span class=\"syntax-keyword syntax-other syntax-haskell\">let</span> (a<span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> b) <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> p (x<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>xs) <span class=\"syntax-keyword syntax-other syntax-haskell\">in</span> (<span class=\"syntax-constant syntax-other syntax-haskell\">False</span><span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> y<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>b)\n      <span class=\"syntax-keyword syntax-operator syntax-haskell\">|</span> otherwise <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> <span class=\"syntax-keyword syntax-other syntax-haskell\">let</span> (a<span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> b) <span class=\"syntax-keyword syntax-operator syntax-haskell\">=</span> p (y<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>xs) <span class=\"syntax-keyword syntax-other syntax-haskell\">in</span> (a<span class=\"syntax-punctuation syntax-separator syntax-comma syntax-haskell\">,</span> x<span class=\"syntax-keyword syntax-operator syntax-haskell\">:</span>b)\n</span></span></code></pre>\n<p>Right now you're probably looking at the code and going... What the actual ... is this?</p>\n<p>Now copy that function into an LLM and prompt it to <em>&quot;explain this function to me as if you were explaining it to my son or daughter but in Python as a reference.&quot;</em></p>\n<p>All of a sudden it becomes accessible. It reads like Python.</p>\n<blockquote>\n<p>This Haskell turns a string into its letters in alphabetical order. It does that in two steps: flip the string backwards, then keep bubbling letters into order until nothing moves.</p>\n</blockquote>\n<pre><code class=\"language-python\"><span class=\"code-snippet\" data-language=\"Python\"><span class=\"syntax-source syntax-python\"><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">flip</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">letters</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>Put the string backwards. &#39;cat&#39; becomes &#39;tac&#39;.<span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span> <span class=\"syntax-keyword syntax-operator syntax-comparison syntax-python\">==</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-begin syntax-python\">&quot;</span></span></span><span class=\"syntax-meta syntax-string syntax-python\"><span class=\"syntax-string syntax-quoted syntax-double syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-string syntax-end syntax-python\">&quot;</span></span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">first</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rest</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-separator syntax-slice syntax-python\">:</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">flip</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rest</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">+</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">first</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">one_pass</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">letters</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>\n    Walk the letters once.\n    Whenever a bigger letter is sitting in front of a smaller one,\n    slide the smaller one forward.\n    Also report whether anything moved.\n    <span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-support syntax-function syntax-builtin syntax-python\">len</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span> <span class=\"syntax-keyword syntax-operator syntax-comparison syntax-python\">&lt;=</span> <span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-constant syntax-language syntax-python\">True</span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span>  <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> already tidy\n</span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">first</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">0</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">second</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">1</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rest</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-begin syntax-python\">[</span></span><span class=\"syntax-meta syntax-item-access syntax-arguments syntax-python\"><span class=\"syntax-constant syntax-numeric syntax-integer syntax-decimal syntax-python\">2</span><span class=\"syntax-punctuation syntax-separator syntax-slice syntax-python\">:</span></span><span class=\"syntax-meta syntax-item-access syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-brackets syntax-end syntax-python\">]</span></span>\n\n    <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">first</span></span> <span class=\"syntax-keyword syntax-operator syntax-comparison syntax-python\">&gt;</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">second</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> smaller one goes in front; keep comparing the bigger one\n</span>        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">moved</span></span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">after</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">one_pass</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">first</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">+</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rest</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-constant syntax-language syntax-python\">False</span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">second</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">+</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">after</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-conditional syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">else</span><span class=\"syntax-punctuation syntax-section syntax-block syntax-python\">:</span></span>\n        <span class=\"syntax-comment syntax-line syntax-number-sign syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-python\">#</span> these two are fine; check the rest\n</span>        <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">moved</span></span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">after</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">one_pass</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">second</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">+</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">rest</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">moved</span></span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">first</span></span> <span class=\"syntax-keyword syntax-operator syntax-arithmetic syntax-python\">+</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">after</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">tidy_up</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">letters</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-comment syntax-block syntax-documentation syntax-python\"><span class=\"syntax-punctuation syntax-definition syntax-comment syntax-begin syntax-python\">&quot;&quot;&quot;</span>Keep doing one pass until a whole pass changes nothing.<span class=\"syntax-punctuation syntax-definition syntax-comment syntax-end syntax-python\">&quot;&quot;&quot;</span></span>\n    <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">done</span></span>, <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span> <span class=\"syntax-keyword syntax-operator syntax-assignment syntax-python\">=</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">one_pass</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n    <span class=\"syntax-meta syntax-statement syntax-if syntax-python\"><span class=\"syntax-keyword syntax-control syntax-flow syntax-conditional syntax-python\">if</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">done</span></span><span class=\"syntax-punctuation syntax-section syntax-block syntax-conditional syntax-python\">:</span></span>\n        <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">tidy_up</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">letters</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n\n<span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-storage syntax-type syntax-function syntax-python\">def</span> <span class=\"syntax-entity syntax-name syntax-function syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">f</span></span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-begin syntax-python\">(</span></span><span class=\"syntax-meta syntax-function syntax-parameters syntax-python\"><span class=\"syntax-variable syntax-parameter syntax-python\">text</span><span class=\"syntax-punctuation syntax-section syntax-parameters syntax-end syntax-python\">)</span></span><span class=\"syntax-meta syntax-function syntax-python\"><span class=\"syntax-punctuation syntax-section syntax-function syntax-begin syntax-python\">:</span></span>\n    <span class=\"syntax-keyword syntax-control syntax-flow syntax-return syntax-python\">return</span> <span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">tidy_up</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-function-call syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-variable syntax-function syntax-python\">flip</span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-begin syntax-python\">(</span><span class=\"syntax-meta syntax-function-call syntax-arguments syntax-python\"><span class=\"syntax-meta syntax-qualified-name syntax-python\"><span class=\"syntax-meta syntax-generic-name syntax-python\">text</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span></span><span class=\"syntax-punctuation syntax-section syntax-arguments syntax-end syntax-python\">)</span></span>\n</span></span></code></pre>\n<p>That's the shift. The artifact doesn't need to be optimized for a human to read cold. It needs to be something a model can explain to a human on demand.</p>\n<h2>types are back pressure</h2>\n<p>If you want a codebase that agents can maintain, you'll notice something quickly: <strong>a Rust codebase is far more maintainable with agents than a Python one</strong>. Types are a form of verification. They provide <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/pressure/\">back pressure</a>: compiler errors that the LLM picks up and fixes automatically, every loop.</p>\n<p>Think of it as a continuum of power. Up one end, Haskell is even stricter than Rust. At the other end, you've got Ruby, Python, PHP, and Perl, where types were never a first-class citizen and are hard to bolt on after the fact.</p>\n<p>This is also why I can get away with cheaper models. Pick a language that does the verification for you, and you need less intelligence to stay on the rails.</p>\n<h2>programming languages move at the speed of human learning</h2>\n<p>Languages evolve through committees, and the pace of language development has been deliberately slowed to match the rate at which humans can learn new concepts.</p>\n<p>I remember when monads arrived in .NET — LINQ in 3.5, championed by Erik Meijer. We're talking about <code>SelectMany</code>, flat map, to be blunt. It took an easy five to eight years before people were comfortable with it. Now it's everywhere in every programming language.</p>\n<p>Or look at Python 2 to 3. It's been about fifteen years, and there are still wounds. The lesson the industry took was &quot;you must not break users,&quot; so nobody makes breaking changes.</p>\n<p>But what happens if the language designer ships a skills pack alongside the breaking change, and the agent just does the migration?</p>\n<blockquote>\n<p>If humans aren't the target audience, we don't have to dumb down the language for adoption, and the LLMs have the entire corpus of programming language theory — what can we do with that?</p>\n</blockquote>\n<p>There are maybe ten or twelve truly great applied programming language designers in the world, and most of them have <strong>specialized their careers in human accessibility</strong>.</p>\n<p>It's going to take people on the fringe of comp sci (the ones who were told, &quot;you can't do that, nobody will learn it&quot;) to hear that this is now false. You can take research that's twenty years old, put it together, and the LLM will do it for you.</p>\n<p>I've been collecting other nerds who are thinking along the same lines. No results to show yet. We're all just playing with this new substrate.</p>\n<blockquote>\n<p>If coding agents will write most of our code, what happens with our communities and sense of ergonomics? How does it impact our compilers and tools? <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/DaYCSHFUBY?ref=ghuntley.com\">https://t.co/DaYCSHFUBY</a></p>\n<p>— José Valim (@josevalim) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/josevalim/status/2103133294317445290?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">September 24, 2026</a></p>\n</blockquote>\n<p>Highly recommend reading this article. Programming language authors who build their languages around agent-first rather than human-first will get ahead. Those who don't will fall behind and end up like Solaris.</p>\n<h2>languages are fungible now</h2>\n<p>Consider being a CTO before AI...</p>\n<blockquote>\n<p>&quot;We need to hire a Ruby person. Over here it's .NET, so that's a separate team. And the company we acquired is Java.&quot;</p>\n</blockquote>\n<p>The end business impact is that you are maintaining three teams, or teams of teams, on tribal ideology about programming languages.</p>\n<p>Now you can <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/loop/\">run loops</a> to port from one language to the next. A founder in the medical space in Australia had an old ASP.NET Web Forms app on IIS. Terrible, terrible, terrible; I've done it, I know. I challenged him to run some loops himself, then go back to his team the next morning without telling them and ask for an estimate on the rewrite. They said years. A week later the migration was done. He did it all himself and completely mogged his engineering team.</p>\n<p>Porting is easy when the end result is easy to verify. Stealing an idea from a Go library and wanting it in Rust is easy now, and has been for at least a year.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/z80\">Can a LLM convert C, to ASM to specs and then to a working Z/80 Speccy tape? Yes.</a></p>\n<p>✨Daniel Joyce used the techniques described in this post to port ls to rust via an objdump. You can see the code here: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/DanielJoyce/ls-rs\">https://github.com/DanielJoyce/ls-rs</a>. Keen, to see more examples - get in contact if you ship something! Damien Guard nerd sniped me and other folks wanted</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--c4421c9b-5f3c-40dc-838c-40b5235ce4e8.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/bafkreiftzmpb7bbkej76rac3kuijg2mcuyjxxhtnqdie5qq6rbrc45v2iu-1-a7544c4e-6d21-416a-898f-997162311d6f.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>It is provably true that languages are fungible, and it makes no business sense to carry so many of them in your business today.</p>\n<p>Operating systems went through a convergence event: AIX, Solaris, HP-UX and IRIX all collapsed into Mac, Linux and Windows. I expect programming languages to converge the same way: down to a couple of gilded languages, or something new rises from the dust.</p>\n<h2>the V8 hot rod</h2>\n<p>The usual objection to a new programming language is adoption. But you don't necessarily need adoption now when deciding whether to use a language, now that we have AI. Like, what libraries exist in this ecosystem don't factor into my decision to create a new project these days.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/libraries\">what is the point of libraries now that you can just generate them?</a></p>\n<p>It’s a meme as accurate as time. The problem is that our digital infrastructure depends upon just some random guy in Nebraska. Open-source, by design, is not financially sustainable. Finding reliable, well-defined funding sources is exceptionally challenging. As projects grow in size, many maintainers burn out and</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--c23bc14e-360c-4106-9896-e25298235b65.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/A-symbolic-traditional-tattoo-art-print-of-a-software-library-in-vibrant-retro-colors-with-complex-ornamental-details.-Creative-light-art-is-used-to-achieve-an-abstract-pattern-with-complimentary-colors--balance-36436c4b-e2ea-4613-85eb-539cecd7bc7d.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>If you'd built some sick V8 hot rod and everyone else was on a horse, would you care whether they adopted it? &quot;Yeah, enjoy that horse, mate.&quot;</p>\n<p>That's why this area is interesting. Not &quot;is there a faster programming language,&quot; but: can we incorporate more ideas from verification into our languages, stop optimizing for humans, and start optimizing for agents? Is there a way to go faster? I don't know yet. I guess we'll have to find out.</p>\n<h2>what I'm building in the meantime</h2>\n<p>Since January, I've been talking about Loom and the idea of a software factory, something that optimizes a whole business function. It's on GitHub, it's not really usable, and it's not intended to be; it's research.</p>\n<p>Software factories are very, very hard to do right now. For the last six months, my view has been that we need one of: better models, better programming languages, or a revival of some old computer science techniques like simulators.</p>\n<p>Ultimately, I want to replace GitHub. I want to bring back something like Phabricator, the engineering system that predates GitHub and came out of Facebook's early days. Google has Piper and Rosie for large-scale refactoring. Meta has EdenFS, Mononoke and Sapling. If GitHub is the only thing you've seen, it seems fine. It's not good enough. I think Git is somewhat end-of-life; I really wish people would stop trying to extend Git's lifespan.</p>\n<p>So right now I've got loops running that are rebuilding a source control system where:</p>\n<ul>\n<li>contents are encrypted;</li>\n<li>agents get a claim, which provides a materialized view of the repository;</li>\n<li>that means real ACLs. Share a sub-path with a contractor, much like Windows file permissions, instead of &quot;the Git repo has everything.&quot;</li>\n</ul>\n<p>It's a distributed system, so I'm building it in Rust and building <strong>the simulator first</strong>, then driving the agent to validate everything through the simulator. That has kept the agent on the rails remarkably well.</p>\n<h2>chapters</h2>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=55s&amp;ref=ghuntley.com\">0:55</a> — the economics of AI are cooked</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=150s&amp;ref=ghuntley.com\">2:30</a> — where you actually need frontier intelligence</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=270s&amp;ref=ghuntley.com\">4:30</a> — get your tokens cheap</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=331s&amp;ref=ghuntley.com\">5:31</a> — Loom and software factories</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=421s&amp;ref=ghuntley.com\">7:01</a> — rebuilding source control; Git is end of life</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=511s&amp;ref=ghuntley.com\">8:31</a> — simulator-first development</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=540s&amp;ref=ghuntley.com\">9:00</a> — OCaml, unikernels and forty years of human-centric computing</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=650s&amp;ref=ghuntley.com\">10:50</a> — readable vs explainable</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=810s&amp;ref=ghuntley.com\">13:30</a> — types as back pressure</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=870s&amp;ref=ghuntley.com\">14:30</a> — languages designed by committee</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=960s&amp;ref=ghuntley.com\">16:00</a> — languages are fungible</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=1170s&amp;ref=ghuntley.com\">19:30</a> — the V8 hot rod</li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=vrCE5m2MRys&amp;t=1230s&amp;ref=ghuntley.com\">20:30</a> — optimise for agents, not humans</li>\n</ul>\n<p>Keep curious.</p>\n",
      "date_modified": "2026-10-02T06:06:40+00:00",
      "date_published": "2026-10-02T06:06:40+00:00",
      "external_url": "https://ghuntley.com/readable/",
      "id": "urn:aggr:item:02ee3a8af37d0bd9f255f700b7fc06f2564c4bdf",
      "summary": "Forty years of computing was designed around humans as the reader, writer and operator. On AI21's YAAP podcast I argued that's no longer a design goal, and what that means for programming languages.",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "software doesn't need to be readable anymore. it needs to be explainable.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-02-software-doesn-t-need-to-be-readable-anymore-it-needs-to-be/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>One of the original promises of a personal computer was that the computer would be personal. It's kind of strange to think that, now in 2026, it has taken circa 40 years for this to actually become true.</p>\n<p>You see, over the last 40 years, someone was either a software developer, also known as a programmer, and in that case they were able to make a computer personal. If you didn't have these skills, you were given an interface, and your ability to personalize the computer or software was limited to what the interface could do.</p>\n<p>Something strange is happening in game development circles right now. With AI, everyone is a game developer. It doesn't matter whether someone has the skills of a software developer or a game developer; they can express what they want, and a couple of loops later, they have outcomes.</p>\n<p>0:00</p>\n<p>/0:59</p>\n<p>credit: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/chasmmmmmmmmmmm/status/2105707774646562818?ref=ghuntley.com\">https://x.com/chasmmmmmmmmmmm/status/2105707774646562818</a></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/10/chasm---AI-Hackers-are-now-mashing-up-EVERY-game-possible-to-create-the-games...--2105706853808136192-_thumb.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Yet, why is it that at most corporates right now, the responsibility to develop software is a named role or job function?</p>\n<blockquote>\n<p>One of my hottest takes right now is that 2026 and 2027 are all about enabling others in your organization to contribute to and develop software, and if your corporate roadmap doesn't have this on the agenda, you're missing the mark. If you aren't aligned with making this happen, then you're self-sabotaging your career.</p>\n</blockquote>\n<p>Corporate is full of dogma about how things should be done, the processes, and who's responsible for getting things done. This needs to be completely rethought from first principles, including who is responsible for these activities and what that entails.</p>\n<p>Everyone is now a software developer. The craft has been commoditized, but access to do the craft within corporate has not. Agile assumed writing software was the costly, scarce activity, so it optimized the loop around human authorship by a select few.</p>\n<p>If you still have software engineers within your company writing code by hand and outright rejecting AI, you should be setting the stage for tough career conversations with that person within the next six months, because they have failed the curiosity test.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=Jr2auYrBDA4\">fundamental skills and knowledge you must have in 2026 for SWE</a></p>\n<p>don't hire left of the line</p>\n<p>It's easy to get political about the commoditization of our profession, and I see engineers that I respect lean into the argument that labs have stolen intellectual property, etc., but it's been two years now...</p>\n<blockquote>\n<p>There is a big pool of juniors who are available, are cheaper, and are more AI-native that can be hired. There's never been a market for free-range organic software; it's always been about more, cheaper and sooner.</p>\n</blockquote>\n<blockquote>\n<p>I've never seen this before in my career: 28-30 year olds who refuse to use AI coding tools.</p>\n<p>You show them what they can do augmented (not replaced) with AI and you see in their eyes that they have no damn clue of what's happening.</p>\n<p>You can't work with these people anymore. Time…</p>\n<p>— Ivan Burazin (@ivanburazin) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/ivanburazin/status/2029693439055474720?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">March 5, 2026</a></p>\n</blockquote>\n<p>If you're looking to get ahead as a software engineer or business leader, my strongest recommendation is to enable the commoditization of access so everyone can write software within your business.</p>\n<p>ps. There is no reason software quality should dip in your organization because of AI adoption. These days, when I hear someone say that, I just think...</p>\n<blockquote>\n<p>&quot;Wow, you're truly over-indexing on the quality of humans that were available to hire in the general labor market. These LLMs generate better code than 99% of companies could hire for. Things have changed. Why can't you see this? Please put your family unit and yourself first.&quot;</p>\n</blockquote>\n<p>Our job as software engineers now is to engineer systems, including safety controls, that let everyone ship to production — safely.</p>\n",
      "date_modified": "2026-10-02T04:38:26+00:00",
      "date_published": "2026-10-02T04:38:26+00:00",
      "external_url": "https://ghuntley.com/access/",
      "id": "urn:aggr:item:099b001407801aeb49cf41c301d16d7d44c187a9",
      "summary": "One of the original promises of a personal computer was that the computer would be personal. It's kind of strange to think that, now in 2026, it has taken circa 40 years for this to actually become true. You see, over the last 40 years,…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "the craft has been commoditized, but access has not",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-10-02-the-craft-has-been-commoditized-but-access-has-not/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>This is the eighteen-month recap: the talk I gave on day two of AI Engineer Singapore. A lot has happened since the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/six-month-recap/\">six-month recap</a> in Melbourne. The recording is below, followed by an edited transcript with the slides.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=m12vGjfbNlo\">AI Engineer Singapore, Day 2</a></p>\n<blockquote>\n<p>Welcome back. For those who were at the party here last night, he actually came on for a couple of sets and DJed as well. So who is Geoffrey Huntley?</p>\n<p>He's an independent AI researcher known for doing unhinged things with AI. He's the person behind the Ralph loop, which is now incorporated in many, many tools that are used today.</p>\n</blockquote>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ralph/\">Ralph Wiggum as a &quot;software engineer&quot;</a></p>\n<p>How Ralph Wiggum went from 'The Simpsons' to the biggest name in AI right now - Venture Beat 😎Here's a cool little field report from a Y Combinator hackathon event where they put Ralph Wiggum to the test. &quot;We Put a Coding Agent in a While Loop and It Shipped 6 Repos Overnight&quot; <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/\">https://github.com/</a></p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2025/06/3ea367ed-cae3-454a-840f-134531dea1fd.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/09/aie-sg-2026-001.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Hello everyone. As confident as I might seem about these topics, I must say this is quite a provocative title. I don't know. So when you're listening to this, I want you to reflect upon it. Maybe I'm right, maybe I'm wrong.</p>\n<p>It's a provocative title because I'm saying that software development now costs less than minimum wage. There was a time when, if you wanted to do photography, you had to buy specialized tools. But now everyone's got an iPhone, and everyone's a photographer. Think about that. Things have changed.</p>\n<p>With that disclaimer out of the way: I do not work for anyone. I am completely independent. I do not represent anyone. So this is going to get spicy. Let's do it animal style.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/09/aie-sg-2026-animal-style.jpg\" alt=\"Geoff wearing the In-N-Out hat\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/real/\">Software development now costs less than than the wage of a minimum wage worker</a></p>\n<p>Hey folks, the last year I've been pondering about this and doing game theory around the discovery of Ralph, how good the models are getting and how that's going to intersect with society. What follows is a cold, stark write-up of how I think it's going to go down. The financial impacts are already</p>\n<p>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/01/Symbolic-traditional-tattoo-art-print-of-the-invention-of-the-shipping-container--presented-with-an-ethereal-spiritual-vibe-in-an-intense-jet-black-wet-rainy-scene--adorned-with-vibrant-rose-tattoo-colors--retro.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/09/aie-sg-2026-002.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>It's been roughly a year and a half since I published the technique of allocating memory in a particular way. If you wrap the tool calls around another loop, it's just a loop. But there's a lot of science in the context engineering needed to actually achieve these outcomes, and it's quite disruptive. Here I was giving this talk about how everything has changed, and this was a week before Atlassian did their layoffs.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/09/aie-sg-2026-003.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Oops. You see, the unit economics of business have forever changed. I want you to really understand how big this is. If you do not believe this is true, you need to stop speaking with other developers. You need to speak with founders. You need to speak with business leaders. You need to get a little more curious about what this means and get ahead of what this means for business.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/09/aie-sg-2026-004.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>What does it mean when everyone is a software developer? For no particular reason at all, Cursor was at the same meetup. This isn't a plug for Cursor, but I want to call something out at this meetup. Here's Roslyn, and there were other people like Roslyn. They're designers. They're product managers. And they're having the time of their damn lives. There weren't any software engineers up there giving talks.</p>\n<p>That's because they're now being enabled to become software developers. For the first time ever, it's like an iPhone in their hands. They can just get stuff done. They can take photos. They can develop software. Whatever is in their wildest dreams, they can do.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/09/aie-sg-2026-005.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I've been traveling around the world for the last three months. I think I've given this talk 17 times now in different cities, including Auckland. In Auckland, I decided to go on a side quest to Hobbiton from The Lord of the Rings.</p>\n<blockquote>\n<p>My tour guide asked, &quot;Geoff, what do you do?&quot; and I'm like, &quot;I do AI. Please don't judge me.&quot; Next thing you know, his eyes lit up, and he goes, &quot;Geoff, how good is AI? How good is AI?&quot;</p>\n</blockquote>\n<p>What does it mean when your tour guide is token-maxing?</p>\n",
      "date_modified": "2026-09-27T08:34:40+00:00",
      "date_published": "2026-09-27T08:34:40+00:00",
      "external_url": "https://ghuntley.com/eighteen-month-recap/",
      "id": "urn:aggr:item:cf54fac01f92b755256ce3132f542ad3371140d3",
      "summary": "This is the eighteen-month recap: the talk I gave on day two of AI Engineer Singapore. A lot has happened since the six-month recap in Melbourne. The recording is below, followed by an edited transcript with the slides. Welcome back. For…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "the eighteen-month recap: AI Engineer, Singapore, May 2026",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-09-27-the-eighteen-month-recap-ai-engineer-singapore-may-2026/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>🎉</p>\n<p>It's been a busy six months, that's for sure. I'm not going to bury the lede here; the short TLDR is I'm joining the folks over at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://antithesis.com/?utm_source=ghuntley\">https://antithesis.com/</a>.</p>\n<hr />\n<p>If I <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/oh-fuck\">wind back time to November 2024</a>, it was apparent to me back then that our profession would change. To be frank, in the last six months our profession has changed more than it has in the last 30 years. Software authoring has been commoditised. Everyone is now a software developer, but being a software developer does not mean that they're an engineer.</p>\n<p>The word engineer <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/squirrel-burgers/\">is used trivially in our profession</a>, but in other industries the word engineer means failures are unacceptable.</p>\n<p>Now I'm a little bit old and crusty these days; I turn 44 next week, and I've seen some absolutely horrible codebases, but if I'm to be honest, I can remember some of the first code that I wrote, and I have regrets. If you caught my talk at the AI Engineer World Fair, one of the things I shared was some deep concerns that we are entering into another Eternal September. You see, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/screwed/\">we didn't create enough software engineers after the 2000s dot-com implosion</a> to properly support an apprenticeship model of learning in our industry.</p>\n<p>It's now twenty-six years since that event, and now that everyone can create software, we've got some hard questions to solve. But whilst many things have changed, the job of software engineers is to produce experiences without defects.</p>\n<p>So I've been pondering how we are going to fix this predicament.</p>\n<p>Here's my hypothesis:</p>\n<ol>\n<li>The discipline/techniques of formal verification and deterministic system testing are about to cross the chasm. There's a whole lot of brownfield software out there that's been written over the last 30 years that is being affected by the <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=eIoohUmYpGI&amp;ref=ghuntley.com\">infinite software crisis</a> (“how do we do code review now?” / “the volume of code/change is too high”) all at once.</li>\n<li>Not enough skilled practitioners in the discipline/techniques of formal verification and deterministic system testing exist.</li>\n<li>Whilst the costs of building a simulator for a project (new or retrofitting an existing project) are significantly cheaper now, there are entire categories and classes of problems that will not surface unless you emulate a deterministic computer (which provides a forceful way to make <em>anything</em> deterministic).</li>\n<li>Antithesis, when used in conjunction with adversarial code reviews by an LLM and with <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/pressure/\">language analyzers driven by pre-commit hooks</a>, will be a key component in software factories that enables people/agents to deliver reliable software without the burden of having to learn this specialized knowledge.</li>\n</ol>\n<p>Creation is now near-free. Verification/understanding is not, yet. It's time to engineer away the slop.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://antithesis.com/blog/sdtalk/?utm_source=ghuntley\">How Antithesis finds bugs (with help from the Super Mario Bros.) | Antithesis</a></p>\n<p>Can solving Super Mario Bros. help solve your distributed systems issues?</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-29c86fea-4d88-4df2-aed6-6e51e7e8b9b7.svg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Antithesis Will Wilson Co-founder &amp; CEO</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/snoutyplays.DX648_wc_ZAzB9t-cbb49132-0709-4d0a-8bb5-9b8d003e8c57.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=zc4cqtibTzs\">Testing a single-node, single threaded, distributed system written in 1985</a></p>\n",
      "date_modified": "2026-07-23T16:40:16+00:00",
      "date_published": "2026-07-23T16:40:16+00:00",
      "external_url": "https://ghuntley.com/slop/",
      "id": "urn:aggr:item:d26b43ac65c9271842c5a405dfb8bdb1e3bae257",
      "summary": "🎉 It's been a busy six months, that's for sure. I'm not going to bury the lede here; the short TLDR is I'm joining the folks over at https://antithesis.com/. If I wind back time to November 2024, it was apparent",
      "tags": [
        "programming"
      ],
      "title": "engineer away the slop",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-07-23-engineer-away-the-slop/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>By <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/author/ghuntley/\">Geoffrey Huntley</a> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/tag/ai/\">AI</a> — 27 Jun 2026</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2000/2026/06/download.jpeg\" alt=\"A couple of months ago in Miami, I sat down and dumped my brains. Here&#39;s the interview...\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Some personal hot takes from AI: Engineer Miami follows...</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=fbqAh46eMkc\">Hot-takes at a fireside chat during AI:Engineer Miami</a></p>\n<p>1. Software development is a dead-end profession because anyone can be a software developer now.</p>\n<p>2. Anyone can use Cursor or any other tool and generate code. Being a coder and being a software engineer are different.</p>\n<p>3. Computers used to be gated; now everyone has the power to make computers malleable. Everyone is a software developer now, but that does not mean they are software engineers</p>\n<p>4. If you cannot demonstrate how a coding agent works, you are just a consumer and have imposed an artificial glass ceiling on your career as a software engineer.</p>\n<p>5. If you are curious, you will have a job. If you have not been curious in the last two years, you are replaceable.</p>\n<p>6. SaaS per-seat economics may become unstable as customers need fewer people to achieve results, prompting founders to think about new unit economics</p>\n<p>7. Most companies will take two or three years (or more!) to figure out AI transformation.</p>\n<p>8. Some companies are already building AI native teams of five to ten people who can build with the grain of AI</p>\n<p>9. There will be an explosion in the number of software developers. Software development is now essentially free, and tokens are cheaper than humans</p>\n<p>10. Not enough engineers know what it means to be a product engineer</p>\n<p>11. JIRA ticket monkeys are cooked</p>\n<p>12. If your company has banned AI, you should quit that company</p>\n<p>13. AI is more like a musical instrument than just a tool. Play with it, make discoveries, build intuition, learn where AI is good and where it fails</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/play/\">deliberate intentional practice</a></p>\n<p>Something I’ve been wondering about for a really long time is, essentially, why do people say AI doesn’t work for them? What do they mean when they say that? From which identity are they coming from? Are they coming from the perspective of an engineer with a job</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--ac5f76ff-d94f-488a-9e1b-3c4d4f7cfabc.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/A-vibrant-retro-style-traditional-tattoo-art-print-featuring-a-guitar--rendered-with-high-contrast-and-dramatic-lighting.-The-complex-ornamental-design-is-set-against-a-stark-white-background--showcasing-intense-color-saturation-and-a-symbo-cd101376-214a-4f32-8bd3-8e4d635e773d.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<h3>p.p.s don't miss out on free lifetime access</h3>\n<p>Join thousands getting premium insights delivered weekly. <strong>Subscribe now and you'll never pay</strong> - even when I start charging new subscribers. This free-for-life offer won't last forever.</p>\n",
      "date_modified": "2026-06-26T21:01:22+00:00",
      "date_published": "2026-06-26T21:01:22+00:00",
      "external_url": "https://ghuntley.com/miami/",
      "id": "urn:aggr:item:49b4c85d7e4daf26ec1dedacc44d6e72b62e09a6",
      "summary": "Some personal hot takes from AI: Engineer Miami follows... 1. Software development is a dead-end profession because anyone can be a software developer now. 2. Anyone can use Cursor or any other tool and generate code. Being a coder and…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "A couple of months ago in Miami, I sat down and dumped my brains. Here's the interview...",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-06-26-a-couple-of-months-ago-in-miami-i-sat-down-and-dumped-my/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>By <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/author/ghuntley/\">Geoffrey Huntley</a> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/tag/activism/\">Activism</a> — 18 May 2026</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2000/2026/05/HIks4iMbQAA2hp0.jpg\" alt=\"the aussie gov just screwed startup founders. my musings.\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<h3>p.p.s don't miss out on free lifetime access</h3>\n<p>Join thousands getting premium insights delivered weekly. <strong>Subscribe now and you'll never pay</strong> - even when I start charging new subscribers. This free-for-life offer won't last forever.</p>\n",
      "date_modified": "2026-05-18T04:33:19+00:00",
      "date_published": "2026-05-18T04:33:19+00:00",
      "external_url": "https://ghuntley.com/livid/",
      "id": "urn:aggr:item:33a4a841560bcbd40627fe664b60e803b0c2ca55",
      "summary": "By Geoffrey Huntley in Activism — 18 May 2026 p.p.s don't miss out on free lifetime access Join thousands getting premium insights delivered weekly. Subscribe now and you'll never pay - even when I start charging new subscribers. This…",
      "tags": [
        "programming",
        "activism"
      ],
      "title": "the aussie gov just screwed startup founders. my musings.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-05-18-the-aussie-gov-just-screwed-startup-founders-my-musings/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>This is a follow-up from my previous post about AI as an economic weapon. If you haven't read it, I suggest that you do before proceeding.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/warfare/\">AI as economic warfare</a></p>\n<p>People often ask me how I feel about open-source models, and to be clear, I’m very supportive of them. But I can’t help pondering about the following... Open source always was and always will be a financial weapon by design. You see, one of the primary goals of open source</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--8.jpg\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/download--2--6.jpeg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>I closed that post with the following, and we're going to expand on it:</p>\n<blockquote>\n<p>The real question, however, is trust. I'm not saying that the Chinese models are dodgy. It's more of a meta question. You see, the question of trust extends to the frontier labs as well. As we enter this weird new space where businesses are being automated with AI, it essentially hands over your business's operations to another entity.</p>\n<p>Another question on my mind is what happens to a country that lacks AI capabilities? When their businesses depend upon AI, and thus the country's economy depends upon AI, what happens if the spigot ever gets turned off through sanctions or war?</p>\n</blockquote>\n<p>If we zoom forward a couple of years. It's now the future, and the future is undefined because no one really knows what it will look like, because it is the future, but if we play with the notion of extrapolating trends that are just starting right now, where founders, including myself, are building businesses with a mindset of autonomous software and product factories. We will soon be in a place where businesses are highly dependent upon the capabilities of AI, whether that be in access or how the models function.</p>\n<p>This concerns me greatly, and it extends far beyond business and into society itself. You see, right now, society is already going through a Harry Potter-style sorting hat event where people are picking and choosing which tribe they belong to.</p>\n<p>If you use any of the Frontier Lab models enough, you develop an eye for their tendencies, how they write, how they think, and how they communicate. If people are picking a single AI producer and using that AI daily in their day-to-day life to make decisions, they are outsourcing their cognitive security to someone else.</p>\n<p>What concerns me is that, almost three or four years ago, Anthropic conducted research that allowed Frontier Labs to perform laparoscopic keyhole surgery to change how the models perform after they were made. This experiment was called Golden Gate Claude.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.anthropic.com/news/golden-gate-claude?ref=ghuntley.com\">Golden Gate Claude</a></p>\n<p>When we turn up the strength of the “Golden Gate Bridge” feature, Claude’s responses begin to focus on the Golden Gate Bridge. For a short time, we’re making this model available for everyone to interact with.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/9a1138d1b0a06a866223c329e6df8cfd6ae502c4-2400x1260.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>In this experiment, Anthropic performed surgery on the model's weight dimensions for the Golden Gate Bridge and no matter what you did when you were having a conversation with this model, the Golden Gate Bridge was always top of mind for the model.</p>\n<p>For example, let's say that you wanted to go get some Panadol. It would give you driving instructions to a pharmacy via the Golden Gate Bridge. If you wanted to write a poem, that poem would prominently feature the Golden Gate Bridge.</p>\n<p>Through modification of the model weights, the Golden Gate Bridge became a black hole where you could not escape from the gravity of the Golden Gate Bridge.</p>\n<blockquote>\n<p>Scaling Monosemanticity: Extracting Interpretable Features from Claude 3 Sonnet: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://transformer-circuits.pub/2024/scaling-monosemanticity/index.html?ref=ghuntley.com\">https://transformer-circuits.pub/2024/scaling-monosemanticity/index.html</a></p>\n</blockquote>\n<p>I'm surprised most people don't even know that this research exists and haven't really talked about or even written about what it could mean for society in the future.</p>\n<p>Here's a scenario for you to chew on:</p>\n<p>What happens when, in a couple of years, if a famous web search company, which was also a frontier AI lab, retires ads in their search product and instead offers their advertisers the ability to bid on the ability to rank higher in model weights than the competitors?</p>\n<blockquote>\n<p>Most people would never know because they've outsourced their cognitive capability to a model.</p>\n</blockquote>\n<p>What happens is if a famous social media network, which is also a Frontier lab, starts allowing their advertisers, to similarly bid to rank higher in the model weights, of their open source models that they're releasing for free.</p>\n<p>Now, what happens if you extrapolate this? I don't know if this will actually happen. It's just baseless speculation, but one thing is for sure: we're entering into this world where a select few companies, these frontier labs, will have significant power over the world and how society functions, thinks and operates.</p>\n<p>If these topics concern you, then perhaps the only true solution is that you should raise your own model, because by doing so, you gain the ability to protect your own cognitive security, business operations and supply chain.</p>\n",
      "date_modified": "2026-03-16T21:31:14+00:00",
      "date_published": "2026-03-16T21:31:14+00:00",
      "external_url": "https://ghuntley.com/cogsec/",
      "id": "urn:aggr:item:5abed4c2663ac2cbe0385fbe079851be7b05229f",
      "summary": "This is a follow-up from my previous post about AI as an economic weapon. If you haven't read it, I suggest that you do before proceeding. AI as economic warfare People often ask me how I feel about open-source models, and to be clear, I’",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "cognitive security",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-03-16-cognitive-security/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>People often ask me how I feel about open-source models, and to be clear, I'm very supportive of them. But I can't help pondering about the following...</p>\n<blockquote>\n<p>Open source always was and always will be a financial weapon by design. You see, one of the primary goals of open source was by releasing something as free, it removes the ability to make money from it.</p>\n</blockquote>\n<p>Now, I'm not sure how old you are, dear reader, but if you wind the clock back far enough, you'll find traces in history that support this claim. Heck, you're probably even using Linux right now on a computer, in your house or at a server in a data centre. This was not always true. Back when this war was last raging, back in 1998, Windows was the server operating system of choice.</p>\n<p>Linux was created to destroy Microsoft's ability to make money from Microsoft Windows. The same holds true for OpenOffice vs. Microsoft Office. It's now almost 20 years since the Halloween papers. If you're not familiar with the topic, I suggest you dig in and get up to speed with the subject matter.</p>\n<blockquote>\n<p>In the last week of October 1998, a confidential Microsoft memorandum on Redmond's strategy against Linux and Open Source software was leaked to me by a source who shall remain nameless. I annotated this memorandum with explanation and commentary over Halloween Weekend and released it to the national press. Microsoft was forced to acknowledge its authenticity. The press rightly treated it as a major story and covered it (with varying degrees of cluefulness).<br />\n- <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://en.wikipedia.org/wiki/Halloween_documents?ref=ghuntley.com\">https://en.wikipedia.org/wiki/Halloween_documents</a></p>\n</blockquote>\n<p>Now you might be wondering why I'm writing about this. It's because local models are getting good. Heck, local models these days tend to be two to four months behind the leading-edge frontier labs.</p>\n<p>Here's the thing, though: these local models are being released for free. You can just download them, or pay a minuscule fee (circa $5 USD/month) to access Frontier's open-source models from Alibaba or Z.AI.</p>\n<p>Meanwhile, America is dumping literally trillions of dollars into research at these frontier labs. Now, I'm not calling AI a bubble because this absolutely is ROI. At this stage, I think it's impossible for anyone to say it is a bubble.</p>\n<p>What I hope to do through this blog post is tweak some people's thinking beyond the bubble narrative. Perhaps what we're seeing is history repeating itself, but perhaps it's a little more sinister. Now, my background is not in geopolitics. I can't help but wonder if the US economy backs itself so hard into a corner funding these research labs, and if these research labs receive a bailout, what does that mean for China? Why is China releasing these models for free?</p>\n<p>Perhaps what we're seeing here is all-out economic warfare between one nation-state and another through the weaponisation of open source because open source was, is, and always will be a financial weapon. In history, free was previously used against companies, but, if my speculation is on the mark, this is the first time it has been used at the national level by one nation against another.</p>\n<p>I don't know what this means, and I'll leave the commentary, whether true or false, to someone with expertise in this arena but if you're aware that this is happening, then there are many ways where you can benefit from what is happening.</p>\n<p>If you are a student or your financial budget does not allow for dropping $1,000 a month for subscriptions from all the major labs, then you can use these open-source models.</p>\n<p>If you're a business, you should build with the mindset that local inferencing will be a thing. I suspect that in a not-so-distant future, we will have local models where society has full visibility into what goes into their training data sets, truly open-source models that are end-to-end reproducible, and I'm excited about these possibilities.</p>\n<p>The real question, however, is trust. I'm not saying that the Chinese models are dodgy. It's more of a meta question. You see, the question of trust extends to the frontier labs as well. As we enter this weird new space where businesses are being automated with AI, it essentially hands over your business's operations to another entity.</p>\n<p>Another question on my mind is what happens to a country that lacks AI capabilities? When their businesses depend upon AI, and thus the country's economy depends upon AI, what happens if the spigot ever gets turned off through sanctions or war?</p>\n",
      "date_modified": "2026-03-16T20:47:11+00:00",
      "date_published": "2026-03-16T20:47:11+00:00",
      "external_url": "https://ghuntley.com/warfare/",
      "id": "urn:aggr:item:661fbe09c21f25568ce9e0b04d9f5296b3716adf",
      "summary": "People often ask me how I feel about open-source models, and to be clear, I'm very supportive of them. But I can't help pondering about the following... Open source always was and always will be a financial weapon by design. You see, one…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "AI as economic warfare",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-03-16-ai-as-economic-warfare/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>By <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/author/ghuntley/\">Geoffrey Huntley</a> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/tag/ai/\">AI</a> — 15 Mar 2026</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2000/2026/03/IMG_1831.jpeg\" alt=\"porting software has been trivial for a while now. here’s how you do it.\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This one is short and sweet. if you want to port a codebase from one language to another here’s the approach:</p>\n<ol>\n<li>Run a ralph loop which compresses all tests into /specs/<em>.md which looks similar to “study every file in tests/</em>* using separate subagents and document in /specs/*.md and link the implementation as citations in the specification“</li>\n<li>Then do a separate Ralph loop for all product functionality - ensuring there’s citations to the specification. “study every file in src/* using seperate subagents per file and link the implementation as citations in the specification“</li>\n<li>Once you have that - within the same repo run a Ralph loop to create a TODO file and then execute a classic ralph - doing just one thing and the most important thing per loop. Remind the agent that it can study the specifications and follow the citations to reference source code.</li>\n<li>For best outcomes you wanna configure your target language to have strict compilation</li>\n</ol>\n<p>The key theory here is usage of citations in the specifications which tease the file_read tool to study the original implementation during stage 3. Reducing stage 1 and stage 2 to specs is the precursor which transforms a code base into high level PRDs without coupling the implementation from the source language.</p>\n<h3>p.p.s don't miss out on free lifetime access</h3>\n<p>Join thousands getting premium insights delivered weekly. <strong>Subscribe now and you'll never pay</strong> - even when I start charging new subscribers. This free-for-life offer won't last forever.</p>\n",
      "date_modified": "2026-03-15T10:02:33+00:00",
      "date_published": "2026-03-15T10:02:33+00:00",
      "external_url": "https://ghuntley.com/porting/",
      "id": "urn:aggr:item:19ce3f1a8a2a6898d3e579019c24a3a1f446f4d5",
      "summary": "This one is short and sweet. if you want to port a codebase from one language to another here’s the approach: Run a ralph loop which compresses all tests into /specs/.md which looks similar to “study every file in tests/* using separate…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "porting software has been trivial for a while now. here’s how you do it.",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-03-15-porting-software-has-been-trivial-for-a-while-now-here-s/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>By <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/author/ghuntley/\">Geoffrey Huntley</a> in <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/tag/ai/\">AI</a> — 13 Mar 2026</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2000/2026/03/download--1-.jpeg\" alt=\"A couple of days ago, I sat down with Vivek Bharathi and dumped my brains. Here&#39;s the interview...\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>0:00</p>\n<p>/11:14</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/03/AI-Expert--30----Rationalizing--Business-Moat-and--technical-Talent-for--agenticai-era--RIs6wikZykI-_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Below you'll find an AI transcription of everything we riffed about.</p>\n<p>Key distinction: Software Development vs. Software Engineering:</p>\n<ul>\n<li>Software development (typing code, prompting LLMs) is accelerating massively and becoming ubiquitous—anyone (e.g., a hairdresser using Cursor) can now be a &quot;developer&quot; due to abundant AI knowledge/tools.\\</li>\n<li>Software engineering remains essential and is evolving: engineers now act like locomotive engineers — keeping the &quot;train&quot; on tracks by designing safe, reliable systems/automations rather than working &quot;in&quot; the business (manual coding).\\</li>\n<li>Shift focus to designing loops, automations, safety mechanisms (e.g., sandboxing, credential management, security), risk engineering, and responsible AI utilization.</li>\n</ul>\n<h2>Implications for professionals:</h2>\n<ul>\n<li>If your identity is tied to being a traditional &quot;software developer&quot; (keyboard typing), it's a tough time—prompting for outcomes is the new norm.</li>\n<li>If your employer bans AI tools, leave immediately: it's business suicide to ignore AI, while staying risks employability suicide as the market for manual coders shrinks rapidly.</li>\n<li>Engineers should prioritize raw technical/cognitive skills → engineer away concerns (e.g., replace binary code reviews with risk-based approaches, feature flags, constrained blast radius, auto-migrations).</li>\n</ul>\n<h2>Open source is &quot;dead&quot; (or greatly diminished):</h2>\n<ul>\n<li>Traditional open-source libraries existed to ease hiring and sharing reusable code.</li>\n<li>Now, with AI generation, there's little point: generating code avoids maintainer burnout, GitHub issue delays, abandoned projects, supply-chain attacks (e.g., npm takeovers), and Dependabot update toil.</li>\n<li>Better to generate first-party code for faster evolution, full control, and no human &quot;tool calls&quot; (which disqualifies true AGI-like autonomy).</li>\n<li>Exceptions: highly sensitive areas like PKI/SSL where generation isn't appropriate.</li>\n</ul>\n<h2>Broader industry shifts in an abundance era:</h2>\n<ul>\n<li>Software moves from scarcity (differentiated libraries, hard-to-replicate tech) to abundance (easy generation/reimplementation).\\</li>\n<li>Many software products become hyper-commodity (like utilities: electricity, web hosting) — easily screenshot + reimplemented via AI (e.g., Claude).</li>\n</ul>\n<h3>Vendor lock-in and switching costs vanish (e.g., auto-migrating databases/apps).</h3>\n<ul>\n<li>True moats now lie in non-technical areas: contracts, relationships, handshakes, stakes, distribution, taste/judgment — the &quot;hard things of business.&quot;</li>\n<li>Unit economics of software have fundamentally changed → questions if software remains investable (VCs unsure about moats, fundraising challenges).</li>\n</ul>\n<blockquote>\n<p>Future: hyper-personalized software; old models of building/scaling via scarcity are disrupted.</p>\n</blockquote>\n<h3>Closing advice</h3>\n<ul>\n<li>Stay relevant by running fast, staying curious, and adapting to the &quot;brave new world.&quot;</li>\n</ul>\n<p>ps. this interview is also available:</p>\n<ul>\n<li>on youtube at <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=SMVyUu-GTpU&amp;ref=ghuntley.com\">https://www.youtube.com/watch?v=SMVyUu-GTpU</a></li>\n<li>X - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2032163849067987280?ref=ghuntley.com\">https://x.com/GeoffreyHuntley/status/2032163849067987280</a></li>\n<li>LinkedIn - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.linkedin.com/posts/geoffreyhuntley_a-couple-of-days-ago-i-sat-down-with-vivek-activity-7437931906714791938-4_75?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAABQKuUB2AJ059keUcRUVLbtmoa6miLVlTI\">https://www.linkedin.com/posts/geoffreyhuntley_a-couple-of-days-ago-i-sat-down-with-vivek-activity-7437931906714791938-4_75</a></li>\n</ul>\n<h3>p.p.s don't miss out on free lifetime access</h3>\n<p>Join thousands getting premium insights delivered weekly. <strong>Subscribe now and you'll never pay</strong> - even when I start charging new subscribers. This free-for-life offer won't last forever.</p>\n",
      "date_modified": "2026-03-12T18:55:07+00:00",
      "date_published": "2026-03-12T18:55:07+00:00",
      "external_url": "https://ghuntley.com/frontier/",
      "id": "urn:aggr:item:bf4115b22a73c37a1c766ed3493cf79a795dba81",
      "summary": "Below you'll find an AI transcription of everything we riffed about. Key distinction: Software Development vs. Software Engineering: Software development (typing code, prompting LLMs) is accelerating massively and becoming…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "A couple of days ago, I sat down with Vivek Bharathi and dumped my brains. Here's the interview...",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-03-12-a-couple-of-days-ago-i-sat-down-with-vivek-bharathi-and/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>Hey folks, I'm currently over in SF. For the last couple of weeks, I've been cryptically tweeting about a hidden mode within something I've been building on called Latent Patterns (see below), and over the last couple of days, I've started opening up and showing people that I suspect is the (or a) future of what's to come.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://latentpatterns.com/?ref=ghuntley.com\">Latent Patterns — Learn AI, from the inside out</a></p>\n<p>Screencasts and technical guides on AI for developers. Understand transformers, attention, embeddings, and more.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-1.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Latent Patterns Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/og-default-1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>An educational platform for learning AI concepts. No fluff, no filler. Just the concepts you need, explained clearly.</p>\n<p>Latent Patterns builds Latent patterns. I've taken some of the ideas behind &quot;<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=zX_Wq9wAyxI&amp;ref=ghuntley.com\">The Weaving Loom</a>&quot; and inverted them, put them into the product itself and have perhaps accidentally created a better Lovable.</p>\n<p>It's interesting because I see all these developer tooling companies building for the persona of developers, but to me, that persona no longer exists. You see, within latent patterns, the product (latent patterns) is now the IDE.</p>\n<p>0:00</p>\n<p>/0:33</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/03/CleanShot-2026-03-08-at-07.38.37_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>If I want to make a change to something, I pop on designer mode, and this allows me to develop LP in LP. I can make changes to the copy or completely change the application's functionality using the designer substrate directly from within the product, then click the launch agent to ship.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>If I click Launch Agent, then it utilises Cursor's new Cloud Agents and Workflow Automations to ship it straight into production using a risk-based approach.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-2.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>I guess you're wondering right now why I would not have my own agents for code editing? Well, that's because they're commodities now. Last month, Cursor hooked me up with a preview of their new stuff, and now that it's out, this is how I've been using it. You could do this with any background execution utility service.</figcaption></figure>\n<p>Instead of having a manual code review for everything, I just ship it. If something is high enough on the risk matrix, for example, a database schema migration, then it halts the shipping, and I have to do a manual review. Having said that, I'll repeat something I've said again and again over the years. You need to watch the loops. Watch the inferencing because that's where your learning is at. When I want something built, I just open up my phone and watch the output get made. I'm supervising it. I'm on the loop, not in the loop.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-3.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>Here's what the prompt roughly looks like. It depends on what the functionality has been changed, whether it's a content change or an actual application logic change.</figcaption></figure>\n<p>I think we're entering into an era of hyper-personalised software, and our industry actually works in circles. The last time we had hyper-personalised software for business was Microsoft Access, Delphi and Visual Basic. You see, back in the year 2000, every business had hyper-personalised software.</p>\n<p>They didn't have to bend or conform to someone else's product vision on how they should operate their business. They didn't need Zapier or all these workflow automation systems stitching together SaaS. No, they had rapid application development, and these businesses had hyper-personalised software.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-4.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>So I've been playing around in this designer within LP, and I've got a rough technical prototype for how I might retire most developer practices, including CI/CD.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-5.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>One thing that is irking me is how natural it seems for everyone to accept that we should wait until we see the outcome. This never used to be the case. Productivity with Microsoft Access back in 2000 was amazing.</p>\n<p>Every second counts; even the 60 seconds for CI/CD deployments for LP, as it is now, is too long. So I'm starting to come to an understanding that the natural next step is to live-edit a program's memory and control flow. Sure, I could move content from the file system to the database, but we can do better. How can we kill CI/CD as it is today and instead safely live-edit the program's logic?</p>\n<blockquote>\n<p>If you build with the mindset and awareness that inferencing speed will be near-instantaneous in the future, then it just makes sense that the logical destination is for anyone to be able to develop the product from within the product, and for the product to become the IDE itself.</p>\n</blockquote>\n<p>All businesses need the following &quot;widgets&quot; / components:</p>\n<ul>\n<li>Analytics</li>\n<li>CRM</li>\n<li>Support Desk</li>\n<li>Newsletters</li>\n<li>Meeting Scheduling</li>\n</ul>\n<p>So, for the last couple of weeks, I've been doing some window shopping...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-7.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>So the first thing I did was model the notion of a user and add customer management functionality. Consider how long it would take in traditional software developer to build such functionality. A very simple user management database with a front end. Before AI, this would have taken weeks at most corporations. Before our industry went backwards, this used to take seconds. Back in the year 2000, it used to be seconds. This used to be just Microsoft Access tables.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-8.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>So let's pull up my own customer record and have a look at what's inside.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-9.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Seems pretty from vanilla, right? But do you notice the acquisition section? latentpatterns.com has first-party analytics built in and is horizontally and vertically integrated throughout the platform. To do this, I literally just ripped a fart into my coding harness and said,</p>\n<blockquote>\n<p>&quot;Hey, I want PostHog. Make it happen&quot;.</p>\n</blockquote>\n<p>The 'coming-soon' UTM is my landing page. You see, LP has not launched <em>yet</em>. I'm building it out in the open and hitting the pavement in San Francisco, New York, and around the world to validate the business case and am doing steak-and-handshake deals to shape the product through conversations with prospective customers. Doing all the unscalable things. Instead of doing LLM outreach and sales automation that way, I'm doing it the old-fashioned way.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-10.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Once someone signs up via LinkedIn or provides information in the three fields above, they get registered as a customer within the database. That might seem quite vanilla, but it's anything but.</p>\n<p>Through the usage of PDL, I can automatically step up who they are, where they work, any achievements they've had in life, and insights such as their likely salary or whether they have decision-making power to purchase. When you take this information and you throw it into a perplexity search, you get this...</p>\n<p>0:00</p>\n<p>/0:06</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/media/2026/03/CleanShot-2026-03-08-at-08.15.17_thumb.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This is baseline functionality that every business needs, and it needs to be first-party within their application. By having all this first-party data in my data tables, I can then layer agents on top of it to automatically prioritise my day via an agentic personal assistant.</p>\n<p>The next thing every business needs is a support desk and a customer relationship management tool. Classically, in most companies today, these are two separate things, and you have to build workflow automations to keep them in sync. No. In LP, they are a first-party thing, and they were built by ripping another fart into my coding agent, asking for</p>\n<blockquote>\n<p>&quot;Hey, I want PipeDrive, Trello, and ZenDesk&quot;</p>\n</blockquote>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-11.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>On top of every customer interaction, the analysis is top and centre. It is deliberately there because it forces me to read this information again before I interact with the customer. This information is automatically refreshed by a background job every night.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-12.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Underneath this summary, for similar reasons, is also another summary of all the activity this person has done if they're in my Discord community (below)</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://latentpatterns.com/discord?ref=ghuntley.com\">Join the Latent Patterns Discord Server!</a></p>\n<p>An educational platform for learning AI concepts. No fluff, no filler. Just the concepts you need, explained clearly. | 784 members</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://static.ghost.org/v5.0.0/images/link-icon.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Discord</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/dced5af7e6b73db279e801a9f458f18b.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-13.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Then, finally, before I even get to the support desk ticket, I have to scroll past and review all the meetings I've had with the person. You see, beans, beans, the magical fruits, the more you eat, the more you toot. So ripped <em>another</em> fart into my coding harness, and I asked it to clone Calendly...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-14.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Throughout the website, various marketing funnels generate support desk tickets and offer the option to meet with me.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-15.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The calendar integration does exactly what you think it does, but with some twists. You see, the beans just keep on producing brain farts, so I prompted my way to victory and made my very own meeting transcription bot that automatically joins these meetings and asks for consent to take notes and record the meeting.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-16.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-17.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>At the end of the meeting, I rip an agent over the transcription and apply sales automation using a mixture of Challenger-based sales and SPIN Selling as a series of LLM prompts. You see, in a previous life, I was also a sales engineer. Items captured include:</p>\n<ul>\n<li>Competitive Landscape</li>\n<li>Budget &amp; Approval Process</li>\n<li>Seat Sizing &amp; Expansion Potential</li>\n<li>Reseller &amp; Training Partner Potential</li>\n<li>Signals &amp; Sentiment</li>\n<li>Buying signals</li>\n<li>Champion indicators</li>\n<li>Rapport notes</li>\n<li>Information Gaps</li>\n<li>Decisions Made</li>\n<li>Follow-Up Items</li>\n<li>Product Demo (What was shown, Questions They Asked)</li>\n<li>Content Interest &amp; Feature Requests</li>\n<li>Perception of the product demo</li>\n<li>Pain Points &amp; Needs</li>\n</ul>\n<p>From there, it's just not so easy, but it's a skill that you can learn. Shut up and become curious. When someone says something, just ask why they said it.</p>\n<p>All you need to do is get folks talking, and the more they share about their needs and pain points, the more information the LLM prompts can process. The more data you can gather, the more effective the follow-up meetings, especially if it's an initial meeting. And with that data, you can then rip an agent over the top of it to do more business automation.</p>\n<p>Thanks for reading, folks. I hope you enjoyed this sneak preview. I'm going all in and building an educational platform. I'm living, breathing, and teaching what it means to be a model-first company. I'm building with recursive latent space, teaching it from my experiences as a one-man company.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/papercuts\">llm weights vs the papercuts of corporate</a></p>\n<p>In woodworking, there’s a saying that you should work with the grain, not against the grain and I’ve been thinking about how this concept may apply to large language models. These large language models are built by training on existing data. This data forms the backbone which creates output based</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--7.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/universal_upscale_0_6a2d76dd-41e0-42a4-8529-bf43d0280256_0-3.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>just in case you missed my previous article about the unhinged things that you can now do as a model first company and why AI adoption will be a problem for corporates.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/real\">Software development now costs less than than the wage of a minimum wage worker</a></p>\n<p>Hey folks, the last year I’ve been pondering about this and doing game theory around the discovery of Ralph, how good the models are getting and how that’s going to intersect with society. What follows is a cold, stark write-up of how I think it’s going to go down. The</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--6.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/Symbolic-traditional-tattoo-art-print-of-the-invention-of-the-shipping-container--presented-with-an-ethereal-spiritual-vibe-in-an-intense-jet-black-wet-rainy-scene--adorned-with-vibrant-rose-tattoo-colors--retro.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>why I think now is the perfect time to build.</p>\n<p>Latent Patterns is an educational platform for learning AI concepts. No fluff, no filler. Just the concepts you need, explained clearly.</p>\n<p>I will be launching shortly. If you want to know when I launch, leave your <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://latentpatterns.com/?ref=ghuntley.com\">digits here</a>, or if you're a company interested in discussing employee education, fill in this form.</p>\n<p>I'll be in SF for Daytona's <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://compute.daytona.io/?ref=ghuntley.com\">event tomorrow</a> and hanging around until Wednesday night, and then heading to New York. I'll be in New York for a week, then I'm heading to Auckland, Lithuania, Estonia, Sydney, Miami, Washington, DC, back to SF, then onwards to Singapore, Melbourne, Copenhagen, and Croatia. It's about 95 days of back-to-back travel. Cya ya'll all soon? ❤️</p>\n<p>ps..</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://latentpatterns.com/principles?ref=ghuntley.com\">Principles — Latent Patterns</a></p>\n<p>Principles for building products with large language models and the latent space — hard-won lessons from shipping AI-native software.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-2.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Latent Patterns</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/og-default-2.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Check this out. These are the principles guiding me as I build Latent Patterns. An educational platform for AI.</p>\n<p>pps. socials:</p>\n<ul>\n<li>X - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2030935650921312499?ref=ghuntley.com\">https://x.com/GeoffreyHuntley/status/2030935650921312499</a></li>\n<li>LinkedIn - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.linkedin.com/posts/geoffreyhuntley_a-sneak-preview-behind-an-embedded-software-share-7436701882716160000-zbza?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAABQKuUB2AJ059keUcRUVLbtmoa6miLVlTI\">https://www.linkedin.com/posts/geoffreyhuntley_a-sneak-preview-behind-an-embedded-software-share-7436701882716160000-zbza</a></li>\n<li>BlueSky - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://bsky.app/profile/ghuntley.com/post/3mgmjlykyis2m?ref=ghuntley.com\">https://bsky.app/profile/ghuntley.com/post/3mgmjlykyis2m</a></li>\n</ul>\n",
      "date_modified": "2026-03-09T09:12:12+00:00",
      "date_published": "2026-03-09T09:12:12+00:00",
      "external_url": "https://ghuntley.com/rad/",
      "id": "urn:aggr:item:eeca505d46fd8154b27725992f1c0644c93f1441",
      "summary": "Hey folks, I'm currently over in SF. For the last couple of weeks, I've been cryptically tweeting about a hidden mode within something I've been building on called Latent Patterns (see below), and over the last couple of days, I've started…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "a sneak preview behind an embedded software factory. I suspect rapid application dev is back",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-03-09-a-sneak-preview-behind-an-embedded-software-factory-i/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>Hey folks, the last year I've been pondering about this and doing game theory around the discovery of Ralph, how good the models are getting and how that's going to intersect with society. What follows is a cold, stark write-up of how I think it's going to go down.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/03/image-18.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.theregister.com/2026/01/27/ralph_wiggum_claude_loops/?ref=ghuntley.com\">https://www.theregister.com/2026/01/27/ralph_wiggum_claude_loops/</a></figcaption></figure>\n<p>The financial impacts are already unfolding. Back when Ralph started to go really viral, there was a private equity firm that was previously long on Atlassian and went deliberately short on Atlassian because of Ralph. In the last couple of days, they released their new investor report, and they made absolute bank.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/CleanShot-2026-02-27-at-19.43.48@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>Dec 2025 - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.minotaurcapital.com/reports/quarterly/2025-12?ref=ghuntley.com\">https://www.minotaurcapital.com/reports/quarterly/2025-12</a></figcaption></figure>\n<p>I discovered Ralph almost a year ago today, and when I made that discovery, I sat on it for a while and focused on education and teaching juniors to pay attention and just writing prolifically, just writing and doing <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/six-month-recap\">keynotes internationally</a>, pleading with people to pay attention and to invest in themselves.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/screwed\">Dear Student: Yes, AI is here, you’re screwed unless you take action...</a></p>\n<p>Two weeks ago a student anonymously emailed me asking for advice. This is the reply and if I was in your shoes this is what I’d do. So, I read your blog post “An oh f*** moment in time” alongside “The future belongs to idea guys that can just do</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--2.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/llmcurve-4.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>It's now one year later, and the cost of software development is $10.42 an hour, which is less than minimum wage and a burger flipper at macca's gets paid more than that. What does it mean to be a software developer when everyone in the world can develop software? Just two nights ago, I was at a Cursor meetup, and nearly everyone in the room was not a software developer, showing off their latest and greatest creations.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/image-3.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Well, they just became software developers because Cursor enabled them to become one. You see, the knowledge and skill of being a software developer has been commoditised. If everyone can be a software developer, what does that mean if your identity function is that you're a software developer and you write software for a living?</p>\n<p>My theory of how it all goes down and gets feral really, really fast. Is quite simple...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/02/CleanShot-2026-02-27-at-17.23.37@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>For the past month, I've been catching up with venture capitalists in Australia and San Francisco and rubber-ducking this concept. You see, for a lot of them, they're not even sure whether their business model as venture capitalists still exists.</p>\n<blockquote>\n<p>Why does someone need to raise a large amount of capital if it's just five man show now?</p>\n</blockquote>\n<p>So let's open up with a classic K shape.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/Screenshot-2026-02-27-at-7.19.32---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>We rewind time to Christmas two years ago, where I originally posted, <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/oh-fuck/\">An &quot;oh fuck&quot; moment in time</a> it was clear to me where this was going. The models were already good enough back then to cause societal disruption. The models were pretty wild; like wild horses, and they needed quite a great deal of skill to get outcomes from them...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/Screenshot-2026-02-27-at-7.23.29---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>If we fast-forward to the last Christmas holidays, many people had their &quot;oh fuck&quot; moment a year later, and the difference between now and then is twofold.</p>\n<p>One: they actually picked up the guitar, played it, and took the Christmas period off because they had the space, capacity, and time to invest in themselves and make discoveries.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/play\">deliberate intentional practice</a></p>\n<p>Something I’ve been wondering about for a really long time is, essentially, why do people say AI doesn’t work for them? What do they mean when they say that? From which identity are they coming from? Are they coming from the perspective of an engineer with a job title and</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--3.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/A-vibrant-retro-style-traditional-tattoo-art-print-featuring-a-guitar--rendered-with-high-contrast-and-dramatic-lighting.-The-complex-ornamental-design-is-set-against-a-stark-white-background--showcasing-intense-color-saturation-and-a-symbo-8.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Two, the horses or models came with factory defaults of &quot;broken in and ready to get shit done&quot;, which made them more accessible; they're easier to use to achieve outcomes, so people didn't need to invest as much time learning how to juice them to get disruptive outcomes.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/Screenshot-2026-02-27-at-7.23.56---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The world is now divided into two types of companies. Model first companies that are lean, apex predators who can operate on razor-thin margins and crush incumbents.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/papercuts\">llm weights vs the papercuts of corporate</a></p>\n<p>In woodworking, there’s a saying that you should work with the grain, not against the grain and I’ve been thinking about how this concept may apply to large language models. These large language models are built by training on existing data. This data forms the backbone which creates output based</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--4.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/universal_upscale_0_6a2d76dd-41e0-42a4-8529-bf43d0280256_0-1.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The next side of the equation is nearly every company out there today, which needs to go through a people transformation program, figure out what to do with AI, and deal with the fact that the fundamentals of business have changed.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/Screenshot-2026-02-27-at-7.29.51---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Jack is doing the right thing for his company by acting early. What will happen is that the time for a competitor to be at your door will be measured in months, not years. And as models get better, the timeframe only compresses.</p>\n<p>The real question is for the folks who, unfortunately, were laid off today; they will need jobs, and they will now see the importance of upskilling with AI. So they'll go on to their next employer or other industries and upskill with AI, and then seek to implement what is needed - automating job functions via AI.</p>\n<p>Then the cycle continues across all industries, all disciplines.</p>\n<p>But it's not going to be just triggered by layoffs. It'll be just triggered by executives who don't get it. When you understand what is going on and how real AI is, it is maddening to be in a company surrounded by people who don't get it.</p>\n<blockquote>\n<p>tfw when Canva's CTO puts you on full blast 😎</p>\n<p>[ps. that 50k LOC is on all endpoints and uplifts devs+non-devs usage of AI and is single source of truth for MCP at Canva] <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/E19pyd9meZ?ref=ghuntley.com\">pic.twitter.com/E19pyd9meZ</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GeoffreyHuntley/status/1939391215482601868?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">June 29, 2025</a></p>\n</blockquote>\n<p>You see, there is a difference between business suicide and employment suicide. The smart folks who don't want to commit employment suicide will leave.</p>\n<blockquote>\n<p>I've never seen this before in my career: 28-30 year olds who refuse to use AI coding tools.</p>\n<p>You show them what they can do augmented (not replaced) with AI and you see in their eyes that they have no damn clue of what's happening.</p>\n<p>You can't work with these people anymore. Time…</p>\n<p>— Ivan Burazin (@ivanburazin) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/ivanburazin/status/2029693439055474720?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">March 5, 2026</a></p>\n</blockquote>\n<p>The smarter ones in that segment will just go and found their own companies, then come back and do what they know. And they'll attack their employers vertically, operating leaner and meaner.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/CleanShot-2026-02-27-at-19.38.35@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>As the models get better, which is slope on slope derivative pace at this stage and as model-first companies get better and better and better at automating their job function, they can be at the door of their previous employer in months, not years.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/Screenshot-2026-03-01-at-8.40.59---AM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>To make matters worse, as the models get better, time gets compressed, and the snake eating its tail speeds up.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/CleanShot-2026-03-01-at-08.38.52@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Which results in employers who did not take corrective actions, unlike Jack, having to lay off people in the long run because margins are being squeezed by new competitors operating leaner, meaner, and faster.</p>\n<p>Then the cycle continues across all industries, all disciplines.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/02/CleanShot-2026-02-27-at-17.24.46@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>As I've been stressing in my writing for almost a year now, employers and employees trade time and skill for money. If a company is having problems adopting AI, then that is a company issue, not an employee issue.</p>\n<blockquote>\n<p>Experience as a software engineer today doesn’t guarantee relevance tomorrow. The dynamics of employment are changing: employees trade time and skills for money, but employers’ expectations are evolving rapidly. Some companies are adapting faster than others.</p>\n<p>Another thing I've been thinking: when someone says, “AI doesn’t work for me,” what do they mean? Are they referring to concerns related to AI in the workplace or personal experiments on greenfield projects that don't have these concerns?</p>\n<p>This distinction matters.</p>\n<p>Employees trade skills for employability, and failing to upskill in AI could jeopardise their future. I’m deeply concerned about this.</p>\n<p>If a company struggles with AI adoption, that’s a solvable problem - it's now my literal job. But I worry more about employees.</p>\n<p>In history, there are tales of employees departing companies that resisted cloud adoption to keep their skills competitive.</p>\n<p>The same applies to AI. Companies that lag risk losing talent who prioritise skill relevance.</p>\n<p><strong>- June 2025</strong> from <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/six-month-recap/\">https://ghuntley.com/six-month-recap/</a></p>\n</blockquote>\n<p>Model weight first companies should be scaring the fuck out of every founder right now if they're not a utility service, for what is a moat now in the era when you can /z80 something?</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/papercuts\">llm weights vs the papercuts of corporate</a></p>\n<p>In woodworking, there’s a saying that you should work with the grain, not against the grain and I’ve been thinking about how this concept may apply to large language models. These large language models are built by training on existing data. This data forms the backbone which creates output based</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2-.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/universal_upscale_0_6a2d76dd-41e0-42a4-8529-bf43d0280256_0.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/z80/\">Can a LLM convert C, to ASM to specs and then to a working Z/80 Speccy tape? Yes.</a></p>\n<p>✨Daniel Joyce used the techniques described in this post to port ls to rust via an objdump. You can see the code here: <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/DanielJoyce/ls-rs\">https://github.com/DanielJoyce/ls-rs</a>. Keen, to see more examples - get in contact if you ship something! Damien Guard nerd sniped me and other folks wanted</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/A-black-and-white--low-angle-digital-illustration-in-a-symbolic-traditional-tattoo-art-style.--A-bald--light-skinned-man-with-a-bushy-beard--prominent-eyebrows--and-a-friendly-expression-wears-denim-overalls--2--1.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/bafkreiftzmpb7bbkej76rac3kuijg2mcuyjxxhtnqdie5qq6rbrc45v2iu-1-6.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>On the topic of moats, I've been thinking about this for almost a year now, and I think I've now got a clearer sense of what moats are in the AI era, but first, let's talk about what moats aren't...</p>\n<ul>\n<li>Any business model that's based on per-seat pricing, as AI starts to rip harder and harder, is going to become much harder to maintain headcount within a corporation because model-first companies will be coming into business and operating much leaner using utility-based pricing. It's a margin game now.</li>\n<li>Any product features or platforms that were designed for humans. I know that's going to sound really wild, but understand these days I go window-shopping on SaaS companies' websites for product features, rip a screenshot into Claude Code, and it rebuilds that product feature/platform. As we enter the era of hyper-personalised software, I think this will be the case more and more. In <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://latentpatterns.com/?ref=ghuntley.com\">my latest creation</a>, I have cloned Posthog, Jira, Pipedrive, and Calendly, and the list just keeps on growing because I want to build a hyper-personalised business that meets all my needs, with full control and everything first-party. I think we're going to see more and more of model first companies operating with this mindset.</li>\n<li>Any business thought that revolved around the high cost of switching from one technology to another, or migrations from one technology to another, was a form of lock-in. This is provably falsified now. It is so easy to rip a fart into Claude Code and migrate from one technology to another. Just last week, I migrated from Cloudflare D1 to a PlanetScale Postgres database automatically using a Ralph Loop, and it just worked. Full-on data migration. When have you ever heard of a database migration going successfully unattended? We're here now, folks.</li>\n</ul>\n<p>If you currently work at a company that fits the top three bullet points, then understand that things are going to get really tight at your employer. I don't know when, but with certainty it <em>will</em> happen. Your best choices are either to find a new employer if the people around you don't get it, or, if there is a need and desire for automation, to lean so hard into AI, automate everything, and become the champion of AI within your company. If your company has banned AI outright, you need to depart right now and find another employer.</p>\n<p>So with that out of the way, what is a moat?</p>\n<ul>\n<li>Distribution. Any form of distribution. Brand awareness. Steaks and handshakes.</li>\n<li>Utility-based pricing, similar to cloud infrastructure on a cents per megabyte or CPU hour.</li>\n<li>Operating as a model-first company and accelerating the transformation so you can operate under the principles below:</li>\n</ul>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://latentpatterns.com/principles?ref=ghuntley.com\">Principles — Latent Patterns</a></p>\n<p>Principles for building products with large language models and the latent space — hard-won lessons from shipping AI-native software.</p>\n<p>Latent Patterns</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/og-default.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/image-1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>AI erases traditional developer identities—backend, frontend, Ruby, or Node.js. Anyone can now perform these roles, creating emotional challenges for specialists with decades of experience. - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/six-month-recap\">https://ghuntley.com/six-month-recap</a></figcaption></figure>\n<p>This is going to be a really hard time for a lot of people because identity functions have been erased, and the hard thing is, it's not just software developers. It's people managers as well. If your identity function is managing people, you need to make adjustments. You need to get back onto the tools ASAP.</p>\n<blockquote>\n<p>Were smaller but effectively cut 2/3rds by telling board I wouldn’t backfill in May 2023. Best decision as got rid of all the people who “are sick of hearing about ai”. 20ish people now do about 30x the output of what having more than 60 did 3 years ago.<br />\n<strong>- an anonymous founder in my DMs today.</strong></p>\n</blockquote>\n<p>This transformation is going to be brutal. Organisations need to be designed differently and need to transform from this...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/02/Screenshot-2026-02-27-at-5.49.19---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>to this...</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2026/02/Screenshot-2026-02-27-at-5.49.46---PM.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>And one of the hardest things is that AI is being rammed into the world non-consentually. It's been pushed by employers and Silicon Valley. Yeah, it sucks, but you gotta pull your chin up, process those feelings and deal with it, but for others it's gonna be really, really rough. There are going to be people who have spent years of their lives doing Game of Thrones, social political stuff, to get to where they are within a company, and it will have been all for nothing.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/CleanShot-2026-02-27-at-17.51.51@2x.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>In the org chart above, consider what the value of the senior engineer, the team lead, the manager and the senior manager in this brave new world is? How much time is spent doing Dilbert activities? What if you can flatten the org chart? If you were a founder, why wouldn't you?</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/CleanShot-2026-02-27-at-17.51.51@2x-1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This is what I've been fearing for a year. I could be wrong, I don't know. Anyone who says that they know for sure is selling horseshit. One thing is absolutely certain: things will change, and there's no going back. The unit economics of business have forever changed.</p>\n<blockquote>\n<p>Wait so you're telling me</p>\n<p>Solo builders are running entire companies now with AI employees working 24/7</p>\n<p>While traditional teams are still stuck in the &quot;we need more headcount&quot; meeting</p>\n<p>And the solo person has better work-life balance?</p>\n<p>How is this not the biggest story in tech…</p>\n<p>— Alex the Engineer (@AlexEngineerAI) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/AlexEngineerAI/status/2028114579738231031?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">March 1, 2026</a></p>\n</blockquote>\n<p>Whether a company does layoffs really comes down to the quality of its leadership. If they're being lazy and don't have ambitious plans, they will need to lay off, because eventually the backlog will run dry, and everything will get automated.</p>\n<p>This isn't me throwing shit at Jack. Like, literally, it's a cold, hard fact that you need fewer people to run a business now. So if you have too many people on your payroll, you need to make changes, but having said that, there will be ambitious founders and leaders who didn't overhire and understand that AI enables them to do anything, and they can do it today. They can make that five-year roadmap happen in a year and provide a backlog for all employees to work on while they utilise AI.</p>\n<p>It's going to be really interesting to see how this pans out.</p>\n<p>All I can ask you to do is tap someone else on the shoulder and stress to them to treat this topic seriously, upskill, and explain the risks going forward, and then ask them to do the same. You see, for a lot of people, they haven't noticed AI is knocking on their door because AI is burrowing under their house.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/image-2.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<ul>\n<li>X - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/GeoffreyHuntley/status/2027306378692595935?ref=ghuntley.com\">https://x.com/GeoffreyHuntley/status/2027306378692595935</a></li>\n<li>BSkye - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://bsky.app/profile/ghuntley.com/post/3mftdnrodas2o?ref=ghuntley.com\">https://bsky.app/profile/ghuntley.com/post/3mftdnrodas2o</a></li>\n<li>LinkedIn - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.linkedin.com/posts/geoffreyhuntley_software-development-now-costs-less-than-activity-7433072287647440896-SOrp?utm_source=share&amp;utm_medium=member_desktop&amp;rcm=ACoAAABQKuUB2AJ059keUcRUVLbtmoa6miLVlTI\">https://www.linkedin.com/posts/geoffreyhuntley_software-development-now-costs-less-than-activity-7433072287647440896-SOrp</a></li>\n</ul>\n",
      "date_modified": "2026-02-27T08:52:26+00:00",
      "date_published": "2026-02-27T08:52:26+00:00",
      "external_url": "https://ghuntley.com/real/",
      "id": "urn:aggr:item:9af8aeaa263f2bfebc496c34ea1742f83073cc47",
      "summary": "Hey folks, the last year I've been pondering about this and doing game theory around the discovery of Ralph, how good the models are getting and how that's going to intersect with society. What follows is a cold, stark write-up of how I…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "Software development now costs less than than the wage of a minimum wage worker",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-02-27-software-development-now-costs-less-than-than-the-wage-of-a/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>I'm going to make this a really quick one because this is doing the rounds, and whilst I've tweeted about it, it's time to dig in.</p>\n<blockquote>\n<p>Pragmatic Engineer's <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GergelyOrosz?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">@GergelyOrosz</a> is on a &quot;secret email list&quot; of agentic AI coders, and they're starting to report trouble sleeping because agent swarms are &quot;like a vampire.&quot;</p>\n<p>&quot;A lot of people who are in 'multiple agents mode,' they're napping during the day... It just really is… <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/slsPgCfkKw?ref=ghuntley.com\">pic.twitter.com/slsPgCfkKw</a></p>\n<p>— TBPN (@tbpn) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/tbpn/status/2019166322060587375?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">February 4, 2026</a></p>\n</blockquote>\n<p>What Gergely is articulating here is something that I and everyone else went through a year ago who were paying attention. AI enables you to teleport to the future and rob your future self of retirement projects. Anything that you've been putting off to do someday, you can do it now.</p>\n<p>To quote a post I authored almost eight months ago:</p>\n<blockquote>\n<p>It might surprise some folks, but I'm incredibly cynical when it comes to AI and what is possible; yet I keep an open mind. That said, two weeks ago, when I was in SFO, I discovered another thing that should not be possible.</p>\n<p>Every time I find out something that works, which should not be possible, it pushes me further and further, making me think that we are already in post-AGI territory.<br />\n- <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/no/\">https://ghuntley.com/no/</a> (dated July 2025)</p>\n</blockquote>\n<p>And another post back in September 2025:</p>\n<blockquote>\n<p>It's a strange feeling knowing that you can create anything, and I'm starting to wonder if there's a seventh stage to the &quot;<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ngmi/\">people stages of AI adoption by software developers</a>&quot;</p>\n</blockquote>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/02/image.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<blockquote>\n<p>whereby that seventh stage is essentially this scene in the matrix...</p>\n</blockquote>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=0YhJxJZOWBw\">The Matrix - 'I Know Kung Fu'</a></p>\n<p>In the previous 12 months, I've cloned SaaS product feature sets of many different companies. I've built file systems, networking protocols and even developed my own programming language.</p>\n<p>From my perspective, nothing really changed in December. The models were already great, but what was needed was a time of rest - people just needed to pick up the guitar and play.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/play\">deliberate intentional practice</a></p>\n<p>Something I’ve been wondering about for a really long time is, essentially, why do people say AI doesn’t work for them? What do they mean when they say that? From which identity are they coming from? Are they coming from the perspective of an engineer with a job title and</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/7V0ak3am_400x400-1-73.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/A-vibrant-retro-style-traditional-tattoo-art-print-featuring-a-guitar--rendered-with-high-contrast-and-dramatic-lighting.-The-complex-ornamental-design-is-set-against-a-stark-white-background--showcasing-intense-color-saturation-and-a-symbo-7.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>What makes December an inflection point was the models became much easier to use to achieve good outcomes and people picked up the guitar with an open mind and played.</p>\n<p>Over the last couple of weeks, I've been catching up with software engineers, venture capitalists, business owners, and people in sales and marketing who are all going through this period of adjustment.</p>\n<p>Universally, it can be described as a mild form of creative psychosis for people who like to create things. All builders who have an internal reward function of creating things as a form of pleasure go through it because AI enables them to just do things.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/dothings/\">The future belongs to people who can just do things</a></p>\n<p>There, I said it. I seriously can’t see a path forward where the majority of software engineers are doing artisanal hand-crafted commits by as soon as the end of 2026. If you are a software engineer and were considering taking a gap year/holiday this year it would be an</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/7V0ak3am_400x400-1-74.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/1_96TO5SzegxgqzECdkV2LNA-4.webp\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Everyone who gets AI goes through it, and it typically lasts about two to three months, until they get it out of their system by completing all the projects they were putting off until retirement.</p>\n<p>Perhaps it could be described as a bit of a reset, similar to what happened during COVID-19, when people were able to reassess what they wanted to do in life.</p>\n<p>It's a coin flip, really, because people are either going to commit more to their current employer if they are an employee, but on the other side of the coin, they're realising they are no longer dependent on others as much to achieve certain financial outcomes.</p>\n<p>Perhaps this is the tipping point where more people throw their hats in and become entrepreneurs.</p>\n<blockquote>\n<p>People with ideas and unique insight can get concepts to market in rapid time and be less dependent on needing others' expertise as the world's knowledge is now in the palms of everyone's hands.</p>\n<p>Technologists are still required, perhaps it's the ideas guys/gals who should be concerned as software engineers now have a path to bootstrap a concept in every white collar industry (recruiting, law, finance, finance, accounting, et al) at breakneck speed without having to find co-founders.</p>\n<p>- From Feb 2025</p>\n</blockquote>\n<p>I guess I need to wrap this up now, but I will say this:</p>\n<p>I've written about how some people won't make it, and I've spent the last year talking about this, pleading with people to pick up the guitar and play...</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=Jr2auYrBDA4\">fundamental skills and knowledge you must have in 2026 for SWE</a></p>\n<p>If you're having trouble sleeping because of all the things that you want to create, congratulations.</p>\n<p>You've made it through to the other side of the chasm, and you are developing skills that employers in 2026 are expecting as a bare minimum.</p>\n<p>The only question that remains is whether you are going to be a consumer of these tools or someone who understands them deeply and automates your job function?</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/agent\">how to build a coding agent: free workshop</a></p>\n<p>It’s not that hard to build a coding agent. 300 lines of code running in a loop with LLM tokens. You just keep throwing tokens at the loop, and then you’ve got yourself an agent.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/7V0ak3am_400x400-1-76.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/how-to-build-an-agent.001-5.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>go build yourself an agent and taste building in the recursive latent space</p>\n<p>Trust me, you want to be in the latter camp because consumption is now the baseline for employment.</p>\n<p>After you come out of this phase, I hope you get to where I am, because just because you can build something doesn't mean you necessarily should. Knowing what not to build now that anything can be built is a very important life lesson.</p>\n<blockquote>\n<p>📰 What <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GergelyOrosz?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">@GergelyOrosz</a> is articulating here is something that I and everyone else went through a year ago who were paying attention. AI enables you to teleport to the future and rob your future self of retirement projects. Anything that you've been putting off to do someday, you… <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/OXm9VvXhdZ?ref=ghuntley.com\">pic.twitter.com/OXm9VvXhdZ</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GeoffreyHuntley/status/2019302144281629087?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">February 5, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-02-05T06:47:00+00:00",
      "date_published": "2026-02-05T06:47:00+00:00",
      "external_url": "https://ghuntley.com/teleport/",
      "id": "urn:aggr:item:43c59f11314b271e593591c1606cf118265f98ab",
      "summary": "I'm going to make this a really quick one because this is doing the rounds, and whilst I've tweeted about it, it's time to dig in. Pragmatic Engineer's @GergelyOrosz is on a \"secret email list\" of agentic AI coders, and",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "teleporting into the future and robbing yourself of retirement projects",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-02-05-teleporting-into-the-future-and-robbing-yourself-of/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>Don’t waste your back pressure ·</p>\n<p>Back pressure for agents You might notice a pattern in the most successful applications of agents over the last year. Projects that are able to setup structure around the agent itself, to provide it with automated feedback on quality and correctness, have been able to push them to work on longer horizon tasks. This back pressure helps the agent identify mistakes as it progresses and models are now good enough that this feedback can keep them aligned to a task for much longer. As an engineer, this means you can increase your leverage by delegating progressively more complex tasks to agents, while increasing trust that when completed they are at a satisfactory standard.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/favicon-8.ico\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>[Moss]</p>\n",
      "date_modified": "2026-01-17T10:46:56+00:00",
      "date_published": "2026-01-17T10:46:56+00:00",
      "external_url": "https://ghuntley.com/pressure/",
      "id": "urn:aggr:item:b7418850fcee10401900fe021f8b88cb0b9513a0",
      "summary": "I am fortunate to be surrounded by folks who listen and the link below post will go down as a seminal reading for people interested in AI context engineering. A simple convo between mates - well Moss translated it into words and i’ve been…",
      "tags": [
        "programming",
        "ai"
      ],
      "title": "don’t waste your back pressure",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-01-17-don-t-waste-your-back-pressure/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>I’ve been thinking about how I build software is so very very different how I used to do it three years ago.</p>\n<p>No, I’m not talking about acceleration through usage of AI but instead at a more fundamental level of approach, techniques and best practices.</p>\n<p>Standard software practices is to build it vertically brick by brick - like Jenga but these days I approach everything as a loop. You see ralph isn’t just about forwards (building autonomously) or reverse mode (clean rooming) it’s also a mind set that these computers can be indeed programmed.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=4Nna09dG_c0\">The Ralph Wiggum Loop from 1st principles (by the creator of Ralph)</a></p>\n<p>watch this video to learn the mindset</p>\n<p>I’m there as an engineer just as I was in the brick by brick era but instead am programming the loop, automating my job function and removing the need to hire humans.</p>\n<p>Everyone right now is going through their zany period - just like i did with forward mode and building software AFK on full auto - however I hope that folks will come back down from orbit and remember this from the original ralph post.</p>\n<blockquote>\n<p>While I was in SFO, everyone seemed to be trying to crack on multi-agent, agent-to-agent communication and multiplexing. At this stage, it's not needed. Consider microservices and all the complexities that come with them. Now, consider what microservices would look like if the microservices (agents) themselves are non-deterministic—a red hot mess.</p>\n<p>What's the opposite of microservices? A monolithic application. A single operating system process that scales vertically. Ralph is monolithic. Ralph works autonomously in a single repository as a single process that <strong>performs one task per loop</strong>.</p>\n</blockquote>\n<p>Software is now clay on the pottery wheel and if something isn’t right then i just throw it back on the wheel to address items that need resolving.</p>\n<p>Ralph is an orchestrator pattern where you allocate the array with the required backing specifications and then give it a goal then looping the goal.</p>\n<p>It's important to <em>watch the loop</em> as that is where your personal development and learning will come from. When you see a failure domain – put on your engineering hat and resolve the problem so it never happens again.</p>\n<p>In practice this means doing the loop manually via prompting or via automation with a pause that involves having to prcss CTRL+C to progress onto the next task. This is still ralphing as ralph is about getting the most out how the underlying models work through context engineering and that pattern is GENERIC and can be used for ALL TASKS.</p>\n<p>In other news I've been cooking on something called &quot;<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/loom?ref=ghuntley.com\">The Weaving Loom</a>&quot;. The source code of loom can now be found on my GitHub; do not use it if your name is not Geoffrey Huntley. Loom is something that has been in my head for the last three years (and various prototypes were developed last year!) and it is essentially infrastructure for evolutionary software. Gas town focuses on spinning plates and orchestration - a full level 8.</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/01/image.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption>see <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04?ref=ghuntley.com\">https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04</a></figcaption></figure>\n<p>I’m going for a level 9 where autonomous loops evolve products and optimise automatically for revenue generation. Evolutionary software - also known as a software factory.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/01/IMG_0578.jpeg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>This is a divide now - we have software engineers outwardly rejecting AI or merely consuming via Claude Code/Cursor to accelerate the lego brick building process....</p>\n<p>but software development is dead - I killed it. Software can now be developed cheaper than the wage of a burger flipper at maccas and it can be built autonomously whilst you are AFK.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=HqPL5ONfOL8\">Programming is Dead and This Man Killed it</a></p>\n<p>hi, it me. i’m the guy</p>\n<p>I’m deeply concerned for the future of these people and have started publishing videos on YouTube to send down ladders before the big bang happens.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=Jr2auYrBDA4\">fundamental skills and knowledge you must have in 2026 for SWE</a></p>\n<p>i now won’t hire you unless you have this fundamental knowledge and can show what you have built with it</p>\n<p>Whilst software development/programming is now dead. We however deeply need software engineers with these skills who understand that LLMs are a new form of programmable computer. If you haven’t built your own coding agent yet - please do.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/agent/\">how to build a coding agent: free workshop</a></p>\n<p>It’s not that hard to build a coding agent. 300 lines of code running in a loop with LLM tokens. You just keep throwing tokens at the loop, and then you’ve got yourself an agent.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/7V0ak3am_400x400-1-70.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/how-to-build-an-agent.001-3.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<h2>ps. think this is out there?</h2>\n<p>It is but watch it happen live. We are here right now, it’s possible and i’m systemising it.</p>\n<p>Here in the tweet below I am putting loom under the mother of all ralph loops to automatically perform system verification. Instead of days of planning, discussions and weeks of verification I’m programming this new computer and doing it afk whilst I DJ so that I don’t have to hire humans.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/01/IMG_0591.jpeg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Any faults identified can be resolved through forward ralph loops to rectify issues. Over the last year the models have became quite good and it's only now that I'm able to realise this full vision but I'll leave you with this dear reader....</p>\n<p>What if the models don't stop getting good?</p>\n<p>How well will your fair if you are still building jenga stacks when there are classes of principal software engineers out there to prove a point that <em>we are here right now and please pay attention</em>.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2026/01/IMG_0607.jpeg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>Go build your agent, go learn how to program the new computer (guidance forthcoming in future posts), fall in love with all the possibilities and then join me in this space race of building automated software factories.</p>\n<blockquote>\n<p>something incredible just happened here</p>\n<p>perhaps first evolutionary software auto heal.</p>\n<p>i was running the system under a ralph system loop test. it identified a problem with a feature. then it studied the codebase, fixed it, deployed it automatically, verified that it worked and… <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/ATDaIU4p5w?ref=ghuntley.com\">https://t.co/ATDaIU4p5w</a> <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/22U7FW6Dye?ref=ghuntley.com\">pic.twitter.com/22U7FW6Dye</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GeoffreyHuntley/status/2012483036143812648?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">January 17, 2026</a></p>\n</blockquote>\n<p>ps. socials</p>\n<blockquote>\n<p>🗞️ everything is a ralph loop</p>\n<p>(link below)</p>\n<p>I’ve been thinking about how I build software is so very very different how I used to do it three years ago.</p>\n<p>No, I’m not talking about acceleration through usage of AI but instead at a more fundamental level of approach, techniques… <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/IBpO4HJ4AK?ref=ghuntley.com\">pic.twitter.com/IBpO4HJ4AK</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GeoffreyHuntley/status/2012416900748525995?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">January 17, 2026</a></p>\n</blockquote>\n",
      "date_modified": "2026-01-17T06:43:54+00:00",
      "date_published": "2026-01-17T06:43:54+00:00",
      "external_url": "https://ghuntley.com/loop/",
      "id": "urn:aggr:item:91c5a322ddeca2d10f1c4d9ee8d306821b3bf397",
      "summary": "I’ve been thinking about how I build software is so very very different how I used to do it three years ago. No, I’m not talking about acceleration through usage of AI but instead at a more fundamental level of approach, techniques and…",
      "tags": [
        "programming",
        "ai",
        "software development"
      ],
      "title": "everything is a ralph loop",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2026-01-17-everything-is-a-ralph-loop/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>In woodworking, there's a saying that you should work with the grain, not against the grain and I've been thinking about how this concept may apply to large language models.</p>\n<p>These large language models are built by training on existing data. This data forms the backbone which creates output based upon the preferences of the underlying model weights.</p>\n<p>We are now one year in where a new category of companies has been founded whereby the majority of the software behind that company was code-generated.</p>\n<p>From here on out I’m going to call to these companies as model weight first. This category of companies can be defined as any company that is building with the data (“grain”) that has been baked into the large language models.</p>\n<p>Model weight first companies do not require as much context engineering. They’re not stuffing the context window with rules to try attempt to override and change the base models to fit a pre-existing corporate standard and conceptualisation of how software should be.</p>\n<p>The large language model has decided on what to call a method name or class name because that method or classs name is what the large language model prefers thus, when code is adapted, modified, and re-read into the context window, it is consuming its preferred choice of tokens.</p>\n<p>Model-weight-first companies do not have the dogma of snake_case vs PascalCase vs kebab-case policies that many corporate companies have. Such policies were created for humans to create consistency so humans can comprehend the codebase. Something that is of a lesser concern now that AI is here.</p>\n<p>Now variable naming is a contrived example, but I suspect in the years to come if a study was done to compare the velocity/productivity/success rates with AI of a model weight first company vs. a corporate company, I suspect a model weight company have vastly better outcomes because they're not trying to do context engineering to force the LLM to follow some pre-existing dogma. There is one universal truth with LLMs as they are now: the less that you use, the better the outcomes you get.</p>\n<p>The less that you allocate (i.e., cursor rules or what else have you), then you'll have more context window available for actually implementing requirements of the software that needs to be built.</p>\n<p>So if we take this thought experiment about the models having preferences for tokens and expand it out to another use case, let's say that you needed to build a Docker container at a model weight first company.</p>\n<p>You could just ask an LLM to build a Docker container, and it knows how to build a Docker container for say Postgres, and it just works. But in the corporate setting, if you ask it to build a Docker container, and in that corporate you have to configure HTTPS, squid proxy, or some sort of artifactory and outbound internet access is restricted, that same simple thing becomes very comical.</p>\n<p>You'll see an agent fill up with lots of failed tool calls unless you do context engineering to say &quot;no, if you want to build a docker container, you got to follow these particular allocations of company conventions” in a crude attempt to override the preferences of the inbuilt model weights.</p>\n<blockquote>\n<p>Building at large companies is hard right now due to the legacy infrastructure. 10-15 years ago, some of these companies were building in house to be frontier. Today, what's available internally is too disconnected from what's available outside and is often years behind.</p>\n<p>— Jaana Dogan ヤナ ドガン (@rakyll) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/rakyll/status/2007279234822324598?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">January 3, 2026</a></p>\n</blockquote>\n<p>At a model weight first company, building a docker image is easy but at a corporate the agent will have one hell of a time and end up with a suboptimal/disappointing outcome.</p>\n<p>So, perhaps this is going to be a factor that needs to be considered when talking and comparing the success rates of AI at one company versus another company, or across industries.</p>\n<p>If a company is having problems with AI and getting outcomes from AI, are they a model weight first company or are they trying to bend AI to their whims?</p>\n<p>Perhaps the corporates who succeed the most with the adoption of AI will be those who shed their dogma that no longer applies and start leaning into transforming to become model-weight-first companies.</p>\n<p>ps. socials.</p>\n<blockquote>\n<p>🗞️ llm weights vs the papercuts of corporate</p>\n<p>(link in next post)</p>\n<p>“If a company is having problems with AI and getting outcomes from AI, are they a model weight first company or are they trying to bend AI to their whims?” <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/WLMGF4HYa1?ref=ghuntley.com\">pic.twitter.com/WLMGF4HYa1</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GeoffreyHuntley/status/1998059600780865979?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">December 8, 2025</a></p>\n</blockquote>\n",
      "date_modified": "2025-12-08T15:55:28+00:00",
      "date_published": "2025-12-08T15:55:28+00:00",
      "external_url": "https://ghuntley.com/papercuts/",
      "id": "urn:aggr:item:4d11dc8c8308fc1d280876b4c425d18e202137c1",
      "summary": "In woodworking, there's a saying that you should work with the grain, not against the grain and I've been thinking about how this concept may apply to large language models. These large language models are built by training on existing…",
      "tags": [
        "programming",
        "ai",
        "software development"
      ],
      "title": "llm weights vs the papercuts of corporate",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2025-12-08-llm-weights-vs-the-papercuts-of-corporate/"
    },
    {
      "authors": [
        {
          "name": "Geoffrey Huntley"
        }
      ],
      "content_html": "<p>It's a strange feeling knowing that you can create anything, and I'm starting to wonder if there's a seventh stage to the &quot;<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ngmi/\">people stages of AI adoption by software developers</a>&quot;</p>\n<figure class=\"article-figure\"><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/2025/03/image-17.png\" alt=\"\" loading=\"eager\" decoding=\"async\" fetchpriority=\"high\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>whereby that seventh stage is essentially this scene in the matrix...</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=0YhJxJZOWBw\">The Matrix - 'I Know Kung Fu'</a></p>\n<p>It's where you deeply understand that '<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/dothings/\">you can now do anything</a>' and just start doing it because it's possible and fun, and doing so is faster than explaining yourself. Outcomes speak louder than words.</p>\n<p>There's a falsehood that AI results in SWE's skill atrophy, and there's no learning potential.</p>\n<blockquote>\n<p>If you’re using AI only to “do” and not “learn”, you are missing out<br />\n- <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://x.com/davidfowl/status/1910930253608001565?ref=ghuntley.com\">David Fowler</a></p>\n</blockquote>\n<p>I've never written a compiler, yet I've always wanted to do one, so I've been working on one for the last three months by running Claude in a while true loop (aka &quot;<a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ralph\">Ralph Wiggum</a>&quot;) with a simple prompt:</p>\n<blockquote>\n<p>Hey, can you make me a programming language like Golang but all the lexical keywords are swapped so they're Gen Z slang?</p>\n</blockquote>\n<p>Why? I really don't know. But it exists. And it produces compiled programs. During this period, Claude was able to implement anything that Claude desired.</p>\n<p>The programming language is called &quot;cursed&quot;. It's cursed in its lexical structure, it's cursed in how it was built, it's cursed that this is possible, it's cursed in how cheap this was, and it's cursed through how many times I've sworn at Claude.</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/size/w2400/2025/09/image-1.png\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture><figcaption><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cursed-lang.org/\">https://cursed-lang.org/</a></figcaption></figure>\n<p>For the last three months, Claude has been running in this loop with a single goal:</p>\n<blockquote>\n<p>&quot;Produce me a Gen-Z compiler, and you can implement anything you like.&quot;</p>\n</blockquote>\n<p>It's now available at:</p>\n<ul>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cursed-lang.org/?ref=ghuntley.com\">https://cursed-lang.org/</a></li>\n<li><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/cursed?ref=ghuntley.com\">https://github.com/ghuntley/cursed</a></li>\n</ul>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cursed-lang.org/?ref=ghuntley.com\">the 💀 cursed programming language: programming, but make it gen z</a></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://static.ghost.org/v5.0.0/images/link-icon.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>💀 cursed</p>\n<p>the website</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/cursed?ref=ghuntley.com\">GitHub - ghuntley/cursed: the 💀 cursed programming language: programming, but make it gen z</a></p>\n<p>the 💀 cursed programming language: programming, but make it gen z - ghuntley/cursed</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/pinned-octocat-093da3e6fa40-28.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub ghuntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/cursed-2\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>the source code</p>\n<h2>whats included?</h2>\n<p>Anything that Claude thought was appropriate to add. Currently...</p>\n<ul>\n<li>The compiler has two modes: interpreted mode and compiled mode. It's able to produce binaries on Mac OS, Linux, and Windows via LLVM.</li>\n<li>There are some half-completed VSCode, Emacs, and Vim editor extensions, and a Treesitter grammar.</li>\n<li>A whole bunch of really wild and incomplete standard library packages.</li>\n</ul>\n<h2>lexical structure</h2>\n<p><strong>Control Flow:</strong><br />\n<code>ready</code> → if<br />\n<code>otherwise</code> → else<br />\n<code>bestie</code> → for<br />\n<code>periodt</code> → while<br />\n<code>vibe_check</code> → switch<br />\n<code>mood</code> → case<br />\n<code>basic</code> → default</p>\n<p><strong>Declaration:</strong><br />\n<code>vibe</code> → package<br />\n<code>yeet</code> → import<br />\n<code>slay</code> → func<br />\n<code>sus</code> → var<br />\n<code>facts</code> → const<br />\n<code>be_like</code> → type<br />\n<code>squad</code> → struct</p>\n<p><strong>Flow Control:</strong><br />\n<code>damn</code> → return<br />\n<code>ghosted</code> → break<br />\n<code>simp</code> → continue<br />\n<code>later</code> → defer<br />\n<code>stan</code> → go<br />\n<code>flex</code> → range</p>\n<p><strong>Values &amp; Types:</strong><br />\n<code>based</code> → true<br />\n<code>cringe</code> → false<br />\n<code>nah</code> → nil<br />\n<code>normie</code> → int<br />\n<code>tea</code> → string<br />\n<code>drip</code> → float<br />\n<code>lit</code> → bool<br />\n<code>ඞT</code> (Amogus) → pointer to type T</p>\n<p><strong>Comments:</strong><br />\n<code>fr fr</code> → line comment<br />\n<code>no cap...on god</code> → block comment</p>\n<h2>example program</h2>\n<p>Here is leetcode 104 - maximum depth for a binary tree:</p>\n<pre><code><span class=\"code-snippet\">vibe main\nyeet &quot;vibez&quot;\nyeet &quot;mathz&quot;\n\n// LeetCode #104: Maximum Depth of Binary Tree 🌲\n// Find the maximum depth (height) of a binary tree using ඞ pointers\n// Time: O(n), Space: O(h) where h is height\n\nstruct TreeNode {\n    sus val normie\n    sus left ඞTreeNode   \n    sus right ඞTreeNode  \n}\n\nslay max_depth(root ඞTreeNode) normie {\n    ready (root == null) {\n        damn 0  // Base case: empty tree has depth 0\n    }\n    \n    sus left_depth normie = max_depth(root.left)\n    sus right_depth normie = max_depth(root.right)\n    \n    // Return 1 + max of left and right subtree depths\n    damn 1 + mathz.max(left_depth, right_depth)\n}\n\nslay max_depth_iterative(root ඞTreeNode) normie {\n    // BFS approach using queue - this hits different! 🚀\n    ready (root == null) {\n        damn 0\n    }\n    \n    sus queue ඞTreeNode[] = []ඞTreeNode{}\n    sus levels normie[] = []normie{}\n    \n    append(queue, root)\n    append(levels, 1)\n    \n    sus max_level normie = 0\n    \n    bestie (len(queue) &gt; 0) {\n        sus node ඞTreeNode = queue[0]\n        sus level normie = levels[0]\n        \n        // Remove from front of queue\n        collections.remove_first(queue)\n        collections.remove_first(levels)\n        \n        max_level = mathz.max(max_level, level)\n        \n        ready (node.left != null) {\n            append(queue, node.left)\n            append(levels, level + 1)\n        }\n        \n        ready (node.right != null) {\n            append(queue, node.right)\n            append(levels, level + 1)\n        }\n    }\n    \n    damn max_level\n}\n\nslay create_test_tree() ඞTreeNode {\n    // Create tree: [3,9,20,null,null,15,7]\n    //       3\n    //      / \\\n    //     9   20\n    //        /  \\\n    //       15   7\n    \n    sus root ඞTreeNode = &amp;TreeNode{val: 3, left: null, right: null}\n    root.left = &amp;TreeNode{val: 9, left: null, right: null}\n    root.right = &amp;TreeNode{val: 20, left: null, right: null}\n    root.right.left = &amp;TreeNode{val: 15, left: null, right: null}\n    root.right.right = &amp;TreeNode{val: 7, left: null, right: null}\n    \n    damn root\n}\n\nslay create_skewed_tree() ඞTreeNode {\n    // Create skewed tree for testing edge cases\n    //   1\n    //    \\\n    //     2\n    //      \\\n    //       3\n    \n    sus root ඞTreeNode = &amp;TreeNode{val: 1, left: null, right: null}\n    root.right = &amp;TreeNode{val: 2, left: null, right: null}\n    root.right.right = &amp;TreeNode{val: 3, left: null, right: null}\n    \n    damn root\n}\n\nslay test_maximum_depth() {\n    vibez.spill(&quot;=== 🌲 LeetCode #104: Maximum Depth of Binary Tree ===&quot;)\n    \n    // Test case 1: Balanced tree [3,9,20,null,null,15,7]\n    sus root1 ඞTreeNode = create_test_tree()\n    sus depth1_rec normie = max_depth(root1)\n    sus depth1_iter normie = max_depth_iterative(root1)\n    vibez.spill(&quot;Test 1 - Balanced tree:&quot;)\n    vibez.spill(&quot;Expected depth: 3&quot;)\n    vibez.spill(&quot;Recursive result:&quot;, depth1_rec)\n    vibez.spill(&quot;Iterative result:&quot;, depth1_iter)\n    \n    // Test case 2: Empty tree\n    sus root2 ඞTreeNode = null\n    sus depth2 normie = max_depth(root2)\n    vibez.spill(&quot;Test 2 - Empty tree:&quot;)\n    vibez.spill(&quot;Expected depth: 0, Got:&quot;, depth2)\n    \n    // Test case 3: Single node [1]\n    sus root3 ඞTreeNode = &amp;TreeNode{val: 1, left: null, right: null}\n    sus depth3 normie = max_depth(root3)\n    vibez.spill(&quot;Test 3 - Single node:&quot;)\n    vibez.spill(&quot;Expected depth: 1, Got:&quot;, depth3)\n    \n    // Test case 4: Skewed tree\n    sus root4 ඞTreeNode = create_skewed_tree()\n    sus depth4 normie = max_depth(root4)\n    vibez.spill(&quot;Test 4 - Skewed tree:&quot;)\n    vibez.spill(&quot;Expected depth: 3, Got:&quot;, depth4)\n    \n    vibez.spill(&quot;=== Maximum Depth Complete! Tree depth detection is sus-perfect ඞ🌲 ===&quot;)\n}\n\nslay main_character() {\n    test_maximum_depth()\n}\n</span></code></pre>\n<p>If this is your sort of chaotic vibe, and you'd like to turn this into the dogecoin of programming languages, head on over to GitHub and run a few more Claude code loops with the following prompt.</p>\n<blockquote>\n<p>study specs/* to learn about the programming language. When authoring the cursed standard library think extra extra hard as the CURSED programming language is not in your training data set and may be invalid. Come up with a plan to implement XYZ as markdown then do it</p>\n</blockquote>\n<p>There is no roadmap; the roadmap is whatever the community decides to ship from this point forward.</p>\n<p>At this point, I'm pretty much convinced that any problems found in cursed can be solved by just running more Ralph loops by skilled operators (ie. people <em>with</em> experience with compilers who shape it through prompts from their expertise vs letting Claude just rip unattended). There's still a lot to be fixed, happy to take pull-requests.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/ralph/\">Ralph Wiggum as a “software engineer”</a></p>\n<p>😎Here’s a cool little field report from a Y Combinator hackathon event where they put Ralph Wiggum to the test. “We Put a Coding Agent in a While Loop and It Shipped 6 Repos Overnight” <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/repomirrorhq/repomirror/blob/main/repomirror.md\">https://github.com/repomirrorhq/repomirror/blob/main/repomirror.md</a> If you’ve seen my socials lately,</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/7V0ak3am_400x400-1-65.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/3ea367ed-cae3-454a-840f-134531dea1fd-2.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>The most high-IQ thing is perhaps the most low-IQ thing: run an agent in a loop.</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://ghuntley.com/mirrors/\">LLMs are mirrors of operator skill</a></p>\n<p>This is a follow-up from my previous blog post: “deliberate intentional practice”. I didn’t want to get into the distinction between skilled and unskilled because people take offence to it, but AI is a matter of skill. Someone can be highly experienced as a software engineer in 2024, but that</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/7V0ak3am_400x400-1-66.jpg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>Geoffrey Huntley Geoffrey Huntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/download--2--4.jpeg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>LLMs amplify the skills that developers already have and enable people to do things where they don't have that expertise yet.</p>\n<p>Success is defined as cursed ending up in the Stack Overflow developer survey as either the &quot;most loved&quot; or &quot;most hated&quot; programming language, and continuing the work to bootstrap the compiler to be written in cursed itself.</p>\n<p>Cya soon in Discord? - <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://discord.gg/CRbJcKaGNT?ref=ghuntley.com\">https://discord.gg/CRbJcKaGNT</a></p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://www.youtube.com/watch?v=BiFt4vw1-uM\">Claude made its own language (it took 3 months)</a></p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://cursed-lang.org/?ref=ghuntley.com\">the 💀 cursed programming language: programming, but make it gen z</a></p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://static.ghost.org/v5.0.0/images/link-icon.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>💀 cursed</p>\n<p>website</p>\n<p><a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://github.com/ghuntley/cursed?ref=ghuntley.com\">GitHub - ghuntley/cursed: the 💀 cursed programming language: programming, but make it gen z</a></p>\n<p>the 💀 cursed programming language: programming, but make it gen z - ghuntley/cursed</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/icon/pinned-octocat-093da3e6fa40-29.svg\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture>GitHub ghuntley</p>\n<p><picture class=\"article-picture article-picture-fallback\" style=\"--image-ratio:16 / 9\"><img src=\"https://storage.ghost.io/c/06/e5/06e5d12b-0328-469d-a0d0-3a0f0ba34c46/content/images/thumbnail/cursed-3\" alt=\"\" loading=\"lazy\" decoding=\"async\" fetchpriority=\"low\" referrerpolicy=\"no-referrer\" class=\"progressive-image\"></picture></p>\n<p>source code</p>\n<p>ps. socials</p>\n<blockquote>\n<p>I ran Claude in a loop for 3 months and created a brand new &quot;GenZ&quot; programming language.</p>\n<p>It's called <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/cursedlang?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">@cursedlang</a>.</p>\n<p>v0.0.1 is now available, and the website is ready to go.</p>\n<p>Details below! <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://t.co/Ku5kbWMRgR?ref=ghuntley.com\">pic.twitter.com/Ku5kbWMRgR</a></p>\n<p>— geoff (@GeoffreyHuntley) <a target=\"_blank\" rel=\"noopener noreferrer\" href=\"https://twitter.com/GeoffreyHuntley/status/1965258228314636524?ref_src=twsrc%5Etfw&amp;ref=ghuntley.com\">September 9, 2025</a></p>\n</blockquote>\n",
      "date_modified": "2025-09-09T03:36:48+00:00",
      "date_published": "2025-09-09T03:36:48+00:00",
      "external_url": "https://ghuntley.com/cursed/",
      "id": "urn:aggr:item:d8b7d3fde70f7bb1f9023ede12f40ad81ed66a6f",
      "summary": "It's a strange feeling knowing that you can create anything, and I'm starting to wonder if there's a seventh stage to the \"people stages of AI adoption by software developers\" whereby that seventh stage is essentially this scene in the…",
      "tags": [
        "programming",
        "ai",
        "vibe coding"
      ],
      "title": "i ran Claude in a loop for three months, and it created a genz programming language called cursed",
      "url": "https://aggr.aymericbeaumet.com/items/ghuntley-com/2025-09-09-i-ran-claude-in-a-loop-for-three-months-and-it-created-a/"
    }
  ],
  "language": "en",
  "title": "Geoffrey Huntley",
  "version": "https://jsonfeed.org/version/1.1"
}