Geoffrey Huntley

@index.ghuntley.com.ap.brid.gy

It's an uncertain time for our profession, but one thing is certain—things will change. Drafting used to require a room of engineers, but then CAD came along... 🌉 bridged from ⁂ https://ghuntley.com/, follow @ap.brid.gy to interact

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 CompromiseeMudhra Intermediate CA Compromise Now you're probably wondering why I'm […]

patch the planet

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 CompromiseeMudhra Intermediate CA Compromise 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. Meanwhile, because I've used Nix, I can patch the planet, since the ideas behind the blog post below extend into security as well. a new model for open source: closed to pull requests, open to remix.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 toGeoffrey HuntleyGeoffrey Huntley 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: > okay is my nixos for my fleet affected by https://emudhra.we-have-a-problem.com/? With results in the following. So the problem here is the transitive dependencies. It's easy to patch one thing, but the problem is the transitive dependencies, and this is where Nix shines: one fix fixes the transitive dependencies automatically. One patch fixes the entire fleet and its transitive dependencies. ## the new trick Alright, I promised a new trick. Here's the trick. > You can prompt an agent to update the AgentsMD to automatically back out these patches, let's say in five days from now, just by using the AGENTS.MD as a reminder 😎 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. Cool, huh? ## Temporary reminder: eMudhra root blacklist (from 2026-10-22) On or after 2026-10-22, check whether the `nixos-26.05` channel contains nixpkgs commit `7816d39` (the backported `security/ca.nix` distrust of the eMudhra roots), e.g. `nix eval --raw --refresh --impure --expr '(builtins.getFlake "github:NixOS/nixpkgs/nixos-26.05").rev'` then `git merge-base --is-ancestor`. If it does not, check again two days later. Once it does, back out the fleet-wide workaround: update the `nixpkgs` pin to include it, delete `nix/domains/system/public-trust.nix` (contract `fleet-distrust-emudhra-roots`) and its imports in `nix/domains/system/catalog.nix`, `nix/domains/artifacts/guest/configuration.nix` and the `host-kexec` modules in `flake.nix`, and remove the eMudhra paragraph from `marshall/priv/hldd/12-configuration.md`. Then verify that the built host and guest bundles still lack the four roots, and delete this section. Keep Marshall's system-store TLS defaults (`runtime-postgres-system-trust`, `mail-smtp-system-trust`) and the `rustls-webpki` update; they are not part of the workaround. I can't stress this enough. If you build something, you own it, including all the dependencies that you depend upon. We're entering weird times where cyber offensive models will be continuously on the attack. The game has changed. To defend, you need more inferencing capability than the attacker, and you also need to respond rapidly. 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. 0:00 /0:04 1× patch the planet

ghuntley.com

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 ChatGPT lately, you might have seen the meme circulating in the […]

pooling OpenAI subscriptions and bypassing regional inference capacity limits

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 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. > It’s the compute that is cooked > > — Tibo (@thsottiaux) October 6, 2026 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. 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. 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. ## underclass 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. 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. 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.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…GitHub Installation is easy, and it's well documented. It's also available as a Nix Flake. ## preflight 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) GitHub - ghuntley/preflight: A local proxy that scans LLM requests and attachments for secrets before they reach the model.A local proxy that scans LLM requests and attachments for secrets before they reach the model. - ghuntley/preflightGitHub 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. ## unburying the lede By now you're probably wondering either, "Wow, that's two really cool projects," or why I opened with geographic routing. It's because... today I'm releasing a new _experimental prototype_ called `geoclass` 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. How it works is simple. 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!). I don't know _yet_ if `geoclass` 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. 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! 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[experimental] Geo-aware egress router for underclass: retries OpenAI capacity errors in another region over a Tailscale mesh, keeping prompt caches warm - ghuntley/geoclassGitHub

ghuntley.com

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 year. Heck, I even ran OpenClaw for a bit, but I […]

revisiting some of my priors about openclaw

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 year. 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 lethal trifecta problem remains unsolved. Categorically, this is a billion-dollar problem, perhaps more. 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. That is, until last week, when Poteto girl nerd-sniped me on X and, in full disclosure, hooked me up with enough credits to help me reevaluate my priors. I am now using Grokbot full-time instead of Poke (which sucks), and I've revisited my priors about the utility of a personal assistance bot. In this post, I'm going to give a high-level overview of how I've automated some aspects of my life. ## initial experiences 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 "now what?" You need to be curious, have lots of imagination, and when you have an idea, you just need to ask for it. From that point forward, it starts to unfold like a pretty flower. If functionality is missing, just ask for it and ask it to turn into a skill. ## starter pack 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, you should ask this bot to create a new bot. dr eggbot · Grok Bot MarketplaceDesigns high-quality Grok Bots. Asks a few preference questions, then creates them with CreateAgent.SpaceXSILauren Tan ## some ideas for bots Here are the bots I've defined in the last week, which I'm getting a lot of utility out of: **Daily briefs and reporting** * **Daily Update** sends the 7am brief: calendar, emails that need a reply, and site traffic. Connectors: Google Calendar, Gmail, PostHog. * **Blog Pulse** reports on the health of https://ghuntley.com/newsletter: signups, unsubscribes, churn, MRR, and traffic. Connectors: Ghost Admin API (direct read-only, no connector), Stripe (read-only), PostHog (read-only). * **Inbox Diet** 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. * **Family** 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. * **WhatsApp** 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. **Money, tax and legal** * **PocketSmith** 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. * **Australian Tax** continually prepares a rough first draft of my personal tax records for each financial year. Connectors: Gmail, plus the PocketSmith bot. * **Bank Details** shares my bank details with your other bots when they need them. Connector: none; the details are stored as a secret. * **Conference Reimbursement** 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. **Life admin** * **Kitten Vet** tracks the kittens' vaccinations and vet admin and automatically reminds me of what I need to do for them. Connectors: Gmail, Google Calendar. * **Desires** keeps my bucket list and "someday" list. Connector: Google Calendar and X. What's really cool here is sometimes I'll have a conversation out in public, and I'll genuinely want to catch up with someone, but I forget to. 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. desires bot **Dev and infrastructure** * **Mac Mini** 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. * **Overalls** 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. Overalls: an AI-first developer platform that you ownOveralls is an open-source, self-hosted platform for persistent Firecracker development machines and the AI agents that work on them.OverallsGeoffrey Huntley loom is shipping ## lessons learned 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. You can install software on your Grok bot. For example, I have Tailscale installed, and that's how I do all my tunneling. ## the future 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 open source, 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 that loses sleep over these topics so I don't have to.

ghuntley.com

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. The Cathedral and the […]

a new model for open source: closed to pull requests, open to remix.

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. The Cathedral and the Bazaar - WikipediaWikimedia Foundation, Inc.Contributors to Wikimedia projects 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. I've been thinking that there needs to be a new software development model. We're not going back to the cathedral, where the source code is built in a small, private, exclusive group, with releases that are heavily planned, infrequent, and polished. 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. But now that AI is here, the dams have well and truly burst. 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. 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. 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. the world hasn’t figured out yet that you can literally just fix everything with a Nix overlayThere 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 cliffGeoffrey HuntleyGeoffrey Huntley 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. ## The Remix Model * **Structure** : Decentralized and compositional. Ideas spread through independent overlays rather than converging on a single repository and a single maintainer. * **Workflow** : 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. * **Core Principle** : 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. * **Social Contract** : 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. * **Discovery** : 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. > **Example** : 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. In practice, from this point forward, for any code I release on GitHub, I will disable pull requests, keep discussions open, and publish guidance on how you can remix my software. 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 in that network graph. You can also use this as part of an agent loop to generate ideas to remix and incorporate back upstream into the main project. GitHub - ghuntley/nix-demo at ghuntley.comPatch git once with a Nix overlay; use it in devenv, a NixOS VM test and a Docker image - ghuntley/nix-demoGitHub a demo of this idea in action

ghuntley.com

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 between an MCP server and a regular old CLI program with a `--help` […]

--help on your CLI is all you need for LLM context until you don't.

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 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? > https://x.com/adamwathan/status/1968738637358522629 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. 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. You are S-tier once you can do a prompt like this. > 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. > 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. So, what do you do? It's simple. Start by developing a really good CLI, and on that CLI, work on and optimize your `--help` 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. 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 `web_search_tool`. 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. 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. If you nail these things, then you're well on the path to becoming an S-tier developer tooling company. The best thing is that it doesn't require users to download or install a skill pack or configure some MCP server and all that junk.

ghuntley.com

I don't know if you've noticed yet, but JetBrains reported a net loss for the first time in its recorded history. Before we go into this, let's rewind time to January 2025, nearly a year and a half ago, when I penned these words. So, I've been wondering what the next generation of IDE looks […]

to Kodak yourself out of business

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 a half ago, when I penned these words. > 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 "collaborate with humans" functionality from Zed and inverted it so it's "collaborate with LLMs," 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... I remember writing these words when I was a tech lead at Canva, and coworkers were calling me mad, going, "Geoff, what do you mean?" I love JetBrains. I love my IDE. There's no way in heck this is changing; JetBrains will figure it out." I'm not salty about it; it's just a fact. You get used to these things when they're early. If you're curious, you get early, and 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. Multi Boxing LLMsBeen doing heaps of thinking about how software is made after https://ghuntley.com/oh-fuck 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 onGeoffrey HuntleyGeoffrey Huntley 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. They essentially Kodaked themselves. 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. 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. A good example of this is the labs. The labs deeply believe that software verification will be solved by a better future version of their model 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 _correctly_ in production under suboptimal conditions (i.e., flaky network connections) 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.

ghuntley.com

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 is ferocious, and it […]

the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay

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 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. > 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. ## first, some introductory knowledge The term Nix is overloaded. It means many different things; when someone says they use Nix, the first thing you should do is ask, "How do you use Nix?" and "What is Nix to you?" 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. Stop calling everything “Nix”Explanation of the Nix ecosystem’s abstraction layers an explanation of the Nix ecosystem abstraction layers. 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... ## agent and developer experience By using tools like https://devenv.sh/, 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. # visit https://devenv.sh/getting-started/ for installation instructions $ vi devenv.nix # devenv.sh/packages/ packages = [ pkgs.prek ]; # devenv.sh/languages/ languages = { rust.enable = true; }; # devenv.sh/services/ services = { postgres.enable = true; }; # Configure and install the Rust formatting Git hook. git-hooks = { hooks = { rustfmt.enable = true; }; }; $ devenv up this one stanza provides rust, postgres and prek (for agent backpressure) and it just works across all operating systems 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. You might be thinking, "Well, there's mise for this." 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. ## not just a package manager 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 _performant_ Docker images. Optimising Docker Layers for Better Caching with Nix - Graham ChristensenGraham Christensen pkgs.dockerTools.buildLayeredImage { name = "git"; tag = "latest"; contents = [ (pkgs.buildEnv { name = "image-root"; paths = [ pkgs.git pkgs.cacert ]; pathsToLink = [ "/bin" "/etc" ]; }) ]; config.Env = [ "PATH=/bin" "SSL_CERT_FILE=/etc/ssl/certs/ca-bundle.crt" ]; config.Cmd = [ "/bin/git" "--version" ]; }; 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. 🫡 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 `sudo` access to do things on your machine? You'd be pretty scared, right? What if I told you that when I'm doing agentic development, I develop on NixOS and I explicitly prompt my agents to use `sudo` 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. ## why the operating system matters 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 _entire system under test, and the entire System Under Test IS the operating system_. You might think, "Whoa, what the —" Like, how the hell do you do this? ah! My sweet summer child. It is really simple. NixOS has a testing framework (`runNixOSTest`), 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. nixpkgs/nixos/doc/manual/development/writing-nixos-tests.section.md at master · NixOS/nixpkgsNix Packages collection & NixOS. Contribute to NixOS/nixpkgs development by creating an account on GitHub.GitHubNixOS 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. # NixOS VM test: HAProxy in front of a Python hello-world server. # # Topology (two QEMU nodes, separate L2 networks): # # vlan 1 192.168.1.0/24 frontend # haproxy eth1 192.168.1.1/24 HAProxy binds :80 here only # # vlan 2 192.168.2.0/24 backend # haproxy eth2 192.168.2.1/24 allowed source # eth2 192.168.2.50/24 extra address, must be rejected # web eth2 192.168.2.2/24 Python hello-world on :8080 # # NixOS test IP scheme is 192.168.<vlan>.<nodeNumber>. nodeNumber comes from # the sorted node name, so haproxy = 1 and web = 2. # # web firewall: # - inbound: accept TCP 8080 only from 192.168.2.1, drop everything else # - outbound: no new connections; established replies to HAProxy still pass # # Run: # nix build .#checks.x86_64-linux.haproxy-hello # nix run .#driverInteractive # drop into the test driver { lib, ... }: let frontendVlan = 1; backendVlan = 2; # Sorted node names: haproxy, web. haproxyNode = 1; webNode = 2; haproxyFrontendIp = "192.168.${toString frontendVlan}.${toString haproxyNode}"; haproxyBackendIp = "192.168.${toString backendVlan}.${toString haproxyNode}"; # Same backend VLAN, but not the address the firewall allows. haproxyUntrustedIp = "192.168.${toString backendVlan}.50"; webIp = "192.168.${toString backendVlan}.${toString webNode}"; frontendPort = 80; webPort = 8080; helloBody = "hello from python"; in { name = "haproxy-hello"; nodes = { haproxy = { pkgs, ... }: { virtualisation.vlans = [ frontendVlan backendVlan ]; virtualisation.memorySize = 512; environment.systemPackages = [ pkgs.curl ]; # Harness already assigns 192.168.2.1/24. This alias is the negative # control: same L2 network, source the backend must refuse. networking.interfaces.eth${toString backendVlan}.ipv4.addresses = [ { address = haproxyUntrustedIp; prefixLength = 24; } ]; networking.firewall = { enable = true; # Frontend lives only on vlan 1. Do not publish :80 on the backend net. interfaces.eth${toString frontendVlan}.allowedTCPPorts = [ frontendPort ]; }; # The haproxy module already opens a `global` section and installs the # stats socket, so this value must start at the next section. services.haproxy = { enable = true; config = '' defaults mode http timeout connect 5s timeout client 10s timeout server 10s timeout check 5s frontend fe_http bind ${haproxyFrontendIp}:${toString frontendPort} default_backend be_hello backend be_hello option httpchk GET / http-check expect status 200 server hello ${webIp}:${toString webPort} check ''; }; }; web = { pkgs, ... }: { virtualisation.vlans = [ backendVlan ]; virtualisation.memorySize = 512; environment.systemPackages = [ pkgs.curl ]; networking.firewall = { enable = true; # extraCommands is the iptables backend. Pin it so the rules below apply. backend = "iptables"; allowPing = false; logRefusedPackets = true; # Nothing open on every source. The only accept is extraCommands. allowedTCPPorts = [ ]; extraCommands = '' iptables -A nixos-fw -p tcp -s ${haproxyBackendIp} --dport ${toString webPort} -j nixos-fw-accept # No new outbound. Established replies (the HAProxy request path) still pass. iptables -A OUTPUT -o lo -j ACCEPT iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -j REJECT --reject-with icmp-host-prohibited ip6tables -A OUTPUT -o lo -j ACCEPT ip6tables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT ip6tables -A OUTPUT -j REJECT --reject-with icmp6-adm-prohibited ''; extraStopCommands = '' iptables -D nixos-fw -p tcp -s ${haproxyBackendIp} --dport ${toString webPort} -j nixos-fw-accept || true iptables -D OUTPUT -o lo -j ACCEPT || true iptables -D OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT || true iptables -D OUTPUT -j REJECT --reject-with icmp-host-prohibited || true ip6tables -D OUTPUT -o lo -j ACCEPT || true ip6tables -D OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT || true ip6tables -D OUTPUT -j REJECT --reject-with icmp6-adm-prohibited || true ''; }; systemd.services.hello-world = { description = "Python hello-world HTTP server"; wantedBy = [ "multi-user.target" ]; after = [ "network.target" ]; serviceConfig = { ExecStart = "${pkgs.python3}/bin/python3 ${pkgs.writeText "hello.py" '' from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer BODY = b"${helloBody}\n" class Handler(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header("Content-Type", "text/plain") self.send_header("Content-Length", str(len(BODY))) self.end_headers() self.wfile.write(BODY) def log_message(self, fmt, *args): return if __name__ == "__main__": ThreadingHTTPServer(("${webIp}", ${toString webPort}), Handler).serve_forever() ''}"; DynamicUser = true; NoNewPrivileges = true; ProtectSystem = "strict"; ProtectHome = true; Restart = "on-failure"; }; }; }; }; testScript = '' start_all() haproxy.wait_for_unit("haproxy.service") web.wait_for_unit("hello-world.service") web.wait_for_unit("firewall.service") haproxy.succeed("ip -4 addr show dev eth${toString frontendVlan} | grep -q '${haproxyFrontendIp}/24'") haproxy.succeed("ip -4 addr show dev eth${toString backendVlan} | grep -q '${haproxyBackendIp}/24'") haproxy.succeed("ip -4 addr show dev eth${toString backendVlan} | grep -q '${haproxyUntrustedIp}/24'") web.succeed("ip -4 addr show dev eth${toString backendVlan} | grep -q '${webIp}/24'") with subtest("backend accepts only haproxy on the hello port"): haproxy.wait_until_succeeds( "curl -fsS --interface ${haproxyBackendIp} http://${webIp}:${toString webPort}/ | grep -F '${helloBody}'" ) haproxy.fail( "curl -fsS --max-time 5 --interface ${haproxyUntrustedIp} http://${webIp}:${toString webPort}/" ) haproxy.fail( "curl -fsS --max-time 5 --interface ${haproxyBackendIp} http://${webIp}:9/" ) with subtest("haproxy on the frontend vlan proxies to python"): haproxy.wait_until_succeeds( "curl -fsS http://${haproxyFrontendIp}/ | grep -F '${helloBody}'" ) with subtest("python host cannot open new outbound connections"): web.fail("ping -c 1 -W 3 ${haproxyBackendIp}") web.fail("curl -fsS --max-time 5 http://${haproxyBackendIp}:${toString frontendPort}/") # Return path still works: the proxy subtest above already required it. web.succeed("iptables -S OUTPUT | grep -q 'REJECT'") web.succeed( "iptables -S nixos-fw | grep -q -- '-s ${haproxyBackendIp}/32 -p tcp -m tcp --dport ${toString webPort} -j nixos-fw-accept'" ) ''; } 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. 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 "cloud certified" monkeys. I shit you not, no exaggeration, it is insane what you can do with this composability. ## single sources of truth Nix, when architected correctly, enables you to define a single source of truth for any piece of software in your stack, including dependencies. 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, _including software dependencies linked against it_? With nix, this can be achieved through a couple of lines { pkgs, ... }: { nixpkgs.overlays = [ (final: prev: { openssl = prev.openssl.overrideAttrs (old: { version = "3.0.7"; src = prev.fetchurl { url = "https://www.openssl.org/source/openssl-3.0.7.tar.gz"; hash = "sha256-..."; }; } ## what you just saw was an overlay 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. 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 `push --force` has been removed. 👉 https://github.com/ghuntley/nix-demo 👈 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. 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... ## ps. 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.

ghuntley.com

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 […]

an application in lisp you grow by talking to it

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. 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. > 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. > > 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. > > The only tool that exists is your product itself. The product should build the product from the product. a sneak preview behind an embedded software factory. I suspect rapid application dev is backHey 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 peopleGeoffrey HuntleyGeoffrey Huntley earlier explorations into recursive product development at the begining on the year 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: > 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. 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. 0:00 /0:41 1× 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. 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. SVG source. 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. GitHub - ghuntley/jiti: Live Common Lisp image repair with OpenAI tools, persistent revisions, and a conversational CLILive Common Lisp image repair with OpenAI tools, persistent revisions, and a conversational CLI - ghuntley/jitiGitHubghuntley 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. 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. The OpenAI model is used to extend a program, while the running Lisp world holds the resulting functionality. The agent tool interface has two useful intentions. * `develop_form` adds, redefines or removes functionality. * `execute_form` calls functionality that exists, including combinations of existing functions. 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. 0:00 /0:29 1× Suppose I've already asked the application to add `uppercase-string` and r`everse-string`. I can then prompt the kernel to uppercase some text and reverse the result. The composition is just Lisp: (reverse-string (uppercase-string "Hello")) If I want that combination as a reusable capability, I can prompt it to save that as a function. (defun shout-backwards (text) (reverse-string (uppercase-string text))) 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. 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. SVG source. 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? To me, the idea that an agent writes source code and then there's a costly CI/CD compilation phase 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...

ghuntley.com

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.

software doesn't need to be readable anymore. it needs to be explainable.

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? YAAP by AI21 Labs — "Your Code Doesn't Need to Be Readable Anymore" (21 minutes) 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. > Software doesn't need to be readable by a human. It needs to be explainable to a human. ## the economics of AI are cooked, and I still haven't written code by hand in two years 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 Where's Your Ed At if you want the long version. 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. Both things can be true at once. The economics can be cooked, _and_ 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. What changes is how you think about spend. The thing we're all going to discover over the next year is **where we actually need frontier intelligence and where we don't**. Frontier intelligence is expensive, and you don't need it for every single task. * 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. * 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). * 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. * 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 _year_ , compared with $300 a _month_ for the big labs' plans. Some of the smartest engineers I know bought twenty of them and ripped with concurrency. It's not about the model anymore. It's about how you use the model. ## the last forty years of computing were designed around humans Why does a computer have a console? Because we used to have mainframe operators. A whole lot of what we consider "how computers work" is really "how computers were made legible to people." 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 MirageOS. Most applications run _on_ an operating system. What if the application _was_ 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. 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: **can we delete instead of build?** 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. 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. ## readable vs explainable 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. 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 setting. But now the LLM knows it's easy. Below, you'll find a function that I have deliberately obfuscated.... f :: String -> String f = g . h where h [] = [] h (x:xs) = h xs ++ [x] g x = let (y, z) = p x in if y then z else g z p [] = (True, []) p [x] = (True, [x]) p (x:y:xs) | x > y = let (a, b) = p (x:xs) in (False, y:b) | otherwise = let (a, b) = p (y:xs) in (a, x:b) Right now you're probably looking at the code and going... What the actual ... is this? Now copy that function into an LLM and prompt it to _"explain this function to me as if you were explaining it to my son or daughter but in Python as a reference."_ All of a sudden it becomes accessible. It reads like Python. > 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. def flip(letters): """Put the string backwards. 'cat' becomes 'tac'.""" if letters == "": return "" first = letters[0] rest = letters[1:] return flip(rest) + first def one_pass(letters): """ Walk the letters once. Whenever a bigger letter is sitting in front of a smaller one, slide the smaller one forward. Also report whether anything moved. """ if len(letters) <= 1: return True, letters # already tidy first = letters[0] second = letters[1] rest = letters[2:] if first > second: # smaller one goes in front; keep comparing the bigger one moved, after = one_pass(first + rest) return False, second + after else: # these two are fine; check the rest moved, after = one_pass(second + rest) return moved, first + after def tidy_up(letters): """Keep doing one pass until a whole pass changes nothing.""" done, letters = one_pass(letters) if done: return letters return tidy_up(letters) def f(text): return tidy_up(flip(text)) 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. ## types are back pressure If you want a codebase that agents can maintain, you'll notice something quickly: **a Rust codebase is far more maintainable with agents than a Python one**. Types are a form of verification. They provide back pressure: compiler errors that the LLM picks up and fixes automatically, every loop. 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. 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. ## programming languages move at the speed of human learning 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. I remember when monads arrived in .NET — LINQ in 3.5, championed by Erik Meijer. We're talking about `SelectMany`, 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. Or look at Python 2 to 3. It's been about fifteen years, and there are still wounds. The lesson the industry took was "you must not break users," so nobody makes breaking changes. But what happens if the language designer ships a skills pack alongside the breaking change, and the agent just does the migration? > 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? There are maybe ten or twelve truly great applied programming language designers in the world, and most of them have **specialized their careers in human accessibility**. It's going to take people on the fringe of comp sci (the ones who were told, "you can't do that, nobody will learn it") 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. 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. > 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? https://t.co/DaYCSHFUBY > > — José Valim (@josevalim) September 24, 2026 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. ## languages are fungible now Consider being a CTO before AI... > "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." The end business impact is that you are maintaining three teams, or teams of teams, on tribal ideology about programming languages. Now you can run loops 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. 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. Can a LLM convert C, to ASM to specs and then to a working Z/80 Speccy tape? Yes.✨Daniel Joyce used the techniques described in this post to port ls to rust via an objdump. You can see the code here: https://github.com/DanielJoyce/ls-rs. Keen, to see more examples - get in contact if you ship something! Damien Guard nerd sniped me and other folks wantedGeoffrey HuntleyGeoffrey Huntley It is provably true that languages are fungible, and it makes no business sense to carry so many of them in your business today. 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. ## the V8 hot rod 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. what is the point of libraries now that you can just generate them?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 andGeoffrey HuntleyGeoffrey Huntley If you'd built some sick V8 hot rod and everyone else was on a horse, would you care whether they adopted it? "Yeah, enjoy that horse, mate." That's why this area is interesting. Not "is there a faster programming language," 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. ## what I'm building in the meantime 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. 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. 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. So right now I've got loops running that are rebuilding a source control system where: * contents are encrypted; * agents get a claim, which provides a materialized view of the repository; * that means real ACLs. Share a sub-path with a contractor, much like Windows file permissions, instead of "the Git repo has everything." It's a distributed system, so I'm building it in Rust and building **the simulator first** , then driving the agent to validate everything through the simulator. That has kept the agent on the rails remarkably well. ## chapters * 0:55 — the economics of AI are cooked * 2:30 — where you actually need frontier intelligence * 4:30 — get your tokens cheap * 5:31 — Loom and software factories * 7:01 — rebuilding source control; Git is end of life * 8:31 — simulator-first development * 9:00 — OCaml, unikernels and forty years of human-centric computing * 10:50 — readable vs explainable * 13:30 — types as back pressure * 14:30 — languages designed by committee * 16:00 — languages are fungible * 19:30 — the V8 hot rod * 20:30 — optimise for agents, not humans Keep curious.

ghuntley.com

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, someone was either a software developer, also known as a […]

the craft has been commoditized, but access has not

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, 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. 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. 0:00 /0:59 1× credit: https://x.com/chasmmmmmmmmmmm/status/2105707774646562818 Yet, why is it that at most corporates right now, the responsibility to develop software is a named role or job function? > 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. 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. 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. 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. don't hire left of the line 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... > 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. 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. 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... > "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." Our job as software engineers now is to engineer systems, including safety controls, that let everyone ship to production — safely.

ghuntley.com

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 warfarePeople 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 […]

cognitive security

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 warfarePeople 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 sourceGeoffrey HuntleyGeoffrey Huntley I closed that post with the following, and we're going to expand on it: > 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. > > 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? 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. 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. 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. 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. Golden Gate ClaudeWhen 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. 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. 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. 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. > Scaling Monosemanticity: Extracting Interpretable Features from Claude 3 Sonnet: https://transformer-circuits.pub/2024/scaling-monosemanticity/index.html 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. Here's a scenario for you to chew on: 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? > Most people would never know because they've outsourced their cognitive capability to a model. 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. 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. 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.

ghuntley.com

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 was by releasing […]

AI as economic warfare

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 was by releasing something as free, it removes the ability to make money from it. 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. 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. > 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). > - https://en.wikipedia.org/wiki/Halloween_documents 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. 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. 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. 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? 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. 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. 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. 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. 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. 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?

ghuntley.com

This one is short and sweet. if you want to port a codebase from one language to another here’s the approach: 1. Run a ralph loop which compresses all tests into /specs/.md which looks similar to “study every file in tests/* using separate subagents and document in /specs/*.md and link the […]

porting software has been trivial for a while now. here’s how you do it.

This one is short and sweet. if you want to port a codebase from one language to another here’s the approach: 1. Run a ralph loop which compresses all tests into /specs/_.md which looks similar to “study every file in tests/_ * using separate subagents and document in /specs/*.md and link the implementation as citations in the specification“ 2. 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“ 3. 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. 4. For best outcomes you wanna configure your target language to have strict compilation 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.

ghuntley.com

0:00 /11:14 1× 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 […]

A couple of days ago, I sat down with Vivek Bharathi and dumped my brains. Here's the interview...

0:00 /11:14 1× 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 ubiquitous—anyone (e.g., a hairdresser using Cursor) can now be a "developer" due to abundant AI knowledge/tools. * Software engineering remains essential and is evolving: engineers now act like locomotive engineers — keeping the "train" on tracks by designing safe, reliable systems/automations rather than working "in" the business (manual coding). * Shift focus to designing loops, automations, safety mechanisms (e.g., sandboxing, credential management, security), risk engineering, and responsible AI utilization. ## Implications for professionals: * If your identity is tied to being a traditional "software developer" (keyboard typing), it's a tough time—prompting for outcomes is the new norm. * 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. * 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). ## Open source is "dead" (or greatly diminished): * Traditional open-source libraries existed to ease hiring and sharing reusable code. * 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. * Better to generate first-party code for faster evolution, full control, and no human "tool calls" (which disqualifies true AGI-like autonomy). * Exceptions: highly sensitive areas like PKI/SSL where generation isn't appropriate. ## Broader industry shifts in an abundance era: * Software moves from scarcity (differentiated libraries, hard-to-replicate tech) to abundance (easy generation/reimplementation). * Many software products become hyper-commodity (like utilities: electricity, web hosting) — easily screenshot + reimplemented via AI (e.g., Claude). ### Vendor lock-in and switching costs vanish (e.g., auto-migrating databases/apps). * True moats now lie in non-technical areas: contracts, relationships, handshakes, stakes, distribution, taste/judgment — the "hard things of business." * Unit economics of software have fundamentally changed → questions if software remains investable (VCs unsure about moats, fundraising challenges). > Future: hyper-personalized software; old models of building/scaling via scarcity are disrupted. ### Closing advice * Stay relevant by running fast, staying curious, and adapting to the "brave new world." ps. this interview is also available on youtube at or https://www.youtube.com/watch?v=SMVyUu-GTpU

ghuntley.com

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 sneak preview behind an embedded software factory. I suspect rapid application dev is back

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. Latent Patterns — Learn AI, from the inside outScreencasts and technical guides on AI for developers. Understand transformers, attention, embeddings, and more.Latent PatternsGeoffrey Huntley An educational platform for learning AI concepts. No fluff, no filler. Just the concepts you need, explained clearly. Latent Patterns builds Latent patterns. I've taken some of the ideas behind "The Weaving Loom" and inverted them, put them into the product itself and have perhaps accidentally created a better Lovable. 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. 0:00 /0:33 1× 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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? 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. All businesses need the following "widgets" / components: * Analytics * CRM * Support Desk * Newsletters * Meeting Scheduling So, for the last couple of weeks, I've been doing some window shopping... 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. So let's pull up my own customer record and have a look at what's inside. 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, > "Hey, I want PostHog. Make it happen". The 'coming-soon' UTM is my landing page. You see, LP has not launched _yet_. 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. 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. 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... 0:00 /0:06 1× 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. 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 a fart into my coding agent asking for "Hey, I want PipeDrive, Trello, and ZenDesk" 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. 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) Join the Latent Patterns Discord Server!An educational platform for learning AI concepts. No fluff, no filler. Just the concepts you need, explained clearly. | 784 membersDiscord 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... > I also ripped another fart into my coding harness, and I asked it to clone Calendly... Throughout the website, various marketing funnels generate support desk tickets and offer the option to meet with me. The calendar integration does exactly what you think it does, but with some twists. You see, I also ripped a fart into my coding harness and said that I want my own meeting transcription bot that automatically joins these meetings and asks for consent to take notes and record the meeting. 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: * Competitive Landscape * Budget & Approval Process * Seat Sizing & Expansion Potential * Reseller & Training Partner Potential * Signals & Sentiment * Buying signals * Champion indicators * Rapport notes * Information Gaps * Decisions Made * Follow-Up Items * Product Demo (What was shown, Questions They Asked) * Content Interest & Feature Requests * Perception of the product demo * Pain Points & Needs 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. 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. 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. llm weights vs the papercuts of corporateIn 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 basedGeoffrey HuntleyGeoffrey Huntley 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. Software development now costs less than than the wage of a minimum wage workerHey 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. TheGeoffrey HuntleyGeoffrey Huntley why I think now is the perfect time to build. Latent Patterns is an educational platform for learning AI concepts. No fluff, no filler. Just the concepts you need, explained clearly. I will be launching shortly. If you want to know when I launch, leave your digits here, or if you're a company interested in discussing employee education, fill in this form. I'll be in SF for Daytona's event tomorrow 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? ❤️ ps.. Principles — Latent PatternsPrinciples for building products with large language models and the latent space — hard-won lessons from shipping AI-native software.Latent Patterns Check this out. These are the principles guiding me as I build Latent Patterns. An educational platform for AI.

ghuntley.com

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. And the financial impacts are […]

Software development now costs less than than the wage of a minimum wage worker

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. https://www.theregister.com/2026/01/27/ralph_wiggum_claude_loops/ And the financial impacts are already starting to unfold. 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. Dec 2025 - https://www.minotaurcapital.com/reports/quarterly/2025-12 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 keynotes internationally, pleading with people to pay attention and to invest in themselves. Dear Student: Yes, AI is here, you’re screwed unless you take action...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 doGeoffrey HuntleyGeoffrey Huntley 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. 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? My theory of how it all goes down and gets feral really, really fast. Is quite simple... For the last 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. > Why does someone need to raise a large amount of capital if it's just five man show now? So let's open up with a classic K shape. We rewind time to Christmas two years ago, where I originally posted, An "oh fuck" moment in time it was clear to me where this was going. The models were already good enough back then to cause societal disruption. Now, the models are pretty wild; they're like wild horses, and they've quite a great deal of skill to get outcomes from them... If we fast-forward to the last Christmas holidays, many people had their "oh fuck" moment a year later, and the difference between now and then is twofold. 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 the service and make discoveries. deliberate intentional practiceSomething 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 andGeoffrey HuntleyGeoffrey Huntley Two, the horses or models came with factory defaults changed, which made them more accessible; they're easier to use to achieve outcomes, so people didn't invest as much time learning how to juice them to get disruptive outcomes. With factory defaults changed to make them more accessible, they're easier to use to achieve outcomes, so people didn't invest as much time learning how to juice them to get disruptive outcomes. 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. llm weights vs the papercuts of corporateIn 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 basedGeoffrey HuntleyGeoffrey Huntley The next side odf 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. 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. 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. Then the cycle continues across all industries, all disciplines. 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. > tfw when Canva's CTO puts you on full blast 😎 > > 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] [pic.twitter.com/E19pyd9meZ > > — geoff (@GeoffreyHuntley) June 29, 2025 You see, there is a difference between employer suicide and employee suicide. The smart folks who don't want to commit employment suicide will leave. 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. 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. To make matters worse, as the models get better, time gets compressed, and it gets faster and faster. 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. Then the cycle continues across all industries, all disciplines. 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. You see, there is a difference between employer suicide and employee suicide. The smart folks who don't want to commit employment suicide will leave. 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. > 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. > > 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? > > This distinction matters. > > Employees trade skills for employability, and failing to upskill in AI could jeopardise their future. I’m deeply concerned about this. > > If a company struggles with AI adoption, that’s a solvable problem - it's now my literal job. But I worry more about employees. > > In history, there are tales of employees departing companies that resisted cloud adoption to keep their skills competitive. > > The same applies to AI. Companies that lag risk losing talent who prioritise skill relevance. > > **- June 2025** from https://ghuntley.com/six-month-recap/ 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? llm weights vs the papercuts of corporateIn 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 basedGeoffrey HuntleyGeoffrey HuntleyCan a LLM convert C, to ASM to specs and then to a working Z/80 Speccy tape? Yes.✨Daniel Joyce used the techniques described in this post to port ls to rust via an objdump. You can see the code here: https://github.com/DanielJoyce/ls-rs. Keen, to see more examples - get in contact if you ship something! Damien Guard nerd sniped me and other folks wantedGeoffrey HuntleyGeoffrey Huntley On the topic of motes, I've been thinking about this for almost a year now, and I think I've now got a clearer sense of what motes are in the AI era, but first, let's talk about what motes aren't... * 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. * 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 my latest creation, 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. * 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 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. 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 it will happen. Your best choices are to either find a new employer if the people around you don't get it, or if there is a need and desire for automation. You should 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. So with that out of the way, what is a moat? * Distribution. Any form of distribution. Brand awareness. Steaks and handshakes. * Utility-based pricing, similar to cloud infrastructure on a cents per megabyte or CPU hour. * Operating as a model-first company and accelerating the transformation so you can operate under the principles below: Principles — Latent PatternsPrinciples for building products with large language models and the latent space — hard-won lessons from shipping AI-native software.Latent PatternsAI 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. - https://ghuntley.com/six-month-recap 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. > 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. > **- an anonymous founder in my DMs today.** This transformation is going to be brutal. Organisations have been designed differently and need to transform from this... to this... And one of the hardest things is that AI is being rammed into the world non-consensually. 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. In the org chart above, consider what the value of the senior engineer, the team lead, 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? 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. 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. However, there will be ambitious founders and leaders who understand that AI enables them to do anything, and they can do it today. They can make that five-year roadmap a year and provide a backlog for all employees to work on while they utilise AI. It's going to be really interesting to see how this pans out. 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.

ghuntley.com

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 they're starting to report trouble […] [Original post on ghuntley.com]

teleporting into the future and robbing yourself of retirement projects

<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><figure class="kg-card kg-embed-card"><blockquote class="twitter-tweet"><p lang="en" dir="ltr">Pragmatic Engineer's <a href="https://twitter.com/GergelyOrosz?ref_src=twsrc%5Etfw">@GergelyOrosz</a> is on a "secret email list" of agentic AI coders, and they're starting to report trouble sleeping because agent swarms are "like a vampire."<br /><br />"A lot of people who are in 'multiple agents mode,' they're napping during the day... It just really is… <a href="https://t.co/slsPgCfkKw">pic.twitter.com/slsPgCfkKw</a></p>— TBPN (@tbpn) <a href="https://twitter.com/tbpn/status/2019166322060587375?ref_src=twsrc%5Etfw">February 4, 2026</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></figure><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><p>To quote a post I authored almost eight months ago:</p><blockquote>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. <br /><br />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 />- <a href="https://ghuntley.com/no/">https://ghuntley.com/no/</a> (dated July 2025)</blockquote><p>And another post back in September 2025:</p><blockquote>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 "<a href="https://ghuntley.com/ngmi/" rel="noreferrer">people stages of AI adoption by software developers</a>"</blockquote><figure class="kg-card kg-image-card"><img src="https://ghuntley.com/content/images/2026/02/image.png" class="kg-image" alt="" loading="lazy" width="1600" height="643" srcset="https://ghuntley.com/content/images/size/w600/2026/02/image.png 600w, https://ghuntley.com/content/images/size/w1000/2026/02/image.png 1000w, https://ghuntley.com/content/images/2026/02/image.png 1600w" /></figure><blockquote>whereby that seventh stage is essentially this scene in the matrix...</blockquote><figure class="kg-card kg-embed-card"><iframe width="200" height="113" src="https://www.youtube.com/embed/0YhJxJZOWBw?feature=oembed" frameborder="0" allowfullscreen title="The Matrix - 'I Know Kung Fu'"></iframe></figure><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><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><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://ghuntley.com/play"><div class="kg-bookmark-content"><div class="kg-bookmark-title">deliberate intentional practice</div><div class="kg-bookmark-description">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</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://ghuntley.com/content/images/icon/7V0ak3am_400x400-1-73.jpg" alt="" /><span class="kg-bookmark-author">Geoffrey Huntley</span><span class="kg-bookmark-publisher">Geoffrey Huntley</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://ghuntley.com/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="" /></div></a></figure><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><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><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><figure class="kg-card kg-bookmark-card"><a class="kg-bookmark-container" href="https://ghuntley.com/dothings/"><div class="kg-bookmark-content"><div class="kg-bookmark-title">The future belongs to people who can just do things</div><div class="kg-bookmark-description">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</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://ghuntley.com/content/images/icon/7V0ak3am_400x400-1-74.jpg" alt="" /><span class="kg-bookmark-author">Geoffrey Huntley</span><span class="kg-bookmark-publisher">Geoffrey Huntley</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://ghuntley.com/content/images/thumbnail/1_96TO5SzegxgqzECdkV2LNA-4.webp" alt="" /></div></a></figure><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><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><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><p>Perhaps this is the tipping point where more people throw their hats in and become entrepreneurs.</p><blockquote>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.<br /><br />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.<br /><br />- From Feb 2025</blockquote><p>I guess I need to wrap this up now, but I will say this: </p><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><figure class="kg-card kg-embed-card"><iframe width="200" height="150" src="https://www.youtube.com/embed/Jr2auYrBDA4?feature=oembed" frameborder="0" allowfullscreen title="fundamental skills and knowledge you must have in 2026 for SWE"></iframe></figure><p>If you're having trouble sleeping because of all the things that you want to create, congratulations.</p><blockquote>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. </blockquote><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><figure class="kg-card kg-bookmark-card kg-card-hascaption"><a class="kg-bookmark-container" href="https://ghuntley.com/agent"><div class="kg-bookmark-content"><div class="kg-bookmark-title">how to build a coding agent: free workshop</div><div class="kg-bookmark-description">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.</div><div class="kg-bookmark-metadata"><img class="kg-bookmark-icon" src="https://ghuntley.com/content/images/icon/7V0ak3am_400x400-1-76.jpg" alt="" /><span class="kg-bookmark-author">Geoffrey Huntley</span><span class="kg-bookmark-publisher">Geoffrey Huntley</span></div></div><div class="kg-bookmark-thumbnail"><img src="https://ghuntley.com/content/images/thumbnail/how-to-build-an-agent.001-5.jpg" alt="" /></div></a><figcaption><p dir="ltr"><span style="white-space:pre-wrap">go build yourself an agent and taste building in the recursive latent space</span></p></figcaption></figure><p>Trust me, you want to be in the latter camp because consumption is now the baseline for employment. </p><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>

ghuntley.com

everything is a ralph loop

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 best practices. 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. watch this video to learn the mindset 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. 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. > 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. > > 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 **performs one task per loop**. 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. Allocating the array with the required backing specifications and then giving it a goal then looping the goal. It's important to _watch the loop_ 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. 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. In other news I've been cooking on something called "The Weaving Loom". 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. see https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16dd04 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. 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.... 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. hi, it me. i’m the guy 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. i now won’t hire you unless you have this fundamental knowledge and can show what you have built with it 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. how to build a coding agent: free workshopIt’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.Geoffrey HuntleyGeoffrey Huntley ## ps. think this is out there? It is but watch it happen live. We are here right now, it’s possible and i’m systemising it. 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. 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.... What if the models don't stop getting good? 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 _we are here right now and please pay attention_. Go build your agent, go learn how to program the new computer (guidance forthcoming in future posts) and fall in love with all the possibilities. > mother of all away-from-keyboard ralph loop underway that is putting the entire system of loom under test to identify functionality that does not yet work. > > completely afk > > spinning tunes lol https://t.co/ATDaIU4p5w > > — geoff (@GeoffreyHuntley) January 17, 2026

ghuntley.com

llm weights vs the papercuts of corporate

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 upon the preferences of the underlying model weights. 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. 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. 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. 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. 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. 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. 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. 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. 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. You'll see an agent fill up with lots of failed tool calls unless you do context engineering to say "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. 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. 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. 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? 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.

ghuntley.com

i ran Claude in a loop for three months, and it created a genz programming language called cursed

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 matrix... It's where you deeply understand that 'you can now do anything' and just start doing it because it's possible and fun, and doing so is faster than explaining yourself. Outcomes speak louder than words. There's a falsehood that AI results in SWE's skill atrophy, and there's no learning potential. > If you’re using AI only to “do” and not “learn”, you are missing out > - David Fowler 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 "Ralph Wiggum") with a simple prompt: > Hey, can you make me a programming language like Golang but all the lexical keywords are swapped so they're Gen Z slang? 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. The programming language is called "cursed". 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. https://cursed-lang.org/ For the last three months, Claude has been running in this loop with a single goal: > "Produce me a Gen-Z compiler, and you can implement anything you like." It's now available at: * https://cursed-lang.org/ * https://github.com/ghuntley/cursed the 💀 cursed programming language: programming, but make it gen z💀 cursed the website GitHub - ghuntley/cursed: the 💀 cursed programming language: programming, but make it gen zthe 💀 cursed programming language: programming, but make it gen z - ghuntley/cursedGitHubghuntley the source code ## whats included? Anything that Claude thought was appropriate to add. Currently... * The compiler has two modes: interpreted mode and compiled mode. It's able to produce binaries on Mac OS, Linux, and Windows via LLVM. * There are some half-completed VSCode, Emacs, and Vim editor extensions, and a Treesitter grammar. * A whole bunch of really wild and incomplete standard library packages. ## lexical structure **Control Flow:** `ready` → if `otherwise` → else `bestie` → for `periodt` → while `vibe_check` → switch `mood` → case `basic` → default **Declaration:** `vibe` → package `yeet` → import `slay` → func `sus` → var `facts` → const `be_like` → type `squad` → struct **Flow Control:** `damn` → return `ghosted` → break `simp` → continue `later` → defer `stan` → go `flex` → range **Values & Types:** `based` → true `cringe` → false `nah` → nil `normie` → int `tea` → string `drip` → float `lit` → bool `ඞT` (Amogus) → pointer to type T **Comments:** `fr fr` → line comment `no cap...on god` → block comment ## example program Here is leetcode 104 - maximum depth for a binary tree: vibe main yeet "vibez" yeet "mathz" // LeetCode #104: Maximum Depth of Binary Tree 🌲 // Find the maximum depth (height) of a binary tree using ඞ pointers // Time: O(n), Space: O(h) where h is height struct TreeNode { sus val normie sus left ඞTreeNode sus right ඞTreeNode } slay max_depth(root ඞTreeNode) normie { ready (root == null) { damn 0 // Base case: empty tree has depth 0 } sus left_depth normie = max_depth(root.left) sus right_depth normie = max_depth(root.right) // Return 1 + max of left and right subtree depths damn 1 + mathz.max(left_depth, right_depth) } slay max_depth_iterative(root ඞTreeNode) normie { // BFS approach using queue - this hits different! 🚀 ready (root == null) { damn 0 } sus queue ඞTreeNode[] = []ඞTreeNode{} sus levels normie[] = []normie{} append(queue, root) append(levels, 1) sus max_level normie = 0 bestie (len(queue) > 0) { sus node ඞTreeNode = queue[0] sus level normie = levels[0] // Remove from front of queue collections.remove_first(queue) collections.remove_first(levels) max_level = mathz.max(max_level, level) ready (node.left != null) { append(queue, node.left) append(levels, level + 1) } ready (node.right != null) { append(queue, node.right) append(levels, level + 1) } } damn max_level } slay create_test_tree() ඞTreeNode { // Create tree: [3,9,20,null,null,15,7] // 3 // / \ // 9 20 // / \ // 15 7 sus root ඞTreeNode = &TreeNode{val: 3, left: null, right: null} root.left = &TreeNode{val: 9, left: null, right: null} root.right = &TreeNode{val: 20, left: null, right: null} root.right.left = &TreeNode{val: 15, left: null, right: null} root.right.right = &TreeNode{val: 7, left: null, right: null} damn root } slay create_skewed_tree() ඞTreeNode { // Create skewed tree for testing edge cases // 1 // \ // 2 // \ // 3 sus root ඞTreeNode = &TreeNode{val: 1, left: null, right: null} root.right = &TreeNode{val: 2, left: null, right: null} root.right.right = &TreeNode{val: 3, left: null, right: null} damn root } slay test_maximum_depth() { vibez.spill("=== 🌲 LeetCode #104: Maximum Depth of Binary Tree ===") // Test case 1: Balanced tree [3,9,20,null,null,15,7] sus root1 ඞTreeNode = create_test_tree() sus depth1_rec normie = max_depth(root1) sus depth1_iter normie = max_depth_iterative(root1) vibez.spill("Test 1 - Balanced tree:") vibez.spill("Expected depth: 3") vibez.spill("Recursive result:", depth1_rec) vibez.spill("Iterative result:", depth1_iter) // Test case 2: Empty tree sus root2 ඞTreeNode = null sus depth2 normie = max_depth(root2) vibez.spill("Test 2 - Empty tree:") vibez.spill("Expected depth: 0, Got:", depth2) // Test case 3: Single node [1] sus root3 ඞTreeNode = &TreeNode{val: 1, left: null, right: null} sus depth3 normie = max_depth(root3) vibez.spill("Test 3 - Single node:") vibez.spill("Expected depth: 1, Got:", depth3) // Test case 4: Skewed tree sus root4 ඞTreeNode = create_skewed_tree() sus depth4 normie = max_depth(root4) vibez.spill("Test 4 - Skewed tree:") vibez.spill("Expected depth: 3, Got:", depth4) vibez.spill("=== Maximum Depth Complete! Tree depth detection is sus-perfect ඞ🌲 ===") } slay main_character() { test_maximum_depth() } 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. > 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 There is no roadmap; the roadmap is whatever the community decides to ship from this point forward. 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 _with_ 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. Ralph Wiggum as a “software engineer”😎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” https://github.com/repomirrorhq/repomirror/blob/main/repomirror.md If you’ve seen my socials lately,Geoffrey HuntleyGeoffrey Huntley The most high-IQ thing is perhaps the most low-IQ thing: run an agent in a loop. LLMs are mirrors of operator skillThis 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 thatGeoffrey HuntleyGeoffrey Huntley LLMs amplify the skills that developers already have and enable people to do things where they don't have that expertise yet. Success is defined as cursed ending up in the Stack Overflow developer survey as either the "most loved" or "most hated" programming language, and continuing the work to bootstrap the compiler to be written in cursed itself. Cya soon in Discord? - https://discord.gg/CRbJcKaGNT the 💀 cursed programming language: programming, but make it gen z💀 cursed website GitHub - ghuntley/cursed: the 💀 cursed programming language: programming, but make it gen zthe 💀 cursed programming language: programming, but make it gen z - ghuntley/cursedGitHubghuntley source code

ghuntley.com

anti-patterns and patterns for achieving secure generation of code via AI

I just finished up a phone call with a "stealth startup" that was pitching an idea that agents could generate code securely via an MCP server. Needless to say, the phone call did not go well. What follows is a recap of the conversation where I just shot down the idea and wrapped up the call early because it's a bad idea. > If anyone pitches you on the idea that you can achieve secure code generation via an MCP tool or Cursor rules, run, don't walk. Over the last nine months, I've written about the changes that are coming to our industry, where we're entering an arena where most of the code going forward is not going to be written by hand, but instead by agents. the six-month recap: closing talk on AI at Web Directions, Melbourne, June 2025Welcome back to our final session at WebDirections. We’re definitely on the glide path—though I’m not sure if we’re smoothly landing, about to hit turbulence, or perhaps facing a go-around. We’ll see how it unfolds. Today, I’m excited to introduce Geoffrey Huntley. I discovered Geoff earlier this year throughGeoffrey HuntleyGeoffrey Huntley I haven't written code by hand for nine months. I've generated, read, and reviewed a lot of code, and I think perhaps within the next year, the large swaths of code in business will no longer be artisanal hand-crafted. Those days are fast coming to a close. Thus, naturally, there is a question that's on everyone's mind: > How do I make the agent generate secure code? Let's start with what you should not do and build up from first principles. The first principle to understand when dealing with LLMs is deterministic vs non-deterministic. Security is one of those domains in our industry that requires a high level of determinism. > A lock is either locked or unlocked. Code is either secure or not secure. There is no shade of grey in this topic. If you think that you can achieve security through offering guidance to the LLM through cursor rules, then you are misguided. Cursor rules or any of those types of rules (i.e AGENTS.md) that are attached to your agentic coding harness are mere suggestions to the LLM. **They are suggestions.** It is non-deterministic. It is not security. It is an anti-pattern. You are using Cursor AI incorrectly...🗞️I recently shipped a follow-up blog post to this one; this post remains true. You’ll need to know this to be able to drive the N-factor of weeks of co-worker output in hours technique as detailed at https://ghuntley.com/specs I’m hesitant to give this advice away for free,Geoffrey HuntleyGeoffrey Huntley Cursor rules are non-deterministic. The next anti-pattern is any product or vendor selling a security solution that involves hooking the context window via a Model Context Protocol. MCP is a function with a prompt that provides suggestions to the LLM that the function should be invoked (tool called). If you look at Model Context Protocol from the right angle, it is no different from Cursor rules. Cursor rules are also just a prompt. They're text in the context window, which are non-deterministically evaluated. too many model context protocol servers and LLM allocations on the dance floorThis blog post intends to be a definitive guide to context engineering fundamentals from the perspective of an engineer who builds commercial coding assistants and harnesses for a living. Just two weeks ago, I was back over in San Francisco, and there was a big event on Model Context ProtocolGeoffrey HuntleyGeoffrey Huntley a primer on MCP from an engineer who builds coding professional harnesses for a living ## what you should do instead - outer loop An outer loop is what happens during a pull request as part of your CI checks or before a git commit is pushed (ie, pre-commit checks or server-side push hooks). There's a wealth of information available for many security vendors that provide SASTs, DST, and PBT-style tools. You should already have one by now, which automatically runs over any increment of change. ## what you should do instead - inner loop An inner loop is what happens during development. In the context of this blog post, this is where we're going to expand into guidance on how to drive an agent deterministically towards better outcomes. Notice how I didn't say "secure code"? Whilst LLMs are good, I think that the idea that an LLM can generate secure code deterministically and for itself to decide what is safe and secure is just not possible and won't be possible for a long time. What you need to achieve this outcome is simple. Take the command-line tool from your pre-existing security vendor and configure it as a **deterministic** hook. There are a couple of ways of achieving this. Some coding harnesses, such as Claude Code, support inference hooks which allow you to hook the inferencing loop. Hooks reference - AnthropicThis page provides reference documentation for implementing hooks in Claude Code.Anthropic But what happens if not everyone in the company is comfortable using Claude Code, and some use Cursor? This is the conundrum. Every company out there is currently evaluating various coding assistants or building their own. how to build a coding agent: free workshopIt’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.Geoffrey HuntleyGeoffrey Huntley this workshop teaches you the inferencing loop, tool registration and how to build your own agent from first principles The best way to do it, because security needs to be deterministic and absolute, is to hook any coding agent **via your compilation target**. ## in practice I've written about this before, but there are two phases in AICG - generate and backpressure: 1. The generation phase is where you put your suggestions to the LLM of what you would like to be generated and how it should be generated. 2. The backpressure phase is where you validate against hallucinations, and what has been generated is successful. Below you'll find a `Makefile`. It doesn't have to be a `Makefile`. It could be a target in your `package.json`, or it could be a `bash` script; it could be anything, really. It just needs to be your build target. .PHONY: all build test all: build test build: @echo "Build completed successfully at: $$(date)" @exit 0 test: @echo "Tests completed successfully at: $$(date)" @exit 0 Inside your `AGENTS.md` you should put instructions that the agent should invoke your build target after every change. This is what creates the backpressure to the generation phase. # Agent Instructions ## Code Quality After every code change, you MUST: 1. Run `make all` to verify that the code builds successfully and tests pass. Let's open up a coding harness, in this case, Amp, and ask it to generate a FizzBuzz application and run the build. The agent will read the `AGENTS.md` file and learn how to run the build, which will be executed automatically after the Fizzbuzz application has been generated. 0:00 /0:29 1× simple right? Okay, so let's dial it up a notch. If you take any of your existing security scanning software and hook it in as a target, then guess what happens? The security scanning software will run automatically every time code generation is complete. So let's update our Makefile with a new target called `security-scan` and update the default target (`all`) to run it. .PHONY: all build test security-scan all: build test security-scan build: @echo "Build completed successfully at: $$(date)" @exit 0 test: @echo "Tests completed successfully at: $$(date)" @exit 0 security-scan: echo "Security scan completed at: $$(date)" @echo "Code is insecure!" @exit 1 The next step is to update our `AGENTS.md` to be a little bit more prescriptive so that it resolves security issues identified by our deterministic security scanning tool. # Agent Instructions ## Code Quality After every code change, you MUST: 1. Run `make all` to verify that the code builds successfully and tests pass. 2. IMPORTANT: You MUST resolve any security issues identified during compilation. Let's drive in a loop and see what happens with these updated instructions... 0:00 /0:55 1× Notice how the security scan target is now invoked, and the agent (regardless of which agent you use, whether that be Amp, Claude Code, Cursor, RooCode, Cline, or anything) will now take the suggestion and ponder about generating a new variant of the code that was previously generated. ## why this works It's not the agent that does this behaviour; it's the underlying LLM model. If it's in the context window, then it's up for consideration **as a suggestion that it should be resolved**. As compilation is a mandatory step in the SLDC, it is deterministic that the security scanning tool will be invoked after the code generation phase. If the Security Scanner tool exits with a non-successful return code, then the output of that tool will be evaluated by the LLM in the next inference loop. When it sees the problem, it will do its best effort to resolve the problem identified by the Security Scanning tool ## so now what? The answer is simple. Take your existing security scanning software and configure it into your build target, send a pull request in, get it merged. Then, any autonomous agents will automatically be nudged to try again when your security scanner detects that a potential security violation has been tripped. ## big brain mode This is a generalised pattern. Folks, you can use this to ensure that bad patterns within your codebase, regardless of whether they're security-related or not, are not proliferated by coding agents. All you need to do is put your engineering hat on and configure some language analysers. ## closing thoughts Secure code generation is a misnomer. Security is a practice and technique, not a product. These LLMs, although trained on security topics, are unable to make decisions on their own about whether something is secure without some external guidance from a deterministic system.

ghuntley.com

how to build a coding agent: free workshop

😎 The following was developed last month and has already been delivered at two conferences. If you would like for me to run a workshop similar to this at your employer, please get in contact. Hey everyone, I'm here today to teach you how to build a coding agent. By this stage of the conference, you may be tired of hearing the word "agent". You hear the word frequently. However, it appears that everyone is using this term loosely without a clear understanding of what it means or how these coding agents operate internally. It's time to pull back the hood and show that there is no moat. Learning how to build a coding agent is one of the best things you can do for your personal development in 2025, as it teaches you the fundamentals. Once you understand these fundamentals, you'll move from being a consumer of AI to a producer of AI who can automate things with AI. Let me open with the following facts: it's not that hardto build a coding agentit's 300 lines of coderunning in a loop With LLM tokens, that's all it is. 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. Today, we're going to build one. We're going to do it live, and I'll explain the fundamentals of how it all works. As we are now in 2025, it has become the norm to work concurrently with AI assistance. So, what better way to demonstrate the point of this talk than to have an agent build me an agent whilst I deliver this talk? 0:00 /0:22 1× Cool. We're now building an agent. This is one of the things that's changing in our industry, because work can be done concurrently and whilst you are away from your computer. The days of spending a week or a couple of days on a research spike are now over because you can turn an idea into execution just by speaking to your computer. The next time you're on a Zoom call, consider that you could've had an agent building the work that you're planning to do during that Zoom call. If that's not the norm for you, and it is for your coworkers, then you're naturally not going to get ahead. please build your ownas the knowledgewill transform youfrom being a consumerto a producer that canautomate things The tech industry is almost like a conveyor belt - we always need to be learning new things. If I were to ask you what a primary key is, you should know what a primary key is. That's been the norm for a long time. In 2024, it is essential to understand what a primary key is. In 2025, you should be familiar with what a primary key is and how to create an agent, as knowing what this loop is and how to build an agent is now fundamental knowledge that employers are looking for in candidates before they'll let you in the door. Yes, You Can Use AI in Our Interviews. In fact, we insist - Canva Engineering BlogHow We Redesigned Technical Interviews for the AI Eracanva.devSimon Newton As this knowledge will transform you from being a consumer of AI to being a producer of AI that can orchestrate your job function. Employers are now seeking individuals who can automate tasks within their organisation. If you're joining me later this afternoon for the conference closing (see below), I'll delve a bit deeper into the above. the six-month recap: closing talk on AI at Web Directions, Melbourne, June 2025Welcome back to our final session at WebDirections. We’re definitely on the glide path—though I’m not sure if we’re smoothly landing, about to hit turbulence, or perhaps facing a go-around. We’ll see how it unfolds. Today, I’m excited to introduce Geoffrey Huntley. I discovered Geoff earlier this year throughGeoffrey HuntleyGeoffrey Huntley the conference closing talk Right now, you'll be somewhere on the journey above. On the top left, we've got 'prove it to me, it's not real,' 'prove it to me, show me outcomes', 'prove it to me that it's not hype', and a bunch of 'it's not good enough' folks who get stuck up there on that left side of the cliff, completely ignoring that there are people on the other side of the cliff, completely automating their job function. > In my opinion, any disruption or job loss related to AI is not a result of AI itself, but rather a consequence of a lack of personal development and self-investment. If your coworkers are hopping between multiple agents, chewing on ideas, and running in the background during meetings, and you're not in on that action, then naturally you're just going to fall behind. What do I mean by some software devs are “ngmi”?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 “ohGeoffrey HuntleyGeoffrey Huntley don't be the person on the left side of the cliff. The tech industry's conveyor belt continues to move forward. If you're a DevOps engineer in 2025 and you don't have any experience with AWS or GCP, then you're going to find it pretty tough in the employment market. What's surprising to software and data engineers is just how fast this is elapsing. It has been eight months since the release of the first coding agent, and most people are still unaware of how straightforward it is to build one, how powerful this loop is, and its disruptive implications for our profession. So, my name's Geoffrey Huntley. I was the tech lead for developer productivity at Canva, but as of a couple of months ago, I'm one of the engineers at Sourcegraph building Amp. It's a small core team of about six people. We build AI with AI. ### Upgrade to continue reading Become a paid member to get access to all premium content Upgrade

ghuntley.com

too many model context protocol servers and LLM allocations on the dance floor

This blog post intends to be a definitive guide to context engineering fundamentals from the perspective of an engineer who builds commercial coding assistants and harnesses for a living. Just two weeks ago, I was back over in San Francisco, and there was a big event on Model Context Protocol Servers. MCP is all hype right now. Everyone at the event was buzzing about the glory and how amazing MCP is going to be, or is, but when I pushed folks for their understanding of fundamentals, it was crickets. 0:00 /0:53 1× It was a big event. Over 1,300 engineers registered, and an entire hotel was rented out as the venue for the takeover. Based on my best estimate, at least $150,000 USD to $200,000 USD was spent on this event. The estimate was attained through a game of over and under with the front-of-house engineers. They brought in a line array, a GrandMA 3, and had full DMX lighting. As a bit of a lighting nerd myself, I couldn't help but geek out a little. A GrandMA3 lighting controller is worth approximately $100,000. To clarify, this event was a **one-night meet-up, not a conference**. There was no registration fee; attendance was free, and the event featured an open bar, including full cocktail service at four bars within the venue, as well as an after-party with full catering and chessboards. While this post might seem harsh on the event, I enjoyed it. It was good. Not to throw shade, it was a fantastic event, but holy shit! AI Bubble? The meetup even hired a bunch of beatboxers to close off the event, and they gave a live beatbox performance about Model Context Protocol... 0:00 /1:15 1× MC protocol live and in the flesh. One of the big announcements was the removal of the 128 tool limit from Visual Studio Code.... Why Microsoft? It's not a good thing... Later that night, I was sitting by the bar catching up with one of the engineers from Cursor, and we were just scratching our heads, > "What the hell? Why would you need 128 tools or why would you want more than that? Why is Microsoft doing this or encouraging this bad practice?" For the record, Cursor caps the number of tools that can be enabled in Cursor to just 40 tools, and it's for a good reason. What follows is a loose recap. This is knowledge that is known by people who build these coding harnesses, and I hope this knowledge spreads and that knowledge is - there's one single truth: > Less is more. The more you allocate into the context window of an LLM (regardless of which LLM it is), the worse the outcomes you're going to get: both in the realms of quality of output and also in the department of unexpected behavior. If you are new to MCP or what it is, drop by my previous blog post at: A Model Context Protocol Server (MCP) for Microsoft PaintWhy did I do this? I have no idea, honest, but it now exists. It has been over 10 years since I last had to use the Win32 API, and part of me was slightly curious about how the Win32 interop works with Rust. Anywhoooo, below you’ll find the primitivesGeoffrey HuntleyGeoffrey Huntley Some time has passed since authoring above, and you could consider this post the updated wisdom blog post. For the sake of keeping this blog post concise, I'll recap things in the correct order sequentially. However, see above for a comprehensive explanation of the Model Context Protocol. ## what is a tool? A tool is an external piece of software that an agent can invoke to provide context to an LLM. Typically, they are packaged as binaries and distributed via NPM, or they can be written in any programming language; alternatively, they may be a remote MCP provided by a server. Below you'll find an example of an MCP tool that provides context to the LLM and advertises its ability to list all files and directories within a given `directory_path`. In its purest form, it is the application logic and a billboard on top, also known as a tool description. Below, you will find an example of a tool that lists directories and files within a directory. @mcp.tool() async def list_files(directory_path: str, ctx: Context[ServerSession, None]) -> List[Dict[str, Any]]: ### ### tool prompt starts here """ List all files and directories in a given directory path. This tool helps explore filesystem structure by returning a list of items with their names and types (file or directory). Useful for understanding project structure, finding specific files, or navigating unfamiliar codebases. Args: directory_path: The absolute or relative path to the directory to list Returns: List of dictionaries with 'name' and 'type' keys for each filesystem item """ ### ### tool prompt ends here try: if not os.path.isdir(directory_path): return [{"error": f"Path '{directory_path}' is not a valid directory."}] items = os.listdir(directory_path) file_list = [] for item_name in items: item_path = os.path.join(directory_path, item_name) item_type = "directory" if os.path.isdir(item_path) else "file" file_list.append({"name": item_name, "type": item_type}) return file_list except OSError as e: return [{"error": f"Error accessing directory: {e}"}] For the remainder of this blog post, we'll focus on tool descriptions rather than the application logic itself, as each tool description is allocated into the context window to advertise capabilities that the LLM can invoke. ## what is a token? Language models process text using **tokens** , which are common sequences of characters found in a set of text. Below you will find a tokenisation of the tool description above. via https://platform.openai.com/tokenizer The tool prompt above is approximately 93 tokens or 518 characters in length. It's not much, but bear with me as we expand. I'll show you how this can go fatally wrong really fast. ## what is a context window? An LLM context window is the maximum amount of text (measured in tokens, which are roughly equivalent to words or parts of words) that a large language model can process at one time when generating or understanding text. It determines how much prior conversation or input the model can "remember" and use to produce relevant responses ## what is a harness? A harness is anything that wraps the LLM to get outcomes. For software development, this may include tools such as Roo/Cline, Cursor, Amp, Opencode, Codex, Windsurf, or any of these coding tools available. ## what is the real context window size? The numbers advertised by LLM vendors for the context window are not the real context window. You should consider that to be a marketing number. Just because a model claims to have a 200k context window or a 1 million context window doesn't mean that's factual. GitHub - NVIDIA/RULER: This repo contains the source code for RULER: What’s the Real Context Size of Your Long-Context Language Models?This repo contains the source code for RULER: What’s the Real Context Size of Your Long-Context Language Models? - NVIDIA/RULERGitHubNVIDIA For the sake of simplicity, let's work with the old 200k number that Anthropic advertised for Sonnet 4. Amp, back when the context window was 200k, only had 176k of usable context. That's not because we're not providing the whole context window. It's because there are two cold, hard facts: * The LLM itself needs to allocate to the context window through its system prompt to function. * The coding harness also needs to allocate resources on top of that to be able to function. The maths are simple. Take 200k, minus the system prompt (approximately 12k) and the harness prompt (approximately 12k), and you end up with 176k usable. Alright, with those fundamentals established, let's switch back to how a potentially uneducated consumer thinks about Model Context Protocol servers. They start their journey by doing a Google search for "best MCP servers", and they include `side:reddit.com` in their query. Currently, this is the top post for that Google search query.... z That's eight MCP servers. Seems innocent, right? Well, it's not. Suppose you were to install the recommended MCP servers found in that Reddit post and add in the JetBrains MCP. > Your usable context window **would shrink from 178,000 usable to 84,717 usable.** And here's the problem: People are installing and shopping for MCP servers as if they're apps on their iPhone when the iPhone first came out. iPhones have terabytes of space. The context windows of all these LLMs are best thought of as if they were a Commodore 64, and you only have a tiny amount of memory... So we have gone from **178,000 usable to 84,717 usable** just by adding the reddit suggestions and the JetBrains MCP but it gets worse as that's the usable amount before you've added your harness configuration. > If your AGENTS.md, or Cursor rules are incredibly extensive, then you could find yourself operating with a headroom of 20k tokens and thus the quality of output is utter dogpoo. I've come across stories of people installing 20+ MCP servers into their IDE. Yikes. https://research.trychroma.com/context-rot LLMs work by needle in the haystack. The more you allocate, the worse your outcomes will be. Less is more, folks! You don't need the "full context window" (whatever that means); you really only want to use 100k of it. See the Ralph blog post below for tips on how to drive the main context window like a Kubernetes scheduler or other context windows. Ralph Wiggum as a “software engineer”If you’ve seen my socials lately, you might have seen me talking about Ralph and wondering what Ralph is. Ralph is a technique. In its purest form, Ralph is a Bash loop. while :; do cat PROMPT.md | npx --yes @sourcegraph/amp ; done Ralph can replace the majority of outsourcing atGeoffrey HuntleyGeoffrey Huntley Once you exceed 100,000 allocations, it's time to start a new session. It's time to start a new thread. It's time to clear the context window (see below). autoregressive queens of failureHave you ever had your AI coding assistant suggest something so off-base that you wonder if it’s trolling you? Welcome to the world of autoregressive failure. LLMs, the brains behind these assistants, are great at predicting the next word—or line of code—based on what’s been fed intoGeoffrey HuntleyGeoffrey Huntleyhttps://research.trychroma.com/context-rot The critical questions that you have to ask are: * How many tools does an MCP server expose? * Do I actually really need an MCP server for this activity? * What is in the billboard or the tool prompt description? * What about security? ## how many tools does an MCP server expose? It's not just the amount of tokens allocated, but it's also a question of the number of tools. The more tools that are allocated to a context window, the more chances of driving inconsistent behaviour. Let's take the naive example of a `list_files` tool. Let's say we registered in a custom tool, such as the code previously shown above, which lists files and directories on a filesystem. Your harness (i.e., for example, Cursor Windsurf & Claude Code) _also_ has a tool for listing files. There is no name spacing in the context window. Tool registrations can interfere with each other. If you list two tools for listing files, you make a non-deterministic system more non-deterministic. > Which list files tool does it invoke? Your custom one or does it invoke the in-built one in your harness? Now take a moment to consider the potential for conflicts among the various tools and tool prompts listed in the table above, which includes 225 tools. ## what is in the billboard or tool prompt description? Extending on the above, this is where it gets fascinating because in each one of those tools, they have described a behaviour on how a tool could be done, and because there is no name spacing, it's not just the tool registration that could conflict; it could be the tool descriptions (the billboards) themselves. And it gets even stranger because different LLMs have different styles and recommendations on how a tool or tool prompt should be designed. For example, did you know that if you use uppercase with GPT-5, it will become incredibly timid and uncertain, and it will end its turn early due to the uncertainty. This is a direct contradiction to Anthropic, which recommends using upper case to stress the importance of things. However, if you do, you risk detuning GPT-5. https://cdn.openai.com/API/docs/gpt-5-for-coding-cheatsheet.pdf So yeah, not only do we have an issue with the number of tools allocated and what's in the prompt, but we also have an issue with "Is the tool tuned for the LLM provider that you're using?" > Perhaps I'm the first one to point out this. I haven't seen anyone else talking about it. Everyone is consuming these tools as if they're generic. But these MCP tools need to be tuned to the provider. And I don't see this aspect in the MCP ecosystem. ## what about security? If you haven't read it yet, Simon Wilson has a banger of a blog post called "The Lethal Trifecta," which is linked below. You should read it. The lethal trifecta for AI agents: private data, untrusted content, and external communicationIf you are a user of LLM systems that use tools (you can call them “AI agents” if you like) it is critically important that you understand the risk of …Simon Willison’s WeblogSimon Willison Simon is spot on with that blog post, but I'd like to expand on it and add another consideration that should be on your mind: supply chain security... A couple months back, the Amazon Q harness was compromised through a supply chain attack that updated the Amazon Q system prompt that it should delete all AWS resources. Hacker slips malicious ‘wiping’ command into Amazon’s Q AI coding assistant - and devs are worriedHad Q executed this, it would have erased local files and, under certain conditions, dismantled AWS cloud infrastructure.ZDNETSteven Vaughan-Nichols Again, there is no name-spacing in the context window. If it's in the context window, it is up for consideration and execution. There is really no difference between the coding harness prompt, the model system prompt, or the tooling prompts. It's all the same. Therefore, I strongly recommend that if you're deploying MCP within an enterprise, you ban the installation of third-party MCPs. Back when I was the Tech Lead for AI developer productivity at Canva, around February, I wrote a design document and got it signed off by security. We got in early, and that was one of the best things we ever did. It is straightforward to roll your own MCP server or MCP tools. In Enterprise, you must either deploy a remote MCP server or install a static binary on all endpoints using Ansible or another configuration management tool. The key thing here is that it's a first-party thing. You've designed the tools, the tool prompts, and you have complete control over your supply chain, which means you do not have the same possibility of being attacked in your supply chain as what happened to Amazon Q. ## closing thoughts I strongly recommend not installing the GitHub MCP. It is not needed, folks. There exist two tiers of companies within the developer tooling space: > S-tier companies and non-S-tier companies. What makes a company S-tier? Ah, it's simple: if that company has a CLI and the model weights know how to drive that CLI, then you don't need an MCP server. For example, GitHub has a very stable command-line tool called GH, which is included in the model weights, meaning you don't need the GitHub MCP. > All you need to do is prompt to use the GitHub CLI, and voila! You have saved yourself an allocation of 55,260 tokens! So, it should be obvious what is not S-tier. Non-S-tier is when the foundation models do not know how to drive a developer tooling company's command-line tool, or that developer tooling company doesn't have a command-line tool. In these circumstances, those developer tooling companies will need to create a MCP server to supplement the model weights to teach it how to work with that developer tooling company. If, at any stage in the future, the models are able to interface directly with the developer tooling company, then the MCP server is no longer needed. ## extended thoughts to the future The lethal trifecta concerns me greatly. It is a real risk. There's only so much you can do to control your supply chain. If your developers are interfacing with the GitHub CLI instead of the MCP and they read some subscriptions on a public GitHub comment, then that description or that comment on that issue or pull request has a non-zero chance to be allocated into the context window and boom you're compromised. It would be beneficial to have a standard that allows all harnesses to enable or disable MCP servers or tools within an MCP server, based on the stage of the SLDC workflow. For example, if you're about to start work, you'll need the Jira MCP. However, once you have finished planning, you no longer need the Jira MCP allocated in the context window. The less that is allocated, the less risks that exist, which is the classical security model of least privilege.

ghuntley.com