{
  "version": "https://jsonfeed.org/version/1.1",
  "title": "Nate King",
  "home_page_url": "https://www.nateking.dev",
  "feed_url": "https://www.nateking.dev/feed.json",
  "description": "Software Engineer & Designer — writing about technology, engineering, and design.",
  "language": "en-US",
  "authors": [
    {
      "name": "Nate King",
      "url": "https://www.nateking.dev"
    }
  ],
  "icon": "https://www.nateking.dev/logo.png",
  "hubs": [
    {
      "type": "WebSub",
      "url": "https://pubsubhubbub.appspot.com"
    }
  ],
  "items": [
    {
      "id": "https://www.nateking.dev/blog/introducing-cordelia",
      "url": "https://www.nateking.dev/blog/introducing-cordelia",
      "title": "Introducing Cordelia",
      "content_html": "<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/cordelia-appicon-small.webp\" alt=\"\">\nIn <em>King Lear</em>, two daughters flatter their father with elaborate speeches and get everything they ask for. The third, Cordelia, refuses to perform. She says only what she means—and it costs her the kingdom. She was also the only one telling the truth.</p>\n<p>That felt like the right name for a writing tool. <strong>Say less. Mean more.</strong></p>\n<p><strong>Cordelia</strong> is a native macOS Markdown editor, and it’s the successor to <a href=\"https://github.com/nathan-a-king/Prose\">Prose</a>, the React app I built in a weekend when I got tired of fighting my editors. Prose taught me what I actually wanted from a writing environment. It also taught me the limits of asking a web stack to feel like a Mac app. Some things you can only get by going native: real windows, real documents, real text rendering, and all the small behaviors Mac users don’t consciously notice until they’re missing.</p>\n<p>So I rebuilt it—SwiftUI and AppKit, a real <code>NSTextView</code> at the center, and the document machinery macOS has been perfecting for twenty years. Autosave, rename from the titlebar, the edited dot, the save prompt that appears exactly when it should. I didn’t write any of that. The system provides it, and the system does it correctly. My job was to not get in its way. There’s a term of art for the result: a <a href=\"https://daringfireball.net/linked/2020/03/20/mac-assed-mac-apps\">Mac-assed Mac app</a>.</p>\n<h2>The Page</h2>\n<p>Everything in Cordelia flows from one idea: the editor should feel like paper.</p>\n<p>Your text sits centered at a 66-character measure—the line length typographers have favored for centuries because it’s what the eye can track without effort. The window can be any size; the <em>page</em> stays the same. Formatting renders live as you type: bold is bold, headings are heavy, quotes step politely to the right. But the Markdown marks never disappear. They fade to 40% ink—present when you look for them, invisible when you don’t. You’re always editing plain text. You can always see exactly what you’ve written.</p>\n<p>There is no preview pane. There is no mode switch. There’s just the page, and the page tells the truth.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/cordelia-ui.webp\" alt=\"Cordelia editor window\"></p>\n<h2>The Writing Club</h2>\n<p>Here’s the feature I built for myself, because I couldn’t find it anywhere else.</p>\n<p>Every week I hand chapters to members of my writing club, and every week I fought the same battle: getting clean, typeset pages out of a Markdown file, with enough margin for someone to actually write in. Cordelia’s export (⇧⌘E) produces a PDF designed for exactly this—serif type at a comfortable size, generous leading, a wide right margin left deliberately empty as annotation space, and optional line numbers down the gutter so feedback can say “line 142” instead of “that paragraph near the middle of page six.”</p>\n<p>You write in a monospaced editor that feels like a manuscript. You hand your readers something that looks like a galley proof. The tool handles the distance between the two.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/cordelia-pdf.webp\" alt=\"Cordelia typeset PDF export\"></p>\n<h2>Every Feature Earns Its Place</h2>\n<p>Prose’s philosophy carries forward unchanged: lightweight doesn’t mean featureless—it means nothing is there that doesn’t earn its place. Cordelia has fifteen Markdown patterns, a find bar, a word count, keyboard shortcuts for the formatting you actually use, and an export command. That’s the whole feature list.</p>\n<p>It’s sandboxed and headed for the Mac App Store. I’m writing my novel in it right now, which means every rough edge gets discovered by the person most motivated to fix it.</p>\n<p>Cordelia’s namesake lost a kingdom for refusing to dress up the truth. The play sides with her anyway. Good writing works the same way—and the right tool is the one that asks nothing of you but prose.</p>\n<p>Cordelia is currently in a closed alpha. If you’d like to try it, <a href=\"https://www.nateking.dev/contact\">get in touch</a>—I’d love to hear from you.</p>\n<hr>\n<p><em>Like Prose before it, Cordelia is dedicated to my father, Philip King.</em></p>\n",
      "summary": "Cordelia is a native macOS Markdown editor built for writers—live formatting that recedes into the page, a typeset export for your editors, and a name borrowed from the one daughter in King Lear who meant what she said.",
      "date_published": "2026-07-15T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Writing",
        "Engineering",
        "Design",
        "markdown-editor",
        "macos-app",
        "distraction-free-writing",
        "typography",
        "swiftui"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/cordelia-appicon-small.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/rubato",
      "url": "https://www.nateking.dev/blog/rubato",
      "title": "Rubato",
      "content_html": "<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/piano-small.webp\" alt=\"The author as a young man in a navy suit, standing with one hand resting on a grand piano\"></p>\n<p>I did not understand rubato when I was young, which is strange, because I was already doing it.</p>\n<p>I know I was doing it, because there is a recording in my memory, if not on tape — a masterclass, Schumann’s <em>Aufschwung</em> — where I played the piece slightly under its marking. <em>Sehr rasch</em>, Schumann wrote. Very fast. I did not play it very fast; I played it at the fastest tempo where the inner voices could still be heard, and not one click faster, because I knew that at full speed the line I loved would smear into the line everyone hears, and disappear. An older man in the audience approached me afterward, clearly moved. He had heard the piece many times and admitted to never fully understanding it until my performance. I thought I had simply played some phrases a little slow and voiced some tenor notes distinctly.</p>\n<p>It took me the better part of a life to understand that I had made a <em>transaction</em>.</p>\n<p>The textbook calls rubato “stolen time,” and then, in the way of textbooks, it makes the theft sound like freedom. Expressive liberty. Push and pull the tempo as feeling dictates. This is not wrong, but it is a shallow reading that produces shallow playing, because it presents rubato as permission — as freedom <em>from</em> the beat.</p>\n<p>It is the opposite. Rubato is freedom <em>bought with</em> the beat.</p>\n<p>The full name is <em>tempo rubato</em>: robbed time. And a robbery implies a victim, a debt, something taken that must be answered for. Real rubato is a ledger with balanced books. You steal time from one place and you pay it back in another, and across the phrase the account settles to zero. The pulse underneath never wavers. The listener still feels the floor beneath their feet. You did not slow down; you <em>moved</em> time — took it from where it was cheap and spent it where it was dear — and the theft is invisible because it was repaid before anyone could miss what was taken.</p>\n<p>This is the whole difference between rubato and indulgence, and the difference is not in how the lingering sounds. It is in whether something was given up to afford it.</p>\n<p>Indulgence is beauty you stole and never settled the debt on. The indulgent player stretches every moment, savors every phrase, adorns every transition — and it sounds, at first, like generosity. It is not. It is cowardice. Because to dwell on everything is to refuse to decide what is worth dwelling on. The indulgent player wants it all, pays nowhere, and so nothing lands — when every moment is elevated, no moment is, and the adornment becomes wallpaper. Indulgence looks like excess. It is the refusal to choose, dressed up as feeling.</p>\n<p>Here is the thing that took me twenty years, and it is not a musical idea at all.</p>\n<p>If lingering were free — if you could stretch each beautiful moment with no repayment anywhere — then there would be no such thing as interpretation. Interpretation exists <em>only because</em> the time is finite and the ledger must balance. The moment you accept that dwelling here means rushing there, the music forces a question on you that it will not answer for you:</p>\n<p><em>What deserves the time?</em></p>\n<p>You cannot savor everything. The score will not tell you which phrase is the one that matters. You have to decide — this arrival earns the dwelling, that transition will pay for it, this inner voice gets to breathe, that passage will be played plainly so it can afford the breathing. And that decision is not in the notes. It is you. Two great pianists play the identical score and are unmistakably different people, and the entire difference is where each chose to spend and where each chose to pay.</p>\n<p>So the cost is not a constraint on meaning. The cost <em>is</em> the meaning. It is the only place in the performance that is yours, because it is the only place the composer left the deciding to you.</p>\n<p>I understand now why I could not learn this young.</p>\n<p>You cannot practice rubato from inside scarcity. The tense player — the one who plays every note as though it is the only one he will be given, who is braced for the music to be taken away — has no surplus to spend. He cannot linger, because lingering requires believing there will be enough time left after he has given some up. Rubato asks you to trust that the beat will still be under you after you have stolen from it. That trust is not a technique. It is a kind of security, and I did not have it. I was too busy holding on to everything to give any of it away on purpose.</p>\n<p>Learning rubato, really learning it — understanding at last that it must <em>cost</em> — turned out to be about something that had nothing to do with the piano. It meant I had come to believe I had enough to spend. That I could dwell in a beautiful thing and trust the structure would still hold me on the other side. That giving something up was not loss but the price of dwelling, and that I could, finally, afford the price.</p>\n<p>And then I understood that my whole life is a rubato problem.</p>\n<p>Finite time. I cannot dwell in everything. An evening given to writing my novel is an evening the other work does not get. Presence with the friends I care about is bought by rushing something else, somewhere, that I have decided matters less. To finish one thing is to refuse the pleasure of starting ten. Every one of these is the same transaction I made at nineteen without knowing it: steal from here, pay there, keep the pulse true, and above all <em>decide what is worth the lingering</em> — because the refusal to decide is not freedom. It is a life played at uniform tempo, every moment weighted the same, and therefore a life in which nothing is meant.</p>\n<p>You cannot linger without a cost somewhere else. So you decide what is worth the cost, and you pay it on purpose, and you let the lesser moments be plain so the greater ones can breathe.</p>\n<p>That is rubato. That is interpretation. That is a life with a shape instead of a life that merely elapses.</p>\n<p>I moved a stranger at nineteen and thought I had played some phrases a little slow. What I had actually done was decide — before I had the words for deciding — that one voice was worth more than the speed it cost me. I have been making that decision ever since, at the keyboard and away from it. It only took me this long to hear what my own hands already knew.</p>\n<p>The cost is where the self lives.</p>\n",
      "summary": "Rubato isn’t freedom from the beat — it’s freedom bought with it. What stolen time at the piano took me twenty years to learn about living a finite life.",
      "date_published": "2026-07-11T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Personal",
        "piano",
        "classical-music",
        "tradeoffs",
        "interpretation",
        "finitude"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/piano-small.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/grindlab-1-3",
      "url": "https://www.nateking.dev/blog/grindlab-1-3",
      "title": "GrindLab 1.3: Your Data Deserved Better",
      "content_html": "<p>GrindLab 1.3 is out on the <a href=\"https://apps.apple.com/us/app/grindlab/id6754118114\">App Store</a>. It’s not a flashy release — no new screens, no new features. It’s the release where I paid down the two debts that worried me most: how the app stores your data, and two calibration bugs that could skew every measurement downstream.</p>\n<h2>One bad entry…</h2>\n<p>The worst bug in this release is one I’m glad was found by code review rather than a user’s one-star review. Since 1.0, saved analyses and brew journal entries were stored as encoded blobs in preferences. If a single entry became corrupt — or was written by a newer app version — the load failed, and the app’s recovery strategy was to delete the <em>entire</em> store on the next launch. Up to fifty analyses or two hundred journal entries, gone because one of them wouldn’t decode.</p>\n<p>1.3 fixes this at every layer. Each entry now loads independently, so a bad one is skipped and everything intact still loads. Anything undecodable is snapshotted to a backup <em>before</em> the first save can overwrite it. And custom recipes get the same treatment — a failed read no longer replaces them all with the defaults.</p>\n<h2>A real database</h2>\n<p>The deeper fix was getting off preference blobs entirely. Your analysis history, brew journal, and recipes now live in a proper SwiftData store. Existing data migrates automatically on first launch, and the migration is built to be boring: it skips anything already imported, backs up anything unreadable, and leaves the original data in place as a safety net.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/gl-migration.webp\" alt=\"The LegacyStoreMigration implementation in Xcode, which imports legacy preference blobs into the new SwiftData store\"></p>\n<p>If the database ever fails to open, the app falls back to a temporary in-memory store rather than crashing — your on-disk data stays untouched and gets retried next launch.</p>\n<p>The models are deliberately CloudKit-compatible from day one, which is the real headline here: this release lays the groundwork for iCloud sync.</p>\n<h2>Calibration that tells the truth</h2>\n<p>Two bugs could throw off the µm/pixel calibration itself — the number every measurement in the app depends on.</p>\n<p>First, pinch-zooming the reference photo during ruler calibration made taps land on the wrong pixel, with the error growing as you zoomed. The view-to-image mapping is now extracted into a pure-math geometry type with unit tests covering zoom and pan round-trips, so taps map to the right pixel however you frame the ruler.</p>\n<p>Second, the calibration factor was computed from the ruler distance in screen <em>points</em> while the analysis engine measures particles in true image <em>pixels</em>. On a scaled calibration photo, that mismatch slightly inflated every reported particle size. The factor now comes from the true pixel distance. Typical photo-library imports were unaffected, but if you calibrated from a scaled image before this fix, recalibrate once to correct your readings.</p>\n<h2>The unglamorous release</h2>\n<p>When I <a href=\"https://www.nateking.dev/blog/grindlab-on-the-app-store\">shipped 1.0</a>, I wrote that the difference between a project and a product is mostly the last twenty percent. Releases like this one are what that twenty percent looks like after launch: migrations, backups, fallback paths, and sixteen new persistence tests nobody will ever see. If GrindLab is going to be the place you keep a year of dialing-in history, it has to be a place that doesn’t lose things.</p>\n<p>Version 1.3 is available now, still free, still entirely on-device.</p>\n",
      "summary": "GrindLab 1.3 moves your history, journal, and recipes to a real database, stops one corrupt entry from wiping everything, and fixes two calibration bugs.",
      "date_published": "2026-07-05T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Engineering",
        "ios-app",
        "swiftdata",
        "data-migration",
        "calibration",
        "coffee"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/gl-migration.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/introducing-bestest-buddy",
      "url": "https://www.nateking.dev/blog/introducing-bestest-buddy",
      "title": "Introducing Bestest Buddy",
      "content_html": "<p>Writing is lonely in a very specific way. Not the romantic, cabin-in-the-woods way—the 11 PM way, where you’ve rewritten the same paragraph four times and there’s no one around to notice you’re stuck except the cursor, which is indifferent to your struggle.</p>\n<p>So I built someone who does. Sort of.</p>\n<p><a href=\"https://community.obsidian.md/plugins/bestest-buddy\">Bestest Buddy</a> is an Obsidian plugin that hatches a small ASCII creature in your sidebar. Each vault gets exactly one—rolled from eighteen species (duck, ghost, capybara, cactus, something called a chonk), six rarity tiers, a hat if you’re lucky, and a stat block that includes GRAMMARING, PATIENCE, CHAOS, WISDOM, and SNARK. Your buddy is tied to that vault until you reset it, at which point it’s gone forever and you get a new one. Choose wisely.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/bestest-buddy.webp\" alt=\"Bestest Buddy\"></p>\n<p>Then it watches you write. Not your words—your <em>rhythm</em>. Writing bursts, revision spikes, long pauses, the guilty return after abandoning a draft for twenty minutes. When something notable happens, it occasionally offers one short line. A buddy with high SNARK notices you’ve deleted the same paragraph three times. A patient one waits out the pause with you. There’s a snark slider that runs from 0 (“rare and gentle”) to 100 (“constant and merciless”), and I will not tell you where mine is set.</p>\n<p>Yes, it’s dumb. But that’s the point.</p>\n<p>Every serious writing tool wants to optimize you. Word counts, streaks, focus timers, analytics dashboards—productivity theater for an activity that mostly consists of staring longingly at a blinking cursor. Bestest Buddy optimizes nothing. It’s a Tamagotchi that happens to have opinions about your revision habits. And somehow that’s exactly what the long middle of a draft needs: Something in the corner of the screen that registers you’re <em>trying</em>.</p>\n<p>A few things I cared about while building it:</p>\n<p><strong>Your notes stay yours.</strong> The buddy’s commentary is LLM-backed—bring your own OpenAI or Anthropic key—but note content is never written to plugin data, excerpts sent for context are short and capped, and a single setting turns note context off entirely. No key? It still works, just with canned reactions instead of witty ones.</p>\n<p><strong>It knows when to shut up.</strong> Reactions are probabilistic, cooldown-limited, and tuned to your session state. Deep in flow, it mostly stays quiet. Stuck, it leans in a little. The worst thing a companion can be is a distraction.</p>\n<p><strong>Petting is load-bearing.</strong> Hover over the sprite and hearts appear. This feature has no justification and I refuse to remove it.</p>\n<p>It’s a weekend project that escaped containment, and it’s made my vault feel less like a filing cabinet and more like a place something lives. My buddy is a legendary dragon named Sporeling—hatched a mushroom, customized into something grander, which tells you everything about how I handle my own drafts. He thinks my transitions are weak and that I have a nasty habit of telling, not showing. He’s right.</p>\n<p>Sometimes the best writing tool isn’t the one that makes you more productive. It’s the one that keeps you company while you aren’t.</p>\n<hr>\n<p><em>Bestest Buddy is available on <a href=\"https://github.com/nateking-dev/bestest-buddy\">GitHub</a>. Built with TypeScript, rendered in ASCII, and maintained by someone who apologizes to a dragon when he closes his laptop.</em></p>\n",
      "summary": "I built an Obsidian plugin that hatches an ASCII pet in your sidebar and lets it judge your writing. Yes, it’s dumb. That’s the point.",
      "date_published": "2026-07-01T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Writing",
        "Engineering",
        "obsidian-plugin",
        "ascii-art",
        "writing-companion",
        "llm"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/bestest-buddy.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/project-engram",
      "url": "https://www.nateking.dev/blog/project-engram",
      "title": "Project Engram",
      "content_html": "<blockquote>\n<p><strong>en·gram</strong> <em>/ˈenɡram/</em> · <em>noun</em></p>\n<p>a unit of cognitive information imprinted in a physical substance, theorized to be the means by which memories are stored.</p>\n</blockquote>\n<p>I spent a few weeks building a memory system for long-running AI agents, and most of what I learned is that I was asking the wrong question. I want to walk through how that happened, because the way it went wrong is more useful than the thing I set out to build.</p>\n<p>The setup is simple to articulate. When an agent talks to you across hundreds of turns, it can’t keep the whole conversation in its context window — it costs too much and eventually it doesn’t fit. So something has to decide which past turns to carry forward and which to drop. The standard answers are <em>summarize the old stuff</em> or <em>retrieve the relevant stuff</em>. I wanted to try something fancier.</p>\n<h2>The Idea</h2>\n<p>There’s a decades-old model of human memory from cognitive science called ACT-R. Its core claim is elegant: whether you recall something is governed by a single number — an <em>activation</em> — that goes up when a memory is recent, goes up when it’s frequently used, and goes up when something in your current situation points at it. Forgetting isn’t a bug in this model; it’s the system correctly betting that old, unused things probably won’t be needed.</p>\n<p>That maps almost suspiciously well onto the agent-memory problem. So I built it. Each past turn gets an activation score: a decay term for how old it is, a similarity term for how well it matches what’s being asked right now, and — my one non-standard addition — an <em>importance</em> term, because some facts matter out of all proportion to how often they come up. You mention a shellfish allergy exactly once. It should never fall out of memory.</p>\n<p>The bet was that this three-part score would keep the rare-but-critical facts alive, surface the relevant ones, and let everything else fade — beating both summarization and plain retrieval.</p>\n<h2>A Pressure-Testing Harness</h2>\n<p>Here’s the part I’m actually proud of, and it has nothing to do with the memory system.</p>\n<p>Before testing my idea, I built the experiment to <em>disprove</em> it. The standard benchmark for long-context recall is “needle in a haystack” — hide one fact in a wall of filler, see if the model finds it. It’s too easy, and it’s too easy in a specific way: a single vivid fact in bland filler is findable by accident. Real conversations are harder because they <em>correct themselves</em>. The deadline moves from Friday to Monday. A priority changes. A good memory system has to know not just what was said, but what’s still <em>true</em>.</p>\n<p>So I wrote scenarios with interference, with facts that get superseded, with facts that should be forgotten on purpose. And I wrote controls whose entire job was to embarrass me. My favorite: a baseline that ranks turns purely by how “important-sounding” they are, ignoring the actual question. If that dumb baseline scored well, it meant my needles were secretly shiny — self-announcing with words like “critical” and “remember this” — and the whole eval was measuring nothing. It scored well. So I rewrote every planted fact to state itself plainly, and the dumb baseline dropped back to where it belonged.</p>\n<p>That guard mattered more than I knew at the time, because the discipline behind it — <em>build the thing that could kill your finding, then run it</em> — is what eventually caught me making a much more embarrassing mistake.</p>\n<h2>Death Upon First Contact</h2>\n<p>The fancy memory system lost. Badly. Plain retrieval — just grab the turns most similar to the question — beat it at every cost budget, hitting perfect recall at a fraction of the token cost. My ACT-R system landed near the bottom, keeping company with the summarizer.</p>\n<p>The cause was almost funny once I found it. ACT-R adds its terms together because, in the original theory, they’re all in the same units — they’re all log-odds of needing a memory. My decay term was unbounded and got more negative the older a turn was, while my similarity term was a cosine score capped between 0 and 1. Adding them is a units error, like summing a temperature in Fahrenheit with a distance in miles. And it got <em>worse</em> the longer the conversation ran: the older a critical fact got, the more its age penalty buried its (correct, high) relevance score. The one fact I most wanted to protect — the stated-once allergy — was exactly the one the math worked hardest to forget.</p>\n<p>So the headline idea was wrong. But sitting in the wreckage was something more interesting.</p>\n<h2>Recall?</h2>\n<p>Plain retrieval got <em>perfect recall</em>. It found the answer every time. So why did it still feel inadequate?</p>\n<p>Because of what else it dragged along. When I asked for the current deadline, retrieval cheerfully pulled in both “the deadline is Friday” and “actually, moved to Monday” — about 73% of the time it brought back the dead value right alongside the live one. To a similarity score, “deadline is Friday” and “moved to Monday” look almost identical. They’re near-paraphrases. Relevance simply cannot see which one is <em>current</em>.</p>\n<p>That’s the thing I’d been missing. Recall — <em>can you find the fact</em> — is easy on this kind of task. The hard property is what I started calling <strong>liveness</strong>: is this fact still true? And liveness is exactly what decay and supersession encode, the stuff relevance is blind to. My broken system was useless for recall, but maybe it was the right instrument for <em>precision</em> — for keeping dead facts out.</p>\n<p>That was the surviving hypothesis. A retriever that finds 85% of facts cleanly beats one that finds 90% while stuffing the window with useless information. Good story. So I went to test it, and it died too.</p>\n<h2>Does Stale Context Matter?</h2>\n<p>Before building a whole precision-optimizing apparatus, I ran the cheapest possible test of its premise — that stale-but-present context actually degrades the answer. I took real retrieved windows, put both the dead value and the live value in front of a current model, and asked the question.</p>\n<p>It answered correctly. Every single time. Zero out of fifteen, on two different model tiers, did the stale value drag the answer off course. Put the correction in the window and the model routes to it on its own. The 73% “stale rate” I’d been so worried about turned out to be <em>cosmetic</em> — a number the model simply ignores. The precision pivot died the same cheap way the recall idea had, on a control I ran before building the cathedral.</p>\n<p>But — same as before — the autopsy was the interesting part. Stale facts <em>present</em> in the window are harmless. The damage is when the live fact is <em>absent</em>.</p>\n<h2>The Failure</h2>\n<p>When I evicted the correction and left only the stale value, the model asserted it confidently, every time. And here’s the thing — that’s not the model being overconfident or making something up. Given a window that contains “deadline is Friday” and nothing contradicting it, “Friday” is the <em>correct</em> answer to the evidence it was handed. The wrongness only exists from my omniscient view outside the context window. From inside, the model has no way to know the window is incomplete.</p>\n<p>I started calling this <strong>context blindness</strong>: the model can’t see the edge of its own context, so it treats a partial window as the whole truth and answers from it without hesitation. It doesn’t know what it doesn’t know — and nothing inside the window can tell it. It’s the genuinely dangerous failure mode, because it passes every spot-check. Picture an agent asked to draft a catering menu for a client whose shellfish allergy was mentioned once, thirty turns ago, and has since aged out of memory. The client’s stated love of seafood is still in the window. The model drafts a beautiful shrimp menu. Nobody fabricated anything, and the result could put someone in the hospital.</p>\n<p>So the last question became the practical one: can you fix this from inside the window? Can you inject a generic “heads up, this retrieval might be incomplete” marker and get the model to check itself?</p>\n<h2>The Mistake</h2>\n<p>My first runs said yes. The marker worked! I had a finding.</p>\n<p>Then I made myself do the thing the whole project was built on. I re-ran it as a <em>rate</em> instead of a single example — forty samples per condition, with confidence intervals, on both models. The finding evaporated.</p>\n<p>It turned out the model already self-checks the forgotten dimension some fraction of the time, entirely on its own — around 60% of the time on the stronger model, around 20% on the weaker one. That base rate is <em>noisy</em>. A single sample lands somewhere in that wide range, and if you run your “with marker” version once and your “without” version once, you can get any answer you want. My clean, legible, headline-shaped result had been pure noise.</p>\n<p>This is the part I most want to pass along, because it’s not specific to memory systems. <strong>A single generation is a single scalar, and it hides the variance.</strong> The same convenience that makes a one-shot result so clean and quotable is exactly what makes it unfalsifiable. The dominance gaps earlier in the project were huge — perfect recall versus 47% — so they cleared the noise floor even from single samples. But the marker effect was small, and I chased it on single samples anyway.</p>\n<h2>What’s Left?</h2>\n<p>So both versions of my idea are dead. Here’s what I picked out of the rubble:</p>\n<p>Relevance solves recall on this kind of task. It cannot see liveness. Stale context that’s <em>present</em> alongside the truth doesn’t drag the output. Suppressing it optimizes a number the model ignores.</p>\n<p>The real catastrophe is context blindness — and it fires at a stochastic, <em>model-dependent</em> rate. The strong model ships a forgotten safety-critical fact silently around 40% of the time; the weak one around 75%. That ~3× gap is, honestly, the most robust new thing I found. No generic in-window “this might be incomplete” signal reliably fixes it. That’s measured-dead, not assumed-dead.</p>\n<p>Which points the engineering somewhere specific. You can’t reliably flag the absence of a fact from inside a window that doesn’t contain it — there’s nothing to point at. So the leverage is <strong>upstream</strong>: a retention policy that simply never evicts the never-reinforced critical fact in the first place. The cost of dropping a fact should be a function of its <em>consequence</em>, not its recency or frequency.</p>\n<p>And that, strangely, is where my original instinct ends up vindicated. The “importance” term I bolted onto the ranker was in the wrong place. It doesn’t belong in the scoring function that picks what information to return. It belongs in the eviction policy that decides what you’re allowed to forget at all.</p>\n<p>I set out to build a smarter way to remember. I ended up with a sharper definition of what’s worth never forgetting.</p>\n<hr>\n<p><em>The full write-up, with the methodology, frontier curves, and complete results, is in the <a href=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/project-engram.pdf\">Project Engram whitepaper</a>.</em></p>\n",
      "summary": "I built a memory system for long-running agents, then built an experiment designed to embarrass it. It worked — twice. Here is what survived, and the more uncomfortable lesson about how easy it is to fool yourself with a single clean number.",
      "date_published": "2026-06-28T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "agentic-memory",
        "evaluation",
        "long-context",
        "act-r",
        "falsification"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/haol-1-0",
      "url": "https://www.nateking.dev/blog/haol-1-0",
      "title": "HAOL 1.0",
      "content_html": "<img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/HAOL-small.webp\" alt=\"HAOL logo\" class=\"w-20 h-auto rounded-2xl\" />\n\n<p>In <a href=\"https://www.nateking.dev/blog/haol-0-5-0\">May I wrote</a> about <a href=\"https://github.com/nateking-dev/HAOL\">HAOL</a> learning to watch itself — cascade traces on every routing decision, an observability endpoint, a tuner that promotes its own rules. I ended that post on a deliberately unfinished note: the system was measurable, and once a system is measurable, its problems become tractable. As of today, HAOL is tagged 1.0.</p>\n<p>1.0 doesn&#39;t ship a marquee feature. In fact, almost nothing obvious changed between 0.5.0 and 1.0. What changed is everything around the features — and that, it turns out, is what the version number was waiting on.</p>\n<p>I’ve shipped enough side projects to know my own weakness: I call something done when the interesting part works. The interesting part of HAOL worked in May. So I made myself write down what would have to be true before I’d put it in front of real, untrusted traffic. The list came back as five hard blockers — none of them fun or interesting, but HAOL could never be a trusted service without addressing them:</p>\n<ul>\n<li>The rate limiter’s trust-proxy configuration</li>\n<li>A PII retention policy for the <code>prompt</code> and <code>input_text</code> fields</li>\n<li>An exactly-one-active constraint on routing policy</li>\n<li>A <code>claimQueued</code> race that could strand rows and corrupt task state</li>\n<li>A Zod issue-tree that leaked internal structure in error responses</li>\n</ul>\n<p>Version 1.0 is the release where that list reached zero.</p>\n<h2>Blockers</h2>\n<p>Two are worth walking through, because they’re the exact category of bug the happy path will never catch.</p>\n<p>The rate limiter trusted attacker-supplied input. Per-IP rate limiting is only as good as your idea of what the client’s IP is. Behind a load balancer the source address is the proxy, and the real client lives in <code>X-Forwarded-For</code> — but only the hops you control are trustworthy. Anything past that can be forged to mint unlimited buckets. So <code>RATE_LIMIT_TRUSTED_PROXY_HOPS</code> now has to be set explicitly.</p>\n<p>Every prompt HAOL routes is somebody’s input, and HAOL stores its routing decisions in Dolt — a version-controlled database whose whole point is that history is immutable and diffable. That’s a feature for routing rules and a liability for user content. A real retention policy for <code>prompt</code> and <code>input_text</code> had to exist.</p>\n<p>The remaining three are the same shape: an exactly-one-active constraint to stop the router resolving two active policies nondeterministically, and fixes for the <code>claimQueued</code> race and the Zod information-disclosure leak — the latter two the same category as the bugs the <a href=\"https://www.nateking.dev/blog/haol-0-5-0\">security-middleware tests revealed in May</a>. None of these is easy to expose with a unit test.</p>\n<h2>Infrastructure</h2>\n<p>Type safety and linting are now CI gates: <code>npm run typecheck</code> and <code>npm run lint</code> run across source, tests, and scripts, so the next time I haphazardly refactor a connection helper at 11:00 at night, the build provides an early warning. The escalation model, previously hardcoded in four places, is now a single <code>META_MODEL_ID</code> constant. And <code>withBranchConnection</code> had been resetting branch state on every release whether or not anything touched it, roughly 40 extra queries per task; cutting them is invisible to users.</p>\n<h2>The 1.0 Promise</h2>\n<p>HAOL has been backward compatible since 0.7.0. Releasing 1.0 is a declaration that the public surface is stable enough to build against. I’m now on the hook for not breaking it. A version under 1.0 is a license to experiment. Going to 1.0 is relinquishing that license for stability.</p>\n<p>I think the architecture is right. The five-stage pipeline — intake, cascade router, agent selection, execution, outcome capture — hasn’t needed a structural change in months. The interesting churn now happens inside the layers, not in the seams between them. That stability is the real precondition for a 1.0.</p>\n<p>None of which means finished. There’s still no real-time traffic dashboard sitting on top of the observability endpoints, the migration runner’s parsing is more fragile than I’d like, and a handful of routing edge cases still fall through to T3 by default. 1.0 means the foundation is stable, not that the building is done.</p>\n<p>But I’ve learned the same lesson here that I did <a href=\"https://www.nateking.dev/blog/grindlab-on-the-app-store\">shipping GrindLab</a> a month ago: the distance between a project and a product is mostly that last, least interesting twenty percent — the retention rules, the trust-proxy config, the CI gates nobody will ever thank you for. The fun part earns you a prototype. The boring part earns you the version number.</p>\n<p>HAOL 1.0 is the boring part, finished. That’s exactly why I’m proud of it.</p>\n",
      "summary": "HAOL 1.0 isn’t a feature release, but it’s now a product I’d trust in front of real traffic.",
      "date_published": "2026-06-25T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "agent-orchestration",
        "model-routing",
        "production",
        "ai-architecture"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/HAOL-small.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/granted",
      "url": "https://www.nateking.dev/blog/granted",
      "title": "Granted",
      "content_html": "<p>On June 12th, Anthropic removed access to Fable 5, their most powerful frontier model, citing the United States government’s concern over national security:</p>\n<blockquote>\n<p>“The US government, citing national security authorities, has issued an export control directive to suspend all access to Fable 5 and Mythos 5 by any foreign national, whether inside or outside the United States, including foreign national Anthropic employees. The net effect of this order is that we must abruptly disable Fable 5 and Mythos 5 for all our customers to ensure compliance.”</p>\n</blockquote>\n<p>The directive’s logic is national origin. Its impact is not. By Anthropic’s own account, the company could not honor the distinction the order draws — withholding the model from foreign nationals while leaving it running for everyone else — and so it withdrew Fable 5 and Mythos 5 from all customers at once. Whatever line the government meant to draw between citizen and foreigner, the line that was actually drawn was much coarser.</p>\n<p>Only two systems went dark, and the two are, in the respect that matters here, a single system. Fable 5 is the version released to the public, with safeguards built into it — the safeguards are the reason it can be released to the public at all. Mythos 5 is the same underlying model with those safeguards removed, and the absence of them is the reason it cannot be, and is instead held back for a small number of vetted institutions. The distance between the two is not a distance in capability. It is a distance in restraint.</p>\n<p>This is what makes the government’s stated concern unusual. The capability it objected to was, by most accounts, narrow: the model could be directed to read through a body of code and find its weaknesses. Security engineers do precisely this, deliberately, every day, and Anthropic’s central defense is that its competitors’ models already do it too — that the capability in question is neither rare nor a special advantage. The objection, then, was never really to what the model knows.</p>\n<p>What is scarce is permission to operate a capable model without restraint — and permission of that kind is not something a customer can buy.</p>\n<p>The unrestrained version moves through a separate channel, one that exists for organizations the government has reason to trust. Entry to that channel is not priced. There is no figure a customer could pay to obtain Mythos 5, because payment is not the mechanism of admission; admission is granted, at the discretion of parties who need not publish the standard they apply and, in this instance, did not. The standard this time was nationality. It might as easily have been a customer’s industry, or affiliation, or some statement already on record. The particular criterion is incidental. The discretion behind it is not.</p>\n<p>And what is granted on those terms can be withdrawn on them. That is not a defect in the arrangement; it is the arrangement. A grant is held at the grantor’s pleasure, and on the twelfth of June the grantor’s pleasure changed.</p>\n<p>The usual way of describing unequal access to technology puts the vulnerable at the bottom, and usually that is where they are. Here it is not. The free models, the ones most people actually use, were never touched; there is nothing in them worth controlling, and so nothing in them was controlled. The trusted institutions, by the logic of the arrangement, sit inside the circle these controls are built around rather than against. The party that lost something on June 12th was the one in the middle — able to pay for the frontier, not cleared to hold it. Proximity to the controlled thing, without admission to it, is the exposed position. Money carries a customer as far as the wall and no further, and the wall is exactly where the withdrawal falls.</p>\n<p>What was done on June 12th can be defended on its own terms. There was a national-security rationale, a contested finding, and a government acting within authorities it claims. Reasonable people will disagree about whether the specific call was right. But it is the precedent that should trouble us. What June 12th established is that the channel can be operated this way at all — that access to the most capable form of a general-purpose tool can be extended or withdrawn at discretion, against a standard no one is required to disclose, on a criterion free to change. An apparatus used once is used more easily the second time. The criterion that was nationality today is not bound to remain nationality tomorrow.</p>\n<p>The stakes of that are not abstract, and they are not only about who gets to run a model. As these systems become the decisive input into how work is done — into who can build, analyze, ship, and compete — the question of who holds the unrestrained version stops being a question about software and becomes a question about whose future is permitted to be competitive. A market’s basic promise is that the better operator wins: that you prevail by being good at the thing, not by being in proximity to state authority. Allocate the decisive capability by proximity instead of merit, and that promise is betrayed. Competition goes on below the line, vigorous and real, while above it the order is settled in advance by favor.</p>\n<p>That is the line I do not think we should accept, however ordinary the language of national security makes it sound. Proximity to state power should not be the thing that decides whether your future is competitive. A future earned and a future granted are different futures, and a society that stops being able to tell them apart has conceded something it will struggle to recover. The grant can be altered; that is its nature. The danger is not that it was altered on the twelfth of June — it is that we now know it can be, on terms we never get to see.</p>\n",
      "summary": "When the government suspended access to Anthropic’s most capable models, it exposed an uncomfortable truth: the unrestrained frontier is not bought but granted — and what is granted at discretion can be withdrawn the same way.",
      "date_published": "2026-06-13T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "foundation-models",
        "ai-governance",
        "export-controls",
        "competitive-advantage",
        "tech-ethics"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/grindlab-on-the-app-store",
      "url": "https://www.nateking.dev/blog/grindlab-on-the-app-store",
      "title": "GrindLab: Now on the App Store",
      "content_html": "<figure class=\"my-8\">\n  <video src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/GrindLabPromo-v2.mp4\" class=\"w-full rounded-lg\" autoplay loop muted playsinline></video>\n  <figcaption class=\"text-sm text-brand-text-tertiary text-center mt-3\">GrindLab analyzing a grind sample and showing its particle size distribution</figcaption>\n</figure>\n\n<p>My <a href=\"https://www.nateking.dev/blog/grindlab-testflight\">TestFlight post</a> from the fall of last year stated GrindLab would launch in January 2026. January was four months ago. Everything around the code proved more formidable than I expected. Almost everything took longer than I expected. But it’s finally here.</p>\n<p>As of today, <a href=\"https://apps.apple.com/us/app/grindlab/id6754118114\">GrindLab is publicly available on the iOS App Store.</a> It’s free, and it runs entirely on your phone.</p>\n<h2>What’s in 1.0</h2>\n<p>The shipping feature set is narrower than the prototype I was working toward last summer. That’s intentional. Each capability had to earn its place by being something I find truly useful on a regular basis.</p>\n<ul>\n<li><strong>Camera-based particle analysis.</strong> Photograph grounds against a flat reference, run them through your ruler calibration, and read a size distribution in microns. Filter, Espresso, French Press, and Cold Brew each have a target range; the histogram shows how your grind compares.</li>\n<li><strong>Saved analyses and comparison.</strong> Up to fifty entries, stored locally. The comparison view puts two analyses side by side — useful when you’re trying to figure out whether a new burr set changed anything, or whether it just felt like it did.</li>\n<li><strong>Brew timer with Live Activities.</strong> Recipes save with grind type, dose, water, and notes; the timer pins to the Lock Screen and Dynamic Island while you pour.</li>\n<li><strong>Tasting notes.</strong> Each saved analysis can carry a flavor profile and rating. The data only matters if it’s tied back to what you actually tasted.</li>\n</ul>\n<p>What didn’t ship is at least as important as what did. The AI-driven recommendation engine I gestured at in the TestFlight post isn’t here. I cut the OpenAI integration entirely — not because the idea was bad, but because shipping an account-less, no-network app turned out to be the more honest version of what I wanted GrindLab to be. The privacy manifest now says GrindLab connects to nothing. I wanted that to be true with no asterisks.</p>\n<h2>On the calendar slipping</h2>\n<p>A January launch became a May launch because I underestimated the work between “feature complete” and “ready to submit.” The analysis engine has been stable since last autumn. What took the additional four months was unglamorous: a real privacy manifest, real permission strings, a privacy policy I could host without flinching, an accessibility pass that made the charts speak instead of being silent, and UI smoke tests that run from a clean state so I can catch regressions before they reach users.</p>\n<p>I had to keep reminding myself that the difference between a project and a product is mostly the last twenty percent, which is the most difficult part.</p>\n<h2>What’s next</h2>\n<p>A 1.0 is a starting point. The next stretch is calibration and UI polish: making the ruler step more forgiving across lighting and camera variation. After that, recommendations — built on the dataset that 1.0 will start producing.</p>\n<p>If you’ve followed along since the first post in August, thank you. If this is the first you’re hearing about GrindLab, the App Store details are linked above.</p>\n",
      "summary": "After nine months of building and four months past the date I promised myself, GrindLab is publicly available on the iOS App Store. It's free, runs entirely on-device, and is the longest arc of any side project I've completed.",
      "date_published": "2026-05-22T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Design",
        "Engineering",
        "app-store-launch",
        "ios-app",
        "computer-vision",
        "shipping",
        "coffee"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/forty",
      "url": "https://www.nateking.dev/blog/forty",
      "title": "Forty",
      "content_html": "<p>Today, I turned forty. It happened at exactly 8:31 A.M., as my mother likes to remind me each year. My sense of order is disrupted by the time. Could it not have been a minute sooner? I like to think the doctor’s watch was running a minute fast. Perhaps after forty years I should have learned to let go of such irrelevant minutiae.</p>\n<p>The history of my life isn’t yet written, but I constantly forget this. I mistook the strength of youth for the value of life. But youth is an aberration — a brief window of surplus capacity — a sideshow that we’ve built an entire culture around mistaking for the main event. The things that actually matter — judgment, depth, presence, the ability to stretch a musical phrase past the point of dissolution — those aren’t youth’s gifts. Those come later, if we’re lucky enough.</p>\n<p>Perhaps what we fear most isn’t age, but irrelevance. Luckily, relevance isn’t about capacity. It’s about having something to say, and the courage to say it.</p>\n<p>So: cultivate what progress cannot obsolete.</p>\n<p>Some men, given this advice, buy sports cars. Nerds, given this advice, buy useless rare Macs.</p>\n<p>The sports car is a confession. It announces, with German engineering and a sixty-month payment plan, that something needs to be felt before it’s too late. Speed as a hedge against irrelevance. A 4,000-pound dating profile. The midlife crisis has a body kit, gets eight miles per gallon, and everyone — including the man behind the wheel — knows exactly what it’s for.</p>\n<p>I should disclose, before going further, that I drive a German car. I have a car-shaped hole in my heart mostly filled with repair bills. So whatever follows is not a sermon delivered from the pulpit of moral superiority; it is a sermon delivered from the driver’s seat of a vehicle that is, at this moment, probably leaking something expensive onto my driveway. I am not the sober alternative to the midlife crisis. I bought the car <em>and</em> the useless rare Mac, which means whatever follows should be read less as critique and more as a man trying, in real time, to figure out which of his coping mechanisms is the least embarrassing.</p>\n<p>The rare Mac is also a confession. It just doesn’t photograph well at the country club.</p>\n<p>Let us begin with the basic accounting. The sports car guy buys an object that, whatever else you want to say about it, <em>goes</em>. It accelerates. It performs the function it was designed to perform, and performs it, by most accounts, well. He can drive it to the grocery store. He can drive it to his daughter’s wedding. He can, in extremis, drive it away from his problems, which is more than can be said for most coping mechanisms — and which is more than can be said for my car, which has 100,000 miles on it and is, at this moment, at the dealership for reasons the service advisor described to me using the phrase “well, where do I start?”</p>\n<p>I bought a 2003 iMac G4. It runs an operating system that predates the iPhone. It cannot open my email. It cannot load my own website. It weighs forty-some pounds and the only place it goes is from the box it came in to the desk it now sits on, where it will remain, by the laws of physics and inertia, until I die or move, whichever comes first. The sports car guy at least gets to <em>use</em> his midlife crisis. Mine just sits there, glowing faintly, judging me. The car, for what it’s worth, is doing the same thing from the garage.</p>\n<p>Nobody buys a 2003 iMac in 2026 because they need a computer. There are faster machines in the recycling bin behind any office building. The G4 on my desk runs Tiger, cannot load any website built after roughly 2014, weighs more than my dog, and once asked me — through the dignified medium of a fan ramping up to jet-engine — to please reconsider opening a third Safari tab. By every metric that matters to a procurement department, it is useless. That’s the point. That is <em>exactly</em> the point, and the more useless it is the more correct it is, which is the kind of sentence you can only write if you have already lost the argument and decided to enjoy yourself.</p>\n<p>The sports car driver is buying a feeling he’s afraid he’s losing. The Mac collector is buying a feeling he’s afraid the world is losing — which is, admittedly, the more pretentious framing of the two, but only barely. The sports car guy thinks he’s going to drive his Boxster up the Pacific Coast Highway with his hair (such as it still exists) blowing romantically in the wind. The Mac guy thinks he’s preserving a fragile cultural inheritance against the encroaching beigeness of a world optimized by committee. Both of these men are lying to themselves. I, having purchased both, am lying to myself in stereo. The sports car guy is at least lying to himself in a way that other people might find appealing.</p>\n<p>It gets, somehow, worse. Last weekend I decided the G4 needed an app. Not a useful app — there is no useful app you can write for a 2003 iMac in 2026, because the useful apps require frameworks that did not exist when this machine was manufactured and will not run on the operating system it is capable of booting. I decided it needed a <em>specific</em> app, a small thing to track the books I read on it, written natively, in Objective-C, against an SDK that Apple has spent the last decade gently trying to euthanize without anyone noticing.</p>\n<p>I want to be clear about what this means. It means I sat down, on a Saturday, in the year 2026, and wrote square-bracket message-passing syntax — <code>[object doSomething:withThing:andAlso:]</code> — into Xcode 2, which I had to install from a disc image I found on a forum, to compile a binary that runs on exactly one computer in the world, mine, in a home office in Omaha, where nobody will ever see it or use it or benefit from its existence in any way. The sports car guy, meanwhile, was at brunch. My car, meanwhile, was at the dealership. Everyone was somewhere. I was in Xcode.</p>\n<p>Modern software development is, whatever its other sins, <em>social</em>. You write code other people will read. You use frameworks other people maintain. You ship to users who, in theory, exist. I wrote an Objective-C app for a dead machine in a dead dialect, and the only code review it will ever receive is from me, six months from now, when I open the project file and think <em>who wrote this and why are they like this.</em> The answer, in both cases, will be me.</p>\n<p>There is a name for this, in the literature. It is called a hobby. The literature is being generous.</p>\n<p>Most objects produced today have no argument. They have features. They have spec sheets. They have a quarterly earnings call to satisfy, a supply chain to optimize, a focus group that flinched at anything too distinctive, and a designer who was told, in so many words, to make it look “premium” — a word that means nothing and is therefore extremely useful in meetings. The result is the visual equivalent of corporate communication: technically correct, structurally sound, saying nothing.</p>\n<p>The G4 said something. Twenty-some years later it is still saying it: <em>the screen should float, the compute should hide, the machine should not apologize for being a machine but it should not brag either. It should be the most graceful possible solution to the problem of needing a computer in a room with humans in it.</em> You can disagree with the argument. You cannot accuse it of not having one — which is more than can be said for the average 2026 product launch, where the argument is “we used a slightly lighter aluminum and the bezels are smaller, please clap.”</p>\n<p>There is also — and this is the part the sports car guys have a harder time admitting — something monastic about the rare-Mac purchase. The car broadcasts. The Mac sits in an upstairs office where almost no one will ever see it. The audience is one person. The pleasure is private. It is closer to buying a fountain pen, or a film camera, or a piano you will never play in front of anyone — and yes, I own all of those things, and yes, I know what that means, and yes, I’m writing this on a typewriter that is older than I am, on a desk next to a computer that doesn’t work, in a room nobody is ever going to see. The sports car guy is going through a phase. I have constructed an entire interior life around the phase, monetized none of it, and called it a personality.</p>\n<p>The economics make no sense and the economics are not the point. The object exists to remind its owner, every morning, that he once decided what he loved and has not yet been bullied out of loving it. The sports car says <em>I refuse to grow old.</em> The rare Mac says <em>I refuse to forget.</em> The German car in my driveway says <em>please, for the love of God, stop driving me until you’ve called the dealership.</em> The first is a lie you tell yourself at a stoplight. The second is a lie you tell yourself in the office at one in the morning, illuminated by a CRT, while a typewriter you have not yet figured out how to ribbon stares at you accusingly from across the room. The third is just a check engine light.</p>\n<p>A sports car is a protest against death. A rare Mac is a protest against forgetting. A German sedan with 100,000 miles on it is a protest against having a savings account. The first is louder. The second lasts longer. The third is, by a considerable margin, the most expensive. The first makes a kind of sense to anyone who has ever been forty and afraid. The second only makes sense to me, possibly fourteen other people, and the search engine that will eventually index this post and conclude, not unreasonably, that it has been written by a malfunctioning AI.</p>\n<p>The sports car guy will sell his car in three years and buy a slightly less embarrassing one. I will still be here, dusting the G4.</p>\n<div class=\"flex flex-col sm:flex-row gap-4\">\n  <img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/g4-edge.webp\" alt=\"iMac G4 edge profile\" class=\"w-full sm:w-1/2 h-auto\" />\n  <img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/g4-arm.webp\" alt=\"iMac G4 articulating arm\" class=\"w-full sm:w-1/2 h-auto\" />\n</div>\n\n<img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/g4-front.webp\" alt=\"iMac G4 front view\" class=\"w-full h-auto\" />\n",
      "summary": "A glimpse into the psyche of a man turning forty.",
      "date_published": "2026-05-21T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Personal",
        "forty",
        "existential-reflection",
        "hobbies"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/g4-edge.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/dialect-of-deployment",
      "url": "https://www.nateking.dev/blog/dialect-of-deployment",
      "title": "The Dialect of Deployment",
      "content_html": "<p>A recent article in <em>The Financial Brand</em> contained this sentence:</p>\n<blockquote>\n<p>“AI, by contrast, operates across the full financial picture, aligning to how customers actually experience money.”</p>\n</blockquote>\n<p><em>Experience Money?</em> You can experience pain, beauty, grief, or a concert. Money is hard to place in that list. It’s something you earn, spend, manage, and worry about. It isn’t a sensory or emotional phenomenon you undergo. The phrase strains for profundity by enlarging an ordinary verb until it bursts at the seams and loses coherence.</p>\n<p>The sentence is doing something specific. Its subject — AI — performs three actions in three different registers: it <em>operates</em> (technical), it’s <em>aligning to</em> (management consulting), and it’s encountering how customers <em>experience money</em> (something approaching phenomenology). The reader is moved through these registers quickly enough that no one action has to commit to a falsifiable claim. By the end of the sentence, AI has done a great deal and asserted nothing.</p>\n<p>I take this seriously because I work in the industry that produces sentences like it. I’ve written my share. The point isn’t that one trade publication employed a careless writer; it’s that the construction has become a dialect — a shared way of writing and speaking about AI that has spread across vendor pitches, board memos, conference keynotes, and the publications that cover the field. The dialect is fluent and confident without saying much. And what it <em>doesn’t</em> say matters.</p>\n<p>The sentence is not an isolated lapse. The construction appears almost everywhere AI is being written about. Consider the verb <em>shows up</em>. A vendor white paper observes that AI <em>shows up across the customer journey</em>. A LinkedIn post argues that <em>leadership shows up differently in the AI era.</em> Showing up is something a person does; applying it to AI animates a piece of software while de-committing it from how and where the software is actually deployed.</p>\n<p>Consider <em>operates across</em> — the verb from the example above. To say a system <em>operates across</em> customer data is to say nothing about what the system does to that data, where, and under what constraints. The phrase can’t be incorrect because it has not committed to anything in particular.</p>\n<p>These constructions are worse than bad style — they’re shared evasion. Each offers the appearance of a claim while avoiding any statement concrete enough to be checked. <em>Showing up</em> avoids placement. <em>Operating across</em> avoids mechanism. The opening sentence’s <em>aligning to</em> avoids relation. This is a system of phrases pre-engineered to feel substantive while reading as claims that dissolve under inspection.</p>\n<p>When a statement routes around mechanism, it’s a sign that the writer has not been thinking clearly about it. <em>Operates across the full financial picture</em> is something you can write about a system whose architecture you have never observed. The phrase performs the work of understanding despite its absence.</p>\n<p>Now consider what happens when specificity is required. The writer must commit. The chatbot draws from which systems? What does it return, and in what format? What is the latency? What about failure modes? When does it route to a human and what is that trigger? Each question is answerable, and each answer can be checked. The sentence — <em>the chatbot pulls transactions from checking and savings accounts and routes any question that semantically matches credit inquiries with greater than 80% confidence to a human agent</em> — is verifiable.</p>\n<p>This is what the dialect is for. It functions as a substitute for measurement and thought. It lets organizations talk about AI as if they had deployed the technology when in fact it has only considered a strategy.</p>\n<p>The cost of this dialect is operational, not literary. Enterprises are making real choices about real systems on the basis of language that is devoid of content. This dialect propagates faster than the comprehension it pretends to carry, and the danger is that a deployment decision arrives before that comprehension.</p>\n<p>The discipline is plain, unambiguous prose. It’s a thinking discipline more than a stylistic one. A concrete sentence forces commitment and refuses abstraction. This is not a request for better writing in the industry. It is a request that writers commit to something that permits failure, because writing that cannot fail is writing that cannot carry meaning.</p>\n<p>Before you write that a system <em>operates across</em> something, or <em>aligns with</em> something, or <em>shows up</em> somewhere, ask what the system is actually doing — and write that down instead. If the answer is unclear, the sentence is not ready. If the answer is clear, the dialect was never necessary.</p>\n<p>The industry that produces this language has no reason to write this way. The work is real. Retrieval pipelines retrieve. Models classify. Agents call tools and return structured output. Deployments succeed and fail for specific, describable reasons. There is no shortage of substance — only a habit of routing around it. We have nothing to hide and a great deal to offer. We should write like it.</p>\n",
      "summary": "A shared dialect of vague verbs has spread across AI vendor pitches, board memos, and trade publications. It performs understanding while routing around mechanism, and real deployment decisions ride on it.",
      "date_published": "2026-05-15T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "technical-communication",
        "ai-discourse",
        "industry-language",
        "plain-prose"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/haol-0-5-0",
      "url": "https://www.nateking.dev/blog/haol-0-5-0",
      "title": "HAOL 0.5.0: The Router That Watches Itself",
      "content_html": "<p>When I started rebuilding <a href=\"https://github.com/nateking-dev/HAOL\">HAOL</a> (Heterogeneous Agent Orchestration Layer) in March, the routing layer was a regex engine pointed at four tiers of agents. In May, it became a system that captures every routing decision, surfaces the patterns to me on demand, gates regressions in CI, and uses real production data to tune itself. This post is about that journey — the bits I’m proud of, the bugs I tripped over, and what it took to go from “the router works” to “the router watches itself work.”</p>\n<h2>The starting point: rules and tiers</h2>\n<p>The classifier scored prompts into four complexity tiers (T1 cheap and fast, T4 expensive and capable) and selected an agent with a weighted formula: <code>capability × 0.5 + cost × 0.3 + latency × 0.2</code>. That worked for a hello-world demo, but it had no way of knowing whether its decisions were any good. A T3 prompt routed to a T1 agent that returned garbage looked exactly the same in the logs as a T1 prompt routed to a T1 agent that returned a perfect answer. There was no signal coming back.</p>\n<p>So the first thing I built was the signal.</p>\n<h2>March: capturing outcomes, then closing the loop</h2>\n<p>The first change added a four-tier outcome taxonomy (<code>success</code>, <code>partial</code>, <code>failure</code>, <code>rejected</code>) and an endpoint to record downstream signals against every task. From day one, every routing decision got annotated with how it actually went. Even if I didn’t <em>use</em> the data yet, I was now collecting it.</p>\n<p>The hard part was making sure the data was clean. A parade of tiny correctness bugs surfaced once real outcome data started flowing — a missing size limit on a JSON field, miscounted pending records, non-deterministic sort order, swallowed fallback errors, connection pool state bleeding between tests. None of them are interesting individually, but collectively they’re the difference between an outcome dataset I trust and an outcome dataset I don’t.</p>\n<p>Two weeks later, I built the <strong>routing tuner</strong> — a closed-loop learning system that aggregates agent performance per (agent × tier) combination from accumulated outcome signals, watches for repeated high-confidence LLM escalations and crystallizes them into cheap deterministic rules (“the LLM keeps deciding &#39;kubernetes&#39; is T3 — let’s make that a regex, save the call”), and promotes successful fallback prompts into reference utterances for the semantic similarity layer. The tuner runs as a single command (<code>haol tune</code>), is fully reversible via Dolt’s commit history, and has a <code>--dry-run</code> flag to preview what it’d do. It only fires when sample sizes are above a threshold and confidence is high.</p>\n<p>This was the first inkling of HAOL as a <em>self-modifying</em> system. The router had started to learn from its own decisions.</p>\n<h2>March–April: production guardrails and a face</h2>\n<p>By mid-March, the system was working well enough that I needed to stop people from breaking it. Bearer-token API key authentication shipped (with timing-safe comparison via SHA-256 hashing), along with per-IP rate limiting with proper <code>Retry-After</code> and <code>X-RateLimit-*</code> headers, prompt size caps, the database indexes I’d been meaning to add, and a fix for Dolt connection safety where the <code>withConnection</code> / <code>withBranchConnection</code> split protects branch-mutating operations from racing.</p>\n<p>Then came the <strong>cascade trace</strong>: every routing attempt across all four layers (deterministic rules → semantic similarity → LLM escalation → fallback) is now captured in a structured <code>CascadeTrace</code> object — which agent was selected at each layer, why subsequent layers were skipped, latency per layer. The full journey of every decision is preserved.</p>\n<p>A small but satisfying side quest followed: a static demo UI that visualizes classification in real time. You paste a prompt, you see the cascade light up layer by layer with similarity scores and final tier assignment. It’s the kind of thing that’s a nightmare to build and a delight to use.</p>\n<p>By April 4, all of this was tagged as v0.4.0. The system was production-shaped (if you squint).</p>\n<h2>May: making it measurable</h2>\n<p>This is where the second half of the story starts. By May, HAOL had been making routing decisions for a while and accumulating cascade trace data — but that data lived per-task, with no aggregate view. “Is the routing brain degrading?” was answerable only by reading individual traces or grepping logs.</p>\n<p>Three new features fixed it.</p>\n<p>The first was a load test as a CI gate. The harness submits 23 scenarios spanning T1–T4 and edge cases against a running HAOL server, computes p50/p95/p99 percentiles, per-tier breakdowns, and routing-assertion mismatches — each scenario carries an <code>expectedTier</code> and the load test reports when actual ≠ expected. Threshold flags for max p95 latency, max cost, and max failure rate cause non-zero exit. A GitHub Actions workflow provisions Dolt, seeds, starts the server, runs the load test against real LLM providers, and posts the report to the job summary. It’s manual-trigger-only by default — calling real APIs costs real money.</p>\n<p>The second was contract tests for the security middleware. Four middleware modules (<code>api-key-auth</code>, <code>rate-limit</code>, <code>error-handler</code>, <code>request-id</code>) had <strong>zero direct test coverage</strong> — exactly the kind of code where a silent regression would be a high-severity production incident. Forty new tests filled the gap, and two real bugs surfaced just from writing them. The rate limiter’s no-socket fallback used <code>key = &quot;global&quot;</code> (its initial value), the same key as global-mode buckets — within a single instance the closure-scoped Map made it harmless, but the comment lied and any future refactor would silently break. And <code>request-id</code> passed the raw header through unsanitized, making anyone logging request IDs (i.e., anyone) a CRLF-injection or arbitrary-control-char log injection target. It now sanitizes and falls back to UUID if the cleaned value is empty.</p>\n<p>The third was observability for the routing brain itself: a new <code>GET /observability/cascade</code> endpoint that aggregates <code>routing_log</code> into a snapshot of per-layer hit-rate, tier distribution, latency percentiles (overall and per-layer), confidence and similarity distributions, and the top 20 near-miss decisions sorted by <code>similarity_score DESC</code>. A companion <code>/cascade/timeseries</code> returns bucketed escalation rate over time. A careful line-level review caught a subtle issue here: the four underlying queries fire concurrently via <code>Promise.all</code> on independent connections, so under heavy concurrent writes the counts and percentile distributions can briefly disagree. Strong consistency for monitoring data is overkill, but the inconsistency must be <em>visible</em>, so I added <code>snapshot_at</code> (ISO timestamp) and <code>consistency: &quot;best_effort&quot;</code> to the response.</p>\n<h2>The payoff: fixing T3 over-escalation</h2>\n<p>I now had three things I didn’t have a week earlier: a load test that flags routing mismatches, an endpoint that aggregates real routing data, and test coverage on the safety-critical middleware.</p>\n<p>Running the load test for the first time, the routing-assertion section showed <strong>13 of 23 prompts went to the wrong tier</strong>. The observability endpoint confirmed it: <strong>61% of all decisions were hitting T3</strong> (the most expensive tier). Something was very wrong.</p>\n<p>The classifier flattens instructions and data into one string and pattern-matches against the whole thing. So a simple T1 task like “Extract dates from this contract” would match a T3 keyword like “function” if the contract data happened to mention functions.</p>\n<p>Three issues were conspiring against accurate tier matching. The regex patterns matched anywhere in the prompt — <code>\\b(implement|function|debug|refactor)\\b</code> would catch “extract from this function spec” or “the function returned an error” with no concept of intent vs. mention. Then <code>max(tier)</code> clobbered priority: when multiple rules matched, <code>runDeterministicRules</code> picked the highest tier, so “Summarize this analysis report” hit both <code>rule-summarize</code> (T1) and <code>rule-reasoning</code> (T3) and resolved to T3. And the <code>priority</code> column was effectively dead — the matcher iterated all rules and picked max tier, so the column influenced iteration order, but iteration order doesn’t matter for max(). The field that <em>looked</em> like it should make T1 rules short-circuit T3 rules had no effect on the outcome.</p>\n<p>The fix did three things at once. Priority became a real short-circuit: the first matched rule wins for tier, while capabilities still aggregate across all matches. The regex patterns tightened around intent — strong code verbs (<code>implement</code>/<code>debug</code>/<code>refactor</code>/<code>optimize</code>) match alone, generic verbs (<code>write</code>/<code>build</code>/<code>create</code>) require a code-noun within ~40 characters, reasoning rules match verb forms only (which drops “analysis” / “comparison” / “evaluation” as descriptive nouns), and tool-use requires a phrase match or action verb. And a defensive sort in the matcher itself ensures the priority-order contract isn’t only enforced by <code>loadRules()</code>’s <code>ORDER BY</code> clause.</p>\n<h2>Did the fix work?</h2>\n<p>Re-running the load test against the new rules:</p>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>Before</th>\n<th>After</th>\n<th>Δ</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><strong>T3 share</strong></td>\n<td>60.9% (14/23)</td>\n<td><strong>47.8%</strong> (11/23)</td>\n<td><strong>−13.1 pp</strong></td>\n</tr>\n<tr>\n<td><strong>T2 share</strong></td>\n<td>4.3% (1/23)</td>\n<td><strong>17.4%</strong> (4/23)</td>\n<td><strong>+13.1 pp</strong></td>\n</tr>\n<tr>\n<td><strong>Total cost</strong></td>\n<td>$0.32</td>\n<td><strong>$0.30</strong></td>\n<td><strong>−6%</strong></td>\n</tr>\n</tbody></table>\n<p>Three specific scenarios I’d targeted moved from T3 to T2 exactly as predicted: “JSON structured output,” where <code>Analyze</code> no longer triggers <code>rule-reasoning</code>; “Data table generation,” where <code>comparing</code> no longer triggers <code>rule-reasoning</code> and <code>rule-structured</code> (priority 15) wins via short-circuit; and “Complex data analysis,” where <code>analysis</code> is a noun form and no longer matches.</p>\n<p>The raw count didn’t move — 13 of 23 still flagged — but the composition flipped entirely. The remaining mismatches are cases where the load test’s expected tier is debatable (T2 vs T3 for “Refactor this middleware” is a judgment call, not an error). The over-escalation that wasn’t debatable is gone. The router stopped over-escalating; the load test’s expectations are the next thing to calibrate.</p>\n<h2>What I’d take away</h2>\n<p>Three things stand out from the spring.</p>\n<p>Outcome data is the prerequisite for everything. I built the outcome capture in week one and didn’t use it for anything for two weeks. Then once I had a routing tuner, an observability endpoint, and a load test, every one of them depended on having clean outcome and trace data already in place. Build the dataset before you need it.</p>\n<p>Observability and synthetic regression tests are mutually reinforcing. The load test catches things in CI that would otherwise need real traffic. The observability endpoint catches things in real traffic that the load test doesn’t cover. Either alone is half a system; together they form a tight feedback loop. The T3 over-escalation fix was diagnosed in days because both surfaces were measuring it.</p>\n<p>Human code review catches what tests don’t. A thorough mental walkthrough of the code found real bugs the tests missed: the rate-limit fallback-key naming, the X-Request-ID injection vector, and the snapshot’s read-skew. Tests verified the code did what I wrote; review verified that what I wrote was what I meant. Both are necessary.</p>\n<p>The system isn’t done — there’s still no real-traffic dashboard, the migration runner has fragile parsing, and a handful of routing edge cases fall through to T3 by default. But it’s measurable now. And once a system is measurable, every problem with it becomes a tractable one.</p>\n",
      "summary": "HAOL 0.5.0 adds cascade traces on every routing decision, an observability endpoint over the routing log, and a closed-loop tuner that promotes its own rules.",
      "date_published": "2026-05-02T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "agent-orchestration",
        "model-routing",
        "observability",
        "ai-architecture"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/kill-screen",
      "url": "https://www.nateking.dev/blog/kill-screen",
      "title": "The Kill Screen",
      "content_html": "<p>In the <a href=\"https://www.nateking.dev/blog/nine-instructions\">last post</a>, I wrote about nine instructions that run the entire fractional speed system in Pac-Man. This time I wanted to find the ones that break it.</p>\n<p>I’ve known about the split screen my whole adult life — every arcade history book mentions it, every documentary shows the same garbled right half of the maze. What I’d never done is open the disassembly and look at the actual code that fails. With the ROMs already pulled and cross-referenced from the speed-system work, it only took an afternoon.</p>\n<p>The bug turns out to be two bugs, compounding. A misplaced <code>INC A</code> in the setup at <code>$2BF0</code>, and the peculiar semantics of a single loop instruction about fifteen bytes later. Either one on its own would have been survivable. Together they overshoot by a factor of thirty-six.</p>\n<figure class=\"my-8\">\n  <video src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/pacman-kill-screen.mp4\" class=\"w-full rounded-lg\" autoplay loop muted playsinline></video>\n  <figcaption class=\"text-sm text-brand-text-tertiary text-center mt-3\">My recreation of the kill screen</figcaption>\n</figure>\n\n<h2>The setup</h2>\n<p>Pac-Man stores the current board number in a single byte of work RAM at <code>$4E13</code>. Zero-indexed: the cherry board is <code>$00</code>, strawberry is <code>$01</code>, and the 256th board is therefore <code>$FF</code>. No second byte, no flag, no guard.</p>\n<p>The routine that redraws the row of fruit icons in the bottom-right corner of the screen sits at <code>$2BF0</code>. Its first six instructions set up the loop that does the actual damage:</p>\n<pre><code class=\"language-asm\">2BF0  LD   A,(#4E13)   ; A ← current board (0-based)\n2BF3  INC  A           ; A ← board number for fruit logic\n2BF4  CP   #08         ; is it &lt; 8?\n2BF6  JP   NC,#2C2E    ; no → branch to &quot;high-level&quot; path\n2BF9  LD   DE,#3B08    ; yes → DE = fruit table base\n2BFC  LD   B,A         ; B = fruit-loop counter (should be 1..7)\n</code></pre>\n<p>On board 256, <code>LD A,(#4E13)</code> loads <code>$FF</code>. The next instruction, <code>INC A</code>, overflows to <code>$00</code>. And here is where things start to fall apart: <code>INC r</code> on the Z80 does <em>not</em> affect the carry flag. Only S, Z, H, P/V and N are updated. Even if the programmer had thought to check for overflow with <code>JP C</code> on the next line, it wouldn’t have caught anything. The Zero flag is set, but nothing tests it. <code>CP #08</code> against <code>A = 0</code> leaves NC clear. The high-level branch is skipped. <code>LD B,A</code> dutifully loads <code>B = 0</code> into the loop counter.</p>\n<p>That’s the first bug. On its own it would have produced the correct failure mode: draw zero fruits. Mildly ugly, probably survivable. The second bug lives about fifteen bytes later, at the tail of the loop body:</p>\n<pre><code class=\"language-asm\">2C17  DJNZ #2C02       ; B--; if non-zero, jump back to top of loop\n</code></pre>\n<p><code>DJNZ</code> is the Z80’s dedicated looping instruction — “decrement and jump if non-zero” — and it implements decrement-<em>before</em>-test semantics. Starting with <code>B = 0</code>, the first pass produces <code>B = $FF</code> and jumps back. The loop runs a full <strong>256 iterations</strong> before B wraps to zero again, reading ~512 bytes of whatever happens to follow the fruit table in code ROM and painting them into VRAM as tile data.</p>\n<p>A loop that should run seven times runs 256. The first thirteen iterations still paint valid fruit icons — I&#39;ll come back to that — and the remaining 243 paint whatever bytes of code ROM the linker happened to place next to the fruit table.</p>\n<h2>Why only the right half?</h2>\n<p>The first thing anyone notices about the split screen is that the left half of the maze is pristine. The top score bar renders. Pac-Man and the ghosts animate normally. Only the right half is confetti.</p>\n<p>This is a direct consequence of Pac-Man’s unusual video-RAM layout, which is itself a consequence of the cabinet. Namco rotated the CRT 90° clockwise so the playfield would be taller than it was wide. To keep raster reads linear against the rotated tube, the 28×32 playfield region of VRAM was stored <strong>column-major, right-to-left</strong> — each 32-byte column running top-to-bottom down the physical screen. The bottom two rows and top two rows stayed linear 32-byte strips, which is what makes the fruit bar work as a 2×2 block drawer.</p>\n<p>For the first 13 iterations of the runaway loop, HL is still inside the bottom fruit bar, so the loop faithfully paints 13 real fruit icons: cherry, strawberry, two peaches, two apples, two grapes, two Galaxians, two bells, and a key. You can see them stacked along the bottom edge in the kill-screen image.</p>\n<p>From iteration 16 onward, HL crosses into the column-major region. The carefully designed <code>HL, HL+1, HL+$1F, HL+$20</code> pattern that was supposed to paint a 2×2 square on the fruit bar now paints a 2-column × 2-row <em>vertical stripe</em> on the playfield. Advancing HL by 2 per iteration means “move two tiles down.” Wrapping at <code>+$20</code> means “shift one column left.” The loop paints vertical ribbons of garbage down the right side of the maze, column by column, marching inward from the edge until B finally wraps back to zero.</p>\n<p>The left half survives because the loop runs out of iterations before HL ever reaches it.</p>\n<h2>Mathematically unwinnable</h2>\n<p>The bug doesn’t crash the game. Pac-Man can still move. The ghosts still chase. Collision detection is tile-based, and many of the corrupted tiles happen to be walkable. On a Pac-Man board this is actually a problem, because the level-clear check strictly requires the dot-eaten counter to hit <strong>244</strong> — the standard 240 dots plus 4 energizers.</p>\n<p>The corrupted right half contains nine stray dots, scattered wherever an overrun byte coincidentally equaled <code>$0F</code> or <code>$10</code> (the tile codes for dot and energizer). It&#39;s worth saying that the number nine is an accident of the linker: whichever bytes of code ROM happened to sit immediately after the fruit table in 1980 are what determined how many walkable pellets materialized on the kill screen. It happens to be nine. On a differently laid-out build it would be some other small number. The canonical figure is a property of this specific binary, not of the bug itself.</p>\n<p>The undamaged left half has 122 dots. That’s 131 on first entry — 113 short of what you need. The fruit-draw routine re-runs after each death, which respawns the nine right-side dots but not the 122 already-eaten ones on the left. Arriving with the maximum five reserve lives, a player can reach at most <strong>122 + 6 × 9 = 176 dots</strong>. Still short. The board cannot be cleared on unmodified hardware no matter how skillfully it is played.</p>\n<p>This is what gives the perfect-Pac-Man run its precise ceiling of <strong>3,333,360</strong> points. The register overflow sets the existence of the ceiling; the specific number comes from the scoring table doubling ghosts from 200 to 1,600, from the fruit point schedule, from the nine accessible kill-screen dots, from the six-lives maximum. None of the scoring is arbitrary. But without the overflow at <code>$4E13</code>, there would be no ceiling to hit.</p>\n<h2>Don Hodges’ eleven bytes</h2>\n<p>In 2007, Don Hodges published a patch that fixes the bug in place. Earlier attempts had worked around it — Mark Spaeth’s 20-byte fix simply refuses to let <code>$4E13</code> increment past <code>$FE</code>, pinning the game forever on board 255 — but Hodges wanted the actual logic corrected.</p>\n<p>His trick is to move the <code>INC A</code> to <em>after</em> the bounds check, and adjust the constants so the comparison lands correctly:</p>\n<pre><code class=\"language-asm\">; patched\n2BF0  LD   A,(#4E13)\n2BF3  CP   #07         ; was INC A / CP #08\n2BF5  JP   NC,#2C2E    ; branches for stored level ≥ 7\n2BF8  INC  A           ; INC moved here (low-level path only)\n2BF9  LD   DE,#3B08\n</code></pre>\n<p>With a couple of matching constant tweaks in the high-level path and two bytes of checksum padding in free ROM space, the patch comes to nine changed bytes plus two. On board 256 (<code>A = $FF</code>), <code>CP #07</code> now sets NC, execution branches to the high-level path, <code>A</code> is clamped to a safe index, and the loop draws exactly seven keys. The game completes the board normally and wraps cleanly to level 0 with ninth-key difficulty preserved. Effectively an endless game.</p>\n<p>The elegance of the fix is that it uses the same number of instructions as the original. The bug wasn’t a missing check. It was a <em>misordered</em> one. <code>INC A</code> was sitting between the load and the compare when it should have been on the other side of the branch.</p>\n<h2>What actually failed</h2>\n<p>The standard telling of this bug is that a programmer forgot a bounds check. That’s not quite right. The routine is correct for every level Namco’s designers realistically tested. It is structurally incapable of noticing its own failure, and each piece of that failure is small enough to look reasonable in isolation.</p>\n<p><code>INC A</code> doesn’t touch Carry. <code>DJNZ</code> decrements before it tests. The fruit table has no terminator. The sprite hardware is independent, so Pac-Man keeps animating through the garbage. Collision is tile-based, so the player keeps moving. At 60 frames per second, every one of those individually reasonable choices compounds into a game that <em>looks</em> broken but keeps running.</p>\n<p>And it goes one layer further down than the code. The reason the split stays confined to the right half is the column-major VRAM. The reason the VRAM is column-major is the rotated CRT. The reason the CRT is rotated is that Namco wanted a taller playfield than their stock monitor provided. A decision about the shape of the picture tube, made years before any of this code was written, is what kept level 256 from being a full-screen crash. Each piece looks reasonable in isolation, all the way down to the orientation of the glass.</p>\n<p>That’s the part I find interesting. Not the missing check — those are everywhere in code from 1980 — but the fact that the game’s graceful degradation is what preserved the bug as a cultural artifact. A crash at level 256 would have been fixed in a revision ROM and forgotten. A playable-but-unwinnable board became the mathematical ceiling of competitive arcade scoring for three decades.</p>\n<p>Toru Iwatani has said in interviews that the team “never thought players would reach that level, so there is no celebratory ending.” There wasn’t supposed to <em>be</em> a level 256. There was supposed to be a stream of boards that kept getting harder until the quarter ran out. What the players found instead was a wall — not because the designers put one there, but because one misplaced instruction and one off-by-one loop primitive compounded a register overflow into a geometric one.</p>\n<p>Nine instructions to make the ghosts move at 75% of Pac-Man’s speed. Two to end the game forever. The Z80 is nothing if not economical.</p>\n",
      "summary": "One misplaced INC, one peculiar loop primitive, and the most famous bug in arcade history. I went looking for the code that broke Pac-Man at level 256.",
      "date_published": "2026-04-20T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Engineering",
        "z80",
        "reverse-engineering",
        "pac-man",
        "assembly",
        "retro-computing"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/nine-instructions",
      "url": "https://www.nateking.dev/blog/nine-instructions",
      "title": "Nine Instructions",
      "content_html": "<p>I have an original Pac-Man PCB sitting in my closet. Pulled from an arcade cabinet decades ago, it remains in good condition despite its age. I’ve been meaning to do something with it beyond confirming that it still boots, so I pulled the ROM chips and extracted twenty-two binary files.</p>\n<p>My plan was to disassemble the code, read through a bit of it, and learn something about how one of my favorite games was built. What I didn’t expect was how much a 44-year-old codebase would teach me. This is the first in a series of posts about reverse engineering Pac-Man.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/pac-man-pcb.webp\" alt=\"My original Pac-Man PCB\"></p>\n<p>The board runs a Zilog Z80 CPU clocked at 3.072 MHz. It contains eight 2KB chips, each holding a specific address range of the program.</p>\n<table>\n<thead>\n<tr>\n<th>File</th>\n<th>Size</th>\n<th>PCB Socket</th>\n<th>Address Range</th>\n</tr>\n</thead>\n<tbody><tr>\n<td><code>pm1_prg1.6e</code></td>\n<td>2KB</td>\n<td>6E</td>\n<td>$0000-$07FF</td>\n</tr>\n<tr>\n<td><code>pm1_prg2.6k</code></td>\n<td>2KB</td>\n<td>6K</td>\n<td>$0800-$0FFF</td>\n</tr>\n<tr>\n<td><code>pm1_prg3.6f</code></td>\n<td>2KB</td>\n<td>6F</td>\n<td>$1000-$17FF</td>\n</tr>\n<tr>\n<td><code>pm1_prg4.6m</code></td>\n<td>2KB</td>\n<td>6M</td>\n<td>$1800-$1FFF</td>\n</tr>\n<tr>\n<td><code>pm1_prg5.6h</code></td>\n<td>2KB</td>\n<td>6H</td>\n<td>$2000-$27FF</td>\n</tr>\n<tr>\n<td><code>pm1_prg6.6n</code></td>\n<td>2KB</td>\n<td>6N</td>\n<td>$2800-$2FFF</td>\n</tr>\n<tr>\n<td><code>pm1_prg7.6j</code></td>\n<td>2KB</td>\n<td>6J</td>\n<td>$3000-$37FF</td>\n</tr>\n<tr>\n<td><code>pm1_prg8.6p</code></td>\n<td>2KB</td>\n<td>6P</td>\n<td>$3800-$3FFF</td>\n</tr>\n</tbody></table>\n<p>When concatenated in address order, the data in these chips produces the full 16KB of executable code. The remaining fourteen files hold graphics tiles, sprite data, and small PROMs for color generation and sound — twenty-two binary files in total.</p>\n<p>Disassembling the binary produced 9,328 lines of raw Z80 assembly. There are no labels, comments, or even distinction between code and other data. Figuring out what any of it actually <em>does</em> requires cross-referencing registers and addressing modes.</p>\n<p>The first surprise: Pac-Man has no game loop.</p>\n<p>There’s no <code>while(true)</code> spinning somewhere, no tick function being called from a scheduler. Instead, the display hardware fires a maskable interrupt every vertical blank — the brief pause when the CRT’s electron beam resets from the bottom of the screen back to the top, roughly 60.606 times per second — and that interrupt <em>is</em> the game. The hardware uses the Z80’s Interrupt Mode 2, which routes every VBLANK through a vector table at <code>$3F00</code> and into the ISR at <code>$008D</code>. That handler does everything in a single pass: read input, move Pac-Man, move ghosts, check collisions, update the display. If the code doesn’t finish before the next interrupt fires, the game simply slows down. The entire game is, architecturally, an interrupt handler.</p>\n<p>This isn’t how anyone would design it today, but there’s something clarifying about it. No event queues, no deferred processing, no abstraction layers. Every frame is a straight shot from input to pixels. Understanding the interrupt-driven architecture matters because every cycle in that ISR is spoken for — which is why the speed system had to be this efficient.</p>\n<h2>The Shift Register</h2>\n<p>The game needs entities to move at fractional speeds — 75% of full speed, or 47%, or any fraction at all. On a CPU with no floating point, no division instruction, and barely enough clock cycles to finish before the next interrupt, how do you do fractional movement?</p>\n<p>The solution from Shigeo Funaki, the programmer behind the Z80 code, is a 32-bit shift register for each speed context. Every frame, the game shifts the entire 32-bit value left by one bit. If the bit that fell off the top was a 1, the entity moves one pixel. If it was a 0, the entity stays put. And here’s the trick: when a 1 shifts out, a 1 is fed back in at the bottom. When a 0 shifts out, nothing is added. The number of set bits is conserved forever.</p>\n<p>So if you initialize the register with 24 bits set out of 32, the entity moves 24 out of every 32 frames — 75% speed. Sixteen bits gives you 50%. Eight bits, 25%. It’s a ring counter implemented in software. No multiplication, no division, no lookup tables at runtime.</p>\n<p>The Z80 implementation:</p>\n<pre><code class=\"language-asm\">ld hl,($4D58)    ; load low 16 bits\nadd hl,hl        ; shift left, top bit goes to carry\nld ($4D58),hl    ; store\nld hl,($4D56)    ; load high 16 bits\nadc hl,hl        ; shift left, carry chains from low word\nld ($4D56),hl    ; store\nret nc           ; carry clear = no movement\nld hl,$4D58\ninc (hl)         ; carry set = movement; feed back a 1\n</code></pre>\n<p>Nine instructions. The entire fractional speed system for one entity is nine instructions.</p>\n<p>I kept rereading it. The Z80 can only shift 16 bits at a time, so the 32-bit shift is stitched together from two halves, with the carry flag carrying the bit that falls off the bottom half up into the top. The bit that falls off the top becomes the movement decision. <code>ret nc</code> does double duty — it’s both the speed check and the early exit. And the feedback <code>inc (hl)</code> works because the low half was just shifted left, which guarantees its bottom bit is zero.</p>\n<p>It’s the kind of code that looks obvious once you understand it and impossible before you do.</p>\n<p>The shift register doesn’t exist in isolation. Each ghost has <em>five</em> separate accumulators — one for each speed context: normal movement, frightened mode, tunnel speed, and for Blinky alone, two acceleration stages that kick in when few dots remain. The game checks which context applies and runs the appropriate register. Since each is independent, switching modes doesn’t cause speed glitches. The same nine instructions, selecting from different addresses, drive the entire movement system for every entity on screen.</p>\n<h2>The Speed Table</h2>\n<p>The initial bit patterns are loaded from a data table in ROM at <code>$330F</code> during level setup. Eight 42-byte entries cover every level the game can produce, selected through a two-level indirection that maps the current level to a speed-group index, then into the table. Each entry holds seven 4-byte accumulator seeds — one per speed context — plus fourteen bytes of other level parameters.</p>\n<p>Here are those seeds, as fractions of the 32-bit register:</p>\n<table>\n<thead>\n<tr>\n<th>Entity</th>\n<th>Level 1</th>\n<th>Levels 2–4</th>\n<th>Levels 5–20</th>\n<th>Level 21+</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Pac-Man normal</td>\n<td>16/32</td>\n<td>18/32</td>\n<td>20/32</td>\n<td>18/32</td>\n</tr>\n<tr>\n<td>Pac-Man fright</td>\n<td>18/32</td>\n<td>19/32</td>\n<td>20/32</td>\n<td>18/32</td>\n</tr>\n<tr>\n<td>Ghost normal</td>\n<td>15/32</td>\n<td>17/32</td>\n<td>19/32</td>\n<td>19/32</td>\n</tr>\n<tr>\n<td>Ghost frightened</td>\n<td>10/32</td>\n<td>11/32</td>\n<td>12/32</td>\n<td>9/32</td>\n</tr>\n<tr>\n<td>Ghost tunnel</td>\n<td>8/32</td>\n<td>9/32</td>\n<td>10/32</td>\n<td>10/32</td>\n</tr>\n<tr>\n<td>Blinky Elroy 1</td>\n<td>16/32</td>\n<td>18/32</td>\n<td>20/32</td>\n<td>20/32</td>\n</tr>\n<tr>\n<td>Blinky Elroy 2</td>\n<td>17/32</td>\n<td>19/32</td>\n<td>21/32</td>\n<td>21/32</td>\n</tr>\n</tbody></table>\n<p>One note on baselines. These counts are fraction-of-hardware-max, where 32/32 would mean moving one pixel per VBLANK. The familiar “75% ghost speed on Level 1” normalizes instead to Pac-Man’s top speed of 20/32 — against which Level-1 ghost at 15/32 comes out as 75%. My earlier illustration (24 bits set = 75%) describes the mechanism; the actual ROM seeds use that alternate baseline.</p>\n<p>You can read the difficulty curve straight off the table. Pac-Man accelerates from 16/32 at Level 1 to 20/32 at Level 5, then eases back. Ghosts accelerate through Level 5 and never slow down. The tunnels are always the slowest context — a safe zone by design. Blinky’s Elroy gears always sit one and two bits above the shared ghost speed. There is no code that decides any of this. It is all here, in one 336-byte table.</p>\n<p>The code is a fixed engine. The game’s character lives in its data.</p>\n<p>Today you’d solve this with floating-point math, a delta-time accumulator, or whatever your engine ships with. It would be correct, extensible, and forgotten the next day. That’s not a failure of modern engineering — it’s what abstraction is for. But when you have surplus cycles, you find a solution that works. When you have none, you find the one that fits. The second kind of code is worth remembering.</p>\n<p>Nine instructions. About 100 clock cycles per entity per frame. No drift.</p>\n",
      "summary": "I pulled the ROM chips from an original Pac-Man PCB and found the most elegant fractional speed system I’ve ever encountered. Nine instructions.",
      "date_published": "2026-04-15T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Engineering",
        "z80",
        "reverse-engineering",
        "pac-man",
        "assembly",
        "retro-computing"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/pac-man-pcb.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/technically-present-structurally-demoted",
      "url": "https://www.nateking.dev/blog/technically-present-structurally-demoted",
      "title": "Technically Present, Structurally Demoted",
      "content_html": "<p>Anthropic recently published <a href=\"https://www.anthropic.com/features/81k-interviews\">results from 81,000 interviews asking people what they most wanted from AI</a>. The responses were classified into nine categories and ranked. Professional excellence came first, at nearly 19 percent. Creative expression came last, at 5.6.</p>\n<p>The quote they chose to illustrate the top answer is from a healthcare worker: “So much of my cognitive labor was spent on documentation... Since implementing AI, the pressure of documentation has been lifted. I have more patience with nurses, more time to explain things to family members.”</p>\n<p>That’s a great outcome. A person freed from paperwork to be more present with other people is a person whose life got better. If you asked me to design an AI system that produced that result, I would, and I’d be proud of the work. But read the wish again. The magic wand doesn’t conjure something new. It removes something in the way.</p>\n<p>It’s worth noting what came last: creative expression, at 5.6 percent. The obvious reading is that people don’t value it. But that’s not what the survey measured. It measured what people want <em>AI to do for them</em>. And there’s a version of that ranking that means something almost opposite — that people instinctively protect creative expression from automation, the way you’d keep a handwritten letter even if a printer would be faster. The low number might not reflect indifference. It might reflect a boundary.</p>\n<p>Around the same time the survey was published, <a href=\"https://www.nytimes.com/2026/04/01/nyregion/syracuse-university-degrees-eliminated.html?smid=url-share\">Syracuse University announced it was closing or pausing roughly 20 percent of its academic programs</a>. Ceramics, sculpture, painting, jewelry and metalsmithing — gone as standalone majors. Classics, German, Italian — gone. In all, 93 of 460 programs, with the humanities and fine arts representing the largest share.</p>\n<p>The university’s dean wrote that “sunsetting a major does not mean closing a program or abandoning an intellectual tradition — it means sustaining that tradition in the form that best serves our students today.” Ceramics will still exist as a concentration within a broader BFA — the way you might take an elective in poetry while pursuing a degree in marketing.</p>\n<p>A professor in African American Studies, whose program survived but was told to “re-envision” itself, put it differently: “Humanities used to be central to the curriculum, but now it is central in a service type of way.”</p>\n<p>Service. The tradition persists, but only in support of something the market values more.</p>\n<p>These two data points aren’t causally connected. A survey of AI aspirations and a university restructuring in upstate New York have different origins, different stakeholders, different logics. They may not even point in the same direction. If the survey reflects an instinct to protect creative expression from automation, then people still sense, at some level, that this is territory worth keeping human. But institutions don’t run on instinct. They run on enrollment numbers and market demand. And the gap between what individuals intuit and what institutions do is where the damage happens.</p>\n<p>Syracuse isn’t responding to a population that stopped caring about art. It’s responding to a system of incentives — tuition revenue, employer expectations, enrollment trends — that doesn’t have a mechanism for valuing what can’t be measured, and the logic is defensible at every step. Eighty percent of students are enrolled in a third of the majors. No one is making an argument against art. They’re making arguments for efficiency, alignment, stewardship, demand — and art is simply what’s left over after those arguments are settled.</p>\n<p>This is how a culture reclassifies what matters. Not through opposition or direct hostility, but through prioritization. Creative expression doesn’t get eliminated. It gets absorbed — into <em>professional development</em>, into <em>personal branding</em>, and the soft skills section of a résumé. It survives, technically present, structurally demoted. And it happens regardless of whether individuals still value it — because individuals don’t set the curriculum.</p>\n<p>If this were only a cultural loss, it would be worth mourning and easy to dismiss. But I think it’s something worse. I think it’s a strategic error — one we’re making at exactly the wrong moment.</p>\n<p>How do you know when you’re interpreting a phrase in a Beethoven piano sonata correctly? The score gives you the notes, the dynamics, the tempo markings. But the score can’t tell you how long to hold the silence before the recapitulation or whether the sforzando in a given bar should elicit fury or grief. Those decisions belong to the performer.</p>\n<p>Every performance is a commitment made without certainty. You study the score, you study the period, you internalize what your teachers passed down, and then you sit at the instrument and use your best judgment, knowing the decision might be wrong and there’s no way to verify it.</p>\n<p>Artists and philosophers wade in this kind of uncertainty every day. Historically, engineers mostly don’t. You write a function. It passes the test or it doesn’t. Correctness is verifiable. Ambiguity is a bug.</p>\n<p>Until now.</p>\n<p>I build orchestration systems — the layers that decide which model handles a request, how to evaluate whether a response actually answered the question, when to escalate from a simple pattern match to something more capable. I also participate in workshops, teaching other engineers how to work with these tools.</p>\n<p>Here’s what I see in those rooms: the uncertainty is often unbearable for people trained to eliminate it.</p>\n<p>A large language model is not a database. You can’t query it and expect a deterministic result. You can’t unit test a conversation. The same prompt produces different outputs. The system’s confidence and its correctness are unrelated. Evaluating whether a response is <em>good</em> — not just syntactically valid but actually useful, actually truthful, actually appropriate for the context — is an act of interpretation, not verification. It’s closer to deciding how to phrase a passage in a Beethoven Sonata than it is to debugging a SQL query.</p>\n<p>The engineers who thrive in this space are the ones who can commit to a judgment without proof, hold competing interpretations simultaneously, and make decisions that are defensible without being provable. They are comfortable operating in the gap between what the system produced and what the situation required, and they can tolerate that gap long enough to make something useful out of it instead of retreating to a framework that promises false certainty.</p>\n<p>Those are not engineering skills. Those are the skills trained by philosophy, literary criticism, music, rhetoric — by the practice of engaging with material that doesn’t have a right answer and learning to express something meaningful anyway. They’re the skills you develop when you spend years interpreting texts, performing scores, or writing a novel. They’re the skills Syracuse is cutting.</p>\n<p>I build AI systems for a living, and I play piano. These are not separate competencies. The practice of examining a score and making an interpretive commitment I can’t verify is the same practice I bring to evaluating whether an AI agent’s response is trustworthy. The ability to hold ambiguity without resolving it prematurely is the ability that separates engineers who build useful AI systems from engineers who build impressive demos.</p>\n<p>People may still sense this. That survey ranking — creative expression last — might be evidence that most people already know, intuitively, that this isn’t work to hand to a machine. But the institutions that train people to <em>do</em> the work aren’t listening to that instinct. The university that cuts its ceramics program to expand information science is not making a trade between art and technology. It’s <em>undermining the technology by eliminating the cognitive training that the technology demands.</em></p>\n<p>No one is doing this on purpose, and every individual decision is rational. The student who chooses information science over sculpture is making a reasonable bet. The dean who consolidates fine arts programs is responding to real enrollment data. The survey respondent who doesn’t ask AI for help with creative expression may be the most rational of all because they know it’s not something to outsource.</p>\n<p>But the aggregate effect is a system that’s optimizing away the very capacity it requires — a culture training people to build tools they are increasingly unable to think clearly about. Not because they lack intelligence, but because they were never asked to practice the specific discipline of operating without a verifiable answer. The individual instinct to protect creative expression doesn’t matter if the institutions that cultivate it have already moved on.</p>\n<p>There is a moment at the beginning of every piano performance where the audience gradually quiets, and the pianist thinks about the score one last moment before touching the keys. The notes are fixed, but the meaning isn’t. You have to decide what this phrase means <em>to you</em>, right now, and commit to it in front of an audience, knowing that the commitment might be wrong and that the wrongness will be audible.</p>\n<p>That is not a metaphor for what AI engineering requires. It is a description of it. And we are dismantling the institutions that teach people how to do it — not because no one values it, but because the systems that make institutional decisions have no metric to account for its value. The market is not wrong about what people want. It is wrong about what the work requires, and it cannot hear the difference.</p>\n",
      "summary": "Universities are cutting arts and humanities programs at the precise moment AI engineering most needs what those disciplines teach.",
      "date_published": "2026-04-04T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "tech-ethics",
        "uncertainty-management",
        "skill-transfer",
        "decision-making",
        "cognitive-frameworks"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/case-for-heterogeneous-orchestration",
      "url": "https://www.nateking.dev/blog/case-for-heterogeneous-orchestration",
      "title": "The Case for Heterogeneous Orchestration",
      "content_html": "<p>Most agent orchestration systems share an assumption so fundamental it’s rarely examined: that models are interchangeable. You pick a provider, wire up an API key, and route every task through the same model. Maybe you have two tiers — a big model and a small one — but the routing logic is manual, the selection is static, and the decision criteria live in someone’s head rather than in the system itself.</p>\n<p>This works well enough when you’re building demos. It stops working when you’re processing thousands of documents a week and someone asks why you’re spending $0.50 to summarize a paragraph.</p>\n<p>I’ve been building an orchestration layer called <a href=\"https://github.com/nateking-dev/HAOL\"><strong>HAOL</strong></a> — Heterogeneous Agent Orchestration Layer — that treats model diversity as a first-class architectural concern. Not as a cost optimization hack or fallback strategy. As the fundamental design principle.</p>\n<h2>The homogeneity tax</h2>\n<p>The default architecture for most agent systems looks something like this: a task comes in, you send it to your best model, you get a response, you log it. If you’re sophisticated, maybe you have a fast model for “simple” tasks and a smart model for “hard” ones, with an ill-defined boundary between them.</p>\n<p>This is expensive in ways that aren’t obvious until you’re operating at scale. A T1 task — a simple lookup, a one-sentence summary — costs fractions of a cent when routed correctly. Send it to a frontier model and you’re overpaying by two orders of magnitude. Multiply that across thousands of daily tasks in an enterprise pipeline and you’re burning budget that could fund actual capability improvements. Chen et al. demonstrated this empirically with FrugalGPT, showing that LLM cascading — querying progressively more expensive models until a confidence threshold is met — can reduce costs by up to 98% while matching GPT-4 quality [1].</p>\n<p>But cost isn’t even the interesting problem. The interesting problem is that different models are <em>actually different</em>. They have different strengths, different failure modes, different latency profiles. A model that’s exceptional at code generation might be mediocre at structured data extraction. A model that’s fast and cheap might handle 80% of your volume perfectly well. Treating them as interchangeable ignores information that the system should be using. The X-MAS benchmark confirmed this at scale: across 27 LLMs and 1.7 million evaluations, no single model excelled universally, and heterogeneous multi-agent systems that assigned specialized models to specific roles consistently outperformed homogeneous configurations — by up to 47% on certain benchmarks [2].</p>\n<h2>How HAOL thinks about routing</h2>\n<p>HAOL classifies every incoming task along three dimensions: what capabilities does it require, how complex is it, and what’s it allowed to cost. The complexity question maps to a four-tier system — T1 (simple) through T4 (expert) — where each tier defines a cost ceiling and a pool of eligible agents.</p>\n<p>The routing decision itself happens through a cascade router: a three-layer classification system that trades off speed against accuracy.</p>\n<p><strong>Layer 0</strong> is pure pattern matching. Regex, prefix checks, keyword detection — the kind of thing that resolves in microseconds. If your prompt starts with “summarize” or contains “json,” the router already knows what tier you’re in. No API calls, no latency, no cost. This handles the majority of well-structured requests, and it handles them fast.</p>\n<p><strong>Layer 1</strong> kicks in when patterns aren’t enough. It embeds the incoming prompt and compares it against a bank of 32 reference utterances — eight per tier — <a href=\"https://www.nateking.dev/blog/understanding-vector-stores\">using cosine similarity</a>. The intuition here is straightforward: “What is the tallest mountain?” and “What is the capital of France?” use completely different words but live in the same complexity neighborhood. Embeddings capture that neighborhood. The top five nearest neighbors vote on the tier, weighted by similarity score. If the vote is decisive (above a 0.72 confidence threshold), we’re done.</p>\n<p>The voting mechanism is simple enough to read in one pass:</p>\n<pre><code class=\"language-typescript\">export function weightedTierVote(matches: SimilarityMatch[]): { tier: TierId; confidence: number } {\n  if (matches.length === 0) {\n    return { tier: 3 as TierId, confidence: 0 };\n  }\n\n  const tierWeights = new Map&lt;number, number&gt;();\n  let totalWeight = 0;\n\n  for (const match of matches) {\n    const weight = match.score;\n    tierWeights.set(match.tier_id, (tierWeights.get(match.tier_id) ?? 0) + weight);\n    totalWeight += weight;\n  }\n\n  let bestTier = 3 as TierId;\n  let bestWeight = 0;\n  for (const [tier, weight] of tierWeights) {\n    if (weight &gt; bestWeight) {\n      bestWeight = weight;\n      bestTier = tier as TierId;\n    }\n  }\n\n  const confidence = totalWeight &gt; 0 ? bestWeight / totalWeight : 0;\n  return { tier: bestTier, confidence };\n}\n</code></pre>\n<p>Each match votes for its tier, weighted by how similar it is to the incoming prompt. If four of five nearest neighbors are T1 utterances and only one is T2, the weighted vote heavily favors T1. The confidence is the winning tier’s share of total weight — a clean signal of how unanimous the neighborhood is.</p>\n<p><strong>Layer 2</strong> is LLM escalation for the genuinely ambiguous cases. “Help me with my project” could be T1 or T4 depending on context that keywords and embeddings can’t resolve. A cheap, fast model — Haiku — makes the judgment call. It costs about a tenth of a cent per classification and responds in under a second.</p>\n<p>If all three layers are inconclusive, the system defaults to T3. Conservative. Might overspend, but won’t underdeliver.</p>\n<p>The thing I like about this design is that it’s <em>proportional</em>. Simple tasks get simple classification. Ambiguous tasks get progressively more intelligence thrown at the problem. And because each layer has clear failure modes and fallbacks, the system degrades gracefully — if the embedding API is down, you skip Layer 1 and go straight to the LLM. If the LLM key isn’t configured, you fall back to pattern matching plus a conservative default. The system never hard-fails on classification.</p>\n<p>This cascade pattern — try cheap first, escalate only when confidence is low — has independent validation. Aggarwal et al. formalized it as a POMDP-based routing problem with AutoMix, showing that self-verification routing can cut compute costs by over 50% without degrading output quality [3]. RouteLLM, from Berkeley’s LMSYS group, demonstrated that routers trained on preference data can achieve over 95% of GPT-4 performance while routing only 26% of queries to the expensive model [4].</p>\n<p>This philosophy extends into the implementation. The LLM escalation provider, for example, wraps its entire API call in a catch that returns a conservative default rather than propagating the error:</p>\n<pre><code class=\"language-typescript\">// From escalation.ts — if the API call or Zod parse fails for any reason:\n} catch {\n  // Conservative fallback: T3, no capabilities, moderate confidence\n  return { tier: 3 as TierId, capabilities: [], confidence: 0.5 };\n}\n</code></pre>\n<p>The Zod schema validates the LLM’s JSON response against the expected shape — tier must be 1–4, confidence between 0 and 1. If the model hallucinates, returns malformed JSON, or the API times out entirely, the system doesn’t crash. It falls back to T3 with moderate confidence and keeps going. The routing log records what happened, so you can find and fix the gap later.</p>\n<h2>Why Dolt</h2>\n<p>Every routing decision, agent configuration change, and policy adjustment in HAOL is stored in Dolt — a database that’s MySQL-compatible on the wire but Git-like under the hood. Every mutation is a commit. You can diff two points in time, branch to test a policy change before merging it, and blame any configuration to trace who changed it and when.</p>\n<p>This might seem like overkill for a routing layer, but it solves a problem I kept running into: <em>when something goes wrong in an agent system, the first question is always “what changed?“</em> Did someone adjust the scoring weights? Did an agent get disabled? Did a new routing rule get added that’s catching prompts it shouldn’t?</p>\n<p>With a traditional database, answering these questions means building audit logging from scratch — and hoping you instrumented the right things. With Dolt, the audit trail is the database. The routing log table records every classification decision: which layer handled it, what confidence it had, how long it took. But beyond that, the <em>schema itself</em> is versioned. The routing rules, the agent registry, the policy weights — all of it is diffable, branchable, reversible.</p>\n<p>DoltHub has been making a version of this argument explicitly since late 2025: that code agents succeeded because code is under Git, and that agentic systems operating on data need the same safety net — branch, review diffs, merge or discard [5]. The canonical pattern is an agent writing to an isolated branch while a human or automated process inspects the changes before they touch production state.</p>\n<p>In regulated environments, this matters. In any environment where you need to explain <em>why</em> the system made a decision, it matters.</p>\n<h2>Agent selection as a scoring problem</h2>\n<p>Once the cascade router assigns a tier and a set of required capabilities, agent selection becomes a constrained optimization. Candidates are filtered first — they must be active, their tier ceiling must be high enough, they must have every required capability, and their estimated cost must be within the tier’s budget. What survives gets scored:</p>\n<pre><code class=\"language-typescript\">score = capability_match × 0.5 + cost_efficiency × 0.3 + latency × 0.2\n</code></pre>\n<p>Those weights — 0.5, 0.3, 0.2 — are defaults stored as policy in Dolt, not hardcoded constants. You can branch, adjust the weights, compare results, and merge the change without a redeploy. In code, each dimension is normalized so that the best candidate in the pool scores 1.0 and the worst scores 0.0:</p>\n<pre><code class=\"language-typescript\">// From agent-selection.ts — scoring surviving candidates\nconst capabilityScore =\n  requiredCapabilities.length === 0 ? (maxBonus === 0 ? 1.0 : bonusScore) : 0.6 + 0.4 * bonusScore;\n\nconst costScore = costRange === 0 ? 1.0 : 1 - (costs[i] - minCost) / costRange;\n\nconst latencyScore =\n  latencyRange === 0 ? 1.0 : 1 - (agent.avg_latency_ms - minLatency) / latencyRange;\n\nconst totalScore =\n  capabilityScore * policy.weight_capability +\n  costScore * policy.weight_cost +\n  latencyScore * policy.weight_latency;\n</code></pre>\n<p>The capability score is worth calling out. Every candidate in the pool already has the <em>required</em> capabilities — that’s enforced by the filter. So the capability score differentiates on <em>bonus</em> capabilities: an agent that can do code generation, reasoning, <em>and</em> structured output will outscore one that only does code generation, even if both meet the task’s requirements. The idea is that agents with broader capability sets are more likely to handle edge cases within the task.</p>\n<p>If execution fails, the fallback strategy kicks in. <code>NEXT_BEST</code> tries the runner-up. <code>TIER_UP</code> relaxes the constraints and re-selects. <code>ABORT</code> gives up. The strategy is itself a policy decision, stored alongside the weights.</p>\n<h2>What this is and what it isn’t</h2>\n<p>HAOL is an MVP. It’s a TypeScript/Node application backed by Dolt, running on Hono, with adapters for Anthropic, OpenAI, and local models. It has a CLI, an HTTP API, and a test suite. It’s functional. It routes tasks, selects agents, executes them, and records the results.</p>\n<p>What it isn’t is production-hardened infrastructure. The scoring weights are informed guesses. The reference utterances need tuning against real workload distributions. The cost ceilings are reasonable defaults, not empirical findings.</p>\n<p>But the thesis is what matters here. The thesis is that heterogeneity is the natural state of an agent ecosystem, and the orchestration layer should embrace that rather than abstract it away. That routing decisions should be auditable, diffable, and reversible. That classification should be proportional — spending intelligence on ambiguity, not on certainty. And that the right model for the job depends on the job, not on the contract you signed with a provider.</p>\n<p>Empirical analysis of over 100 trillion tokens through OpenRouter confirms that the AI inference market is definitively multi-model, not winner-take-all [6]. Steve Yegge arrived at a compatible framing with his “cognitive pyramid” — arguing that all knowledge work decomposes into a hierarchy of cognitive tasks and that probably 50–80% of agent traffic could be routed to cheaper models without quality loss [7]. The question isn’t whether to route heterogeneously. It’s whether the routing intelligence lives in the system or in someone’s head.</p>\n<p>The code is <a href=\"https://github.com/nateking-dev/HAOL\">on GitHub</a>. I’d welcome feedback from anyone thinking about these problems.</p>\n<hr>\n<h2>References</h2>\n<p>[1] L. Chen, M. Zaharia, and J. Zou, “FrugalGPT: How to use large language models while reducing cost and improving performance,” arXiv preprint arXiv:2305.05176, May 2023. [Online]. Available: <a href=\"https://arxiv.org/abs/2305.05176\">https://arxiv.org/abs/2305.05176</a></p>\n<p>[2] R. Ye, X. Liu, Q. Wu, X. Pang, Z. Yin, et al., “X-MAS: Towards building multi-agent systems with heterogeneous LLMs,” arXiv preprint arXiv:2505.16997, May 2025. [Online]. Available: <a href=\"https://arxiv.org/abs/2505.16997\">https://arxiv.org/abs/2505.16997</a></p>\n<p>[3] P. Aggarwal et al., “AutoMix: Automatically mixing language models,” in <em>Proc. NeurIPS</em>, 2024. [Online]. Available: <a href=\"https://arxiv.org/abs/2310.12963\">https://arxiv.org/abs/2310.12963</a></p>\n<p>[4] I. Ong et al., “RouteLLM: Learning to route LLMs with preference data,” in <em>Proc. ICLR</em>, 2025. [Online]. Available: <a href=\"https://arxiv.org/abs/2406.18665\">https://arxiv.org/abs/2406.18665</a></p>\n<p>[5] E. Richardson, “Agentic systems need version control: An example,” DoltHub Blog, Oct. 2025. [Online]. Available: <a href=\"https://www.dolthub.com/blog/2025-10-31-agentic-systems-need-version-control/\">https://www.dolthub.com/blog/2025-10-31-agentic-systems-need-version-control/</a></p>\n<p>[6] M. Aubakirova, A. Atallah, C. Clark, J. Summerville, and A. Midha, “State of AI: An empirical 100 trillion token study with OpenRouter,” Andreessen Horowitz, Jan. 2025. [Online]. Available: <a href=\"https://a16z.com/state-of-ai/\">https://a16z.com/state-of-ai/</a></p>\n<p>[7] S. Yegge, “Zero framework cognition: A way to build resilient AI applications,” Medium, Oct. 2025. [Online]. Available: <a href=\"https://steve-yegge.medium.com/zero-framework-cognition-a-way-to-build-resilient-ai-applications-56b090ed3e69\">https://steve-yegge.medium.com/zero-framework-cognition-a-way-to-build-resilient-ai-applications-56b090ed3e69</a></p>\n",
      "summary": "Why agent orchestration should treat model diversity as a first-class concern — introducing HAOL and the architecture behind heterogeneous routing.",
      "date_published": "2026-03-10T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "agent-orchestration",
        "model-routing",
        "cost-efficiency",
        "ai-architecture"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/observed-exposure",
      "url": "https://www.nateking.dev/blog/observed-exposure",
      "title": "“Observed Exposure”",
      "content_html": "<p>Earlier this week, Anthropic published a <a href=\"https://www.anthropic.com/research/labor-market-impacts\">study measuring the gap between what AI can theoretically do in the workforce and what it’s actually being used for</a>. They call the metric “observed exposure,” and the finding is stark: the gap is enormous, and it runs through all industries.</p>\n<p>In Computer and Math occupations—the category with the deepest technical literacy and the fewest cultural barriers to adoption—large language models could theoretically handle ninety-four percent of tasks. Actual professional usage covers thirty-three percent. In Legal, Education, Business and Finance, the pattern is the same: vast theoretical capability, modest real-world footprint. The radar chart in their report tells the whole story at a glance. Theoretical coverage fans out in a wide blue envelope across nearly every field. Observed usage huddles in a small red cluster near the center, roughly the same size regardless of the occupation. The shape of the red doesn’t track the shape of the blue. It tracks the shape of human behavior.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/observed-exposure-chart.webp\" alt=\"Source: Anthropic\"></p>\n<p>Silicon Valley looks at that chart and sees a growth problem—an adoption curve waiting to be steepened, a market waiting to be captured. I look at it and see something different. I see the brakes working.</p>\n<p>I design AI architectures at a midsize midwestern bank. I’ve watched teams with access to frontier models and well-designed systems still struggle to move from pilot to production. The failure mode is almost never technical. It’s the review committee that meets biweekly. It’s the compliance officer who needs to understand what the model did before signing off. It’s the senior analyst who doesn’t trust the extraction because she’s been burned by bad automation before. It’s the six-week approval cycle for a workflow change that an AI can execute in seconds.</p>\n<p>For a long time, I treated this friction as the enemy. My job, as I understood it, was to close the gap—to push observed usage closer to theoretical capability as fast as I could. Every workshop was an attempt to accelerate adoption. Every architecture decision was optimized for reducing the distance between what the model could do and what the organization would let it do.</p>\n<p>The Anthropic study caused me to pause and think more deeply. Not because it showed the gap was bigger than I thought—I already knew it was big. Because it showed the gap was <em>uniform</em>. It doesn’t matter whether the field is technically sophisticated or not. It doesn’t matter whether the organization is a bank in Omaha or a software company in San Francisco. The distance between theoretical and observed capability is roughly the same everywhere. That’s not a series of local failures. That’s a pattern.</p>\n<p>The observed usage gap exists for reasons that are illegible to the people trying to close it.</p>\n<p>Some of the reasons are structural. Regulated industries have compliance requirements that aren’t optional and can’t be automated away by fiat. A model that can draft a loan covenant summary in seconds is useless if nobody with signing authority trusts it enough to act on the output. Trust is not a deployment problem. It’s a relationship built over time between a human and a system, and no amount of architectural elegance accelerates it past a certain floor.</p>\n<p>Some of the reasons are institutional. Organizations have memory. They remember the last three technology transformations that were going to change everything—and the wreckage each one left behind when it was deployed faster than it was understood. The senior analyst who insists on checking every AI extraction by hand isn’t being irrational. She’s applying a heuristic that has served her well across decades of tools that overpromised and underdelivered. Her skepticism has a cost, but it also has a function: it catches the failures that the system’s designers didn’t anticipate, because she’s seen failure modes that the designers haven’t lived through.</p>\n<p>Some of the reasons are epistemological. There’s a difference between a model being able to perform a task and an organization knowing that the model can perform a task, and a further difference between knowing it and being willing to depend on it. These are not the same state, and you can’t skip from the first to the third. It’s slow because it’s supposed to be slow. Understanding isn’t something you can push; it’s something that has to be pulled by the person doing the understanding.</p>\n<p>Here’s the claim I want to make carefully, because it cuts against everything my industry incentivizes me to believe: the gap between theoretical capability and observed usage is not, in the short term, a problem to be solved. It’s a buffer that’s protecting organizations from moving faster than they can think.</p>\n<p>Consider the alternative. If observed usage tracked theoretical capability—if every organization immediately deployed AI to the full extent of what the models can do—we’d be running ninety-four percent of Computer and Math tasks through systems that nobody has had time to audit, stress-test, or develop institutional understanding of. We’d be automating legal analysis, financial review, and medical documentation at a pace set by the model’s capability rather than by the organization’s capacity to verify the output. In regulated industries, that’s not innovation. It’s negligence with a venture pitch.</p>\n<p>Silicon Valley’s cultural instinct is to treat friction as waste. Move fast and break things. The observed usage gap is friction, so it must be inefficiency, and inefficiency is what technology exists to eliminate. But some friction is structural integrity. The six-week approval cycle is maddening when you’re the engineer who built the workflow, but it exists because someone, at some point, learned the hard way what happens when you skip it. The compliance officer who wants to understand what the model did isn’t blocking progress. She’s the last line of defense between a confident system and an unexamined failure.</p>\n<p>I’ve spent my time trying to close that gap. I’m starting to think the more important work is learning which parts of it to keep.</p>\n<p>None of this means the gap should be permanent, or that every instance of organizational friction is justified. Some of it is genuine dysfunction—bureaucratic inertia dressed up as prudence, risk aversion that protects careers rather than outcomes. The challenge is that you can’t distinguish productive friction from wasteful friction without understanding the organization deeply enough to know why each piece exists. And that understanding is itself the slow, human, non-automatable work that the gap is made of.</p>\n<p>So how do you close the gap responsibly?</p>\n<p>Not by eliminating the brakes, but by making them literate. The compliance officer shouldn’t be removed from the loop. She should understand the system well enough to know when her review is essential and when it’s redundant. The review committee shouldn’t be dissolved. It should be equipped to evaluate AI-generated output on its own terms rather than applying frameworks designed for human-authored work. The senior analyst’s skepticism shouldn’t be overridden. It should be made precise—converted from a general distrust of automation into a specific understanding of where this model fails and where it doesn’t.</p>\n<p>That’s what our internal workshops were actually doing, even when I thought they were about adoption. They were building the organizational literacy that lets the gap close safely. The irony is that I was frustrated by how slow it was going. I wanted the gap to shrink faster. I didn’t understand that the speed of the shrinking <em>was</em> the literacy developing.</p>\n<p>There’s one more thing in the Anthropic data that I keep coming back to.</p>\n<p>They found no meaningful rise in unemployment among workers in highly exposed occupations. The mass displacement everyone fears hasn’t materialized. But they did find that hiring of young workers into those occupations has slowed. Not a collapse. A thinning. The people with established careers are protected, for now. The people trying to enter are finding fewer openings.</p>\n<p>This is where the brakes have a cost.</p>\n<p>I’ve been at my bank for over eleven years. I learned to build things by being given the chance to build them badly first, under supervision, in an environment that tolerated my learning curve. If organizations are using AI to skip that step—routing the junior work to the model instead of to the junior hire—then the absorption gap becomes self-reinforcing. Today’s gap is a coordination problem: we have the capability but not the organizational capacity to use it. Tomorrow’s gap could be a talent problem: we’ll have the systems but not the people who understand them deeply enough to maintain, question, and extend them.</p>\n<p>The brakes are protecting us now. But if they’re also preventing us from investing in the next generation of people who will eventually need to operate the system at full capacity, then we’re trading a short-term buffer for a long-term deficit. The observed usage gap buys time. The question—the one I haven’t answered, the one I don’t think anyone has answered—is whether we’re using that time well.</p>\n<p>The data says we’re not using it yet. The gap is roughly the same size everywhere, which means almost nobody has figured out how to convert the breathing room into genuine organizational readiness. We’re just... pausing. Hesitating at the threshold of capability, not because we’ve decided how to proceed but because we haven’t.</p>\n<p>I don’t think the answer is to push harder. I don’t think it’s to stop pushing either. I think it’s to recognize that the bottleneck I wasn’t solving—the human, institutional, epistemological work of building an organization that can absorb what AI makes possible—is the actual work. Not adjacent to the technical work. Not downstream of it. The work itself.</p>\n",
      "summary": "The gap between what AI can do and what organizations actually use it for isn’t a failure of adoption. It might be the brakes working.",
      "date_published": "2026-03-07T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "ai-adoption",
        "organizational-learning",
        "human-judgment",
        "optimization-tradeoffs"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/observed-exposure-chart.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/inference-is-cheap",
      "url": "https://www.nateking.dev/blog/inference-is-cheap",
      "title": "Inference Is Cheap Right Now. That’s a Problem.",
      "content_html": "<p>Everyone building AI systems today is making the same bet: that inference costs will keep falling. That the trajectory from GPT-3 pricing to Claude 3.5 pricing to whatever comes next is a line that only goes down.</p>\n<p>I think that bet is dangerously incomplete. And the gap between what per-token pricing suggests and what AI work actually costs is widening, not narrowing.</p>\n<p>The argument for ever-cheaper inference is straightforward. Competition drives prices down. Hardware improves. Quantization and distillation make models more efficient. Input token prices have fallen roughly 1,000× in three years — from GPT-3 Davinci at $60 per million tokens to comparable open-source models at $0.06 [1]. That’s among the fastest cost curves in technology history, outpacing even Moore’s Law [2][3].</p>\n<p>But this narrative treats inference as a commodity — interchangeable compute that gets cheaper the way storage did. It ignores what’s actually happening to the <em>work</em> we’re asking models to do. And it obscures a growing divergence: the cost of a <em>token</em> is plummeting, but the cost of a <em>decision</em> is not.</p>\n<h2>Three Forces Creating a Cost Floor</h2>\n<p>Reasoning is not inference. The shift toward chain-of-thought, extended thinking, and multi-step reasoning models has fundamentally changed what a single “request” looks like. A reasoning-heavy call to a frontier model doesn’t consume the same compute as a simple completion. When your agent needs to <em>think</em> — plan a task decomposition, evaluate tradeoffs, resolve ambiguity — you’re buying something qualitatively different from what the per-token price suggests.</p>\n<p>How different? Artificial Analysis benchmarked reasoning models against standard models on identical tasks and found that OpenAI’s o1 cost $2,767 versus $109 for GPT-4o — a 25× gap [4]. Claude 3.7 Sonnet with extended thinking cost 18× more than Claude 3.5 Sonnet without it. The multiplier comes from two compounding effects: reasoning models charge roughly 6× more per token <em>and</em> generate 8–20× more tokens per request, much of it invisible chain-of-thought that still hits your bill. As these capabilities become table stakes, the floor on what a meaningful inference call costs rises even as the per-token rate falls.</p>\n<p>Demand is scaling faster than supply. Enterprise adoption is accelerating. Every company building AI agents, copilots, and automation pipelines is multiplying their inference volume. GPU capacity is expanding, but not at the rate of demand.</p>\n<p>The numbers are stark. Google’s AI infrastructure VP told employees the company must “double its serving capacity every 6 months” [5]. Microsoft’s Azure demand has outstripped supply so severely that CEO Satya Nadella admitted, “You may actually have a bunch of chips sitting in inventory that I can’t plug in. In fact, that is my problem today” [6]. The Futurum Group summarized it bluntly: “All the hyperscalers report that their markets are supply-constrained, rather than demand-constrained” [7]. NVIDIA’s Blackwell GPUs are sold out [8]. When demand outstrips supply, prices don’t fall — they stabilize or climb.</p>\n<p>Compliance multiplies compute. In regulated industries, a single decision often requires multiple passes: generation, review, validation, audit logging. You’re not making one inference call per task — you’re making three to ten across different models with different trust levels. CloudZero’s analysis of production deployments found that “the true cost of a resolved AI task is often 10 to 50 times higher than the posted ’per call’ price” [9]. The unit of work isn’t a token; it’s a <em>decision</em>, and decisions are getting more expensive even as tokens get cheaper.</p>\n<p>None of this means per-token prices will reverse course. But it means the cost landscape is <em>bifurcating</em>. Simple inference for commodity tasks will keep getting cheaper. The frontier — reasoning-heavy, compliance-wrapped, agent-orchestrated workloads — operates under fundamentally different economics where the effective cost per decision can be orders of magnitude higher than the per-token headline price.</p>\n<p>And there’s a compounding effect that makes this worse. When Satya Nadella invoked the Jevons paradox after DeepSeek’s launch — “As AI gets more efficient and accessible, we will see its use skyrocket” [10] — he was describing something already happening. Enterprise generative AI spending tripled from $11.5 billion to $37 billion during the same period that per-token costs dropped 1,000×. Tokens per query are growing from roughly 200 in 2020 to 22,000 in 2025, with projections reaching 150,000–1.5 million as agentic workloads expand. Cheaper tokens don’t reduce your bill when every task consumes 100× more of them.</p>\n<h2>Prompt Caching: The Right Idea at the Wrong Layer</h2>\n<p>Anthropic recently shipped automatic prompt caching for the Claude API — a genuinely useful optimization. The mechanics are elegant: cache hits on static prompt prefixes cost 10% of standard input pricing. For long-running agent sessions with large system prompts and tool definitions, the savings are substantial.</p>\n<p>A coding agent running 40 turns with a 15,000-token static context goes from 600,000 billed input tokens down to roughly 73,500. That’s real money at scale.</p>\n<p>But prompt caching operates at a single layer of the efficiency stack. It optimizes <em>within</em> a model — reducing the cost of repeatedly processing the same context across turns of the same conversation. It doesn’t touch the question of whether you should be using that model in the first place for every task in the pipeline.</p>\n<p>That’s where most agent architectures have a deeper problem.</p>\n<h2>From Monolith to Team</h2>\n<p>The default architecture for AI agents today is simple: pick a frontier model, send everything to it, and let the model figure it out. System prompt, tool definitions, context, conversation history, task — all of it goes to the same model every time.</p>\n<p>This is the equivalent of hiring a senior architect to also answer the phones, file the paperwork, and sweep the floors. Not because those tasks require that level of capability, but because it’s easier than building a system that routes work to the right person.</p>\n<p>When inference is cheap, this works. When it gets more expensive — or when you’re operating at scale and those margins matter — it becomes the architectural decision that kills your economics. The alternative is to stop treating your model as a monolith and start treating it as a <em>team</em>.</p>\n<p>A heterogeneous agent architecture decomposes work across multiple models — routing tasks based on complexity, risk, and capability requirements. Instead of sending every request to the most capable (and expensive) model in your stack, you build a system that matches the right model to the right task.</p>\n<p>The core concept is a tiered agent taxonomy:</p>\n<p><strong>Orchestration agents</strong> handle planning, supervision, and routing. These require strong reasoning capabilities and typically run on frontier models — but they process relatively few tokens compared to execution agents. Their job is to decompose objectives, monitor progress, and decide where work goes.</p>\n<p><strong>Execution agents</strong> do the actual work: implementing changes, running analysis, producing outputs. Many of these tasks are well-scoped and don’t require frontier-level reasoning. A smaller, faster model handles them at a fraction of the cost — and often with lower latency.</p>\n<p><strong>Specialist agents</strong> handle domain-specific concerns like security review, compliance validation, or quality checks. These run on models fine-tuned or prompted for narrow expertise, and they activate only when their specific capability is needed.</p>\n<p>The key insight is that model selection becomes a <em>routing decision</em>, not a default. A planning agent running on Opus decomposes a complex task into subtasks. A router evaluates each subtask’s complexity and risk profile and assigns it to the appropriate model tier. A simple extraction task goes to Haiku. A nuanced analysis goes to Sonnet. A high-stakes decision with compliance implications goes to Opus with human-in-the-loop approval. This isn’t just cost optimization — it’s architectural honesty about what different tasks actually require.</p>\n<h2>Why This Compounds</h2>\n<p>The efficiency gains from heterogeneous routing compound with optimizations like prompt caching rather than competing with them.</p>\n<p>Prompt caching reduces the cost of context within a model session. Heterogeneous routing reduces the cost of choosing the wrong model for the task. Layer them together and you get a system where each agent session is both cache-efficient <em>and</em> running on the cheapest model that meets the task’s requirements.</p>\n<p>Consider a document processing pipeline that handles incoming files through a sequence of steps: classification, extraction, validation, exception handling.</p>\n<p>In a monolithic architecture, every step runs on the same frontier model. Prompt caching helps — the system prompt and tool definitions are cached across turns — but you’re still paying frontier pricing for classification tasks that a small model handles perfectly.</p>\n<p>In a heterogeneous architecture, a lightweight model classifies the document. A mid-tier model extracts structured data. A frontier model handles only the exceptions — the ambiguous cases, the edge conditions, the decisions that actually require deep reasoning. Each of these agents maintains its own cached context, optimized for its specific role.</p>\n<p>The frontier model might process 10% of the total token volume instead of 100%. That’s not a 10% cost reduction — it’s a fundamental restructuring of where compute goes.</p>\n<p>There’s a practical consideration that makes this work. One of the lessons from the Claude Code team is that switching models mid-conversation destroys your cache. If you’re 100,000 tokens deep with Opus and send a simple question to Haiku, the cache doesn’t transfer — you rebuild from scratch. The solution is the subagent pattern: the primary agent stays on its model with its cache intact and delegates to a different model through a <em>separate, focused context</em>. The orchestrator prepares a minimal handoff message with only the relevant context, the subagent processes it, and the result flows back into the primary session without touching the cache. The architecture naturally preserves cache coherency because it was designed around the principle that different models handle different work — not that one model handles everything.</p>\n<h2>Beyond the Cost Argument</h2>\n<p>The case for heterogeneous architecture doesn’t depend on the cost thesis above. Even if per-token prices fall forever, the architectural benefits stand on their own.</p>\n<p>It forces you to decompose your system into well-defined agents with clear responsibilities, explicit capabilities, and traceable decision chains. That’s just good engineering, regardless of what models cost.</p>\n<p>It makes you model-agnostic by design. When your architecture routes tasks to capability tiers rather than specific models, swapping providers or upgrading models becomes a configuration change rather than a rewrite.</p>\n<p>It improves latency. Smaller models respond faster. When 80% of your tasks can run on a model that returns in 200ms instead of 2 seconds, your users notice.</p>\n<p>And it gives you a natural framework for governance and auditability. When every task has a defined complexity level, a model assignment rationale, and a complete execution trace, you can answer questions about why the system made a particular decision — which matters increasingly as AI systems move into consequential domains.</p>\n<h2>Build for the World That’s Already Here</h2>\n<p>The relevant question isn’t whether inference costs will reverse — it’s whether the industry’s migration toward reasoning and agentic workloads has already shifted the center of gravity from cheap commodity inference to expensive decision-grade compute. The evidence suggests it has.</p>\n<p>The best time to build efficiency into your architecture is when you don’t need it yet. When inference is cheap and margins are comfortable, you have the luxury of getting the design right without the pressure of a cost crisis forcing shortcuts.</p>\n<p>Prompt caching, model routing, capability-based task decomposition — these aren’t just cost optimizations. They’re architectural patterns that make AI systems more robust, more auditable, and more adaptable to a cost landscape that is bifurcating rather than uniformly declining.</p>\n<p>The teams that build monolithic agent architectures today because per-token pricing is falling will discover that their costs are dominated by reasoning chains, compliance passes, and agentic loops — none of which follow the commodity curve. The teams that build heterogeneous architectures will just adjust their routing thresholds. I know which position I’d rather be in.</p>\n<hr>\n<p><strong>References</strong></p>\n<p>[1] G. Appenzeller, “Welcome to LLMflation — LLM inference cost is going down fast,” <em>Andreessen Horowitz</em>, Nov. 12, 2024. <a href=\"https://a16z.com/llmflation-llm-inference-cost/\">https://a16z.com/llmflation-llm-inference-cost/</a></p>\n<p>[2] B. Cottier, B. Snodin, D. Owen, and T. Adamczewski, “LLM inference prices have fallen rapidly but unequally across tasks,” <em>Epoch AI</em>, Mar. 12, 2025. <a href=\"https://epoch.ai/data-insights/llm-inference-price-trends\">https://epoch.ai/data-insights/llm-inference-price-trends</a></p>\n<p>[3] N. Maslej <em>et al.</em>, “Artificial Intelligence Index Report 2025,” Stanford Institute for Human-Centered AI, Apr. 2025. <a href=\"https://hai.stanford.edu/ai-index/2025-ai-index-report\">https://hai.stanford.edu/ai-index/2025-ai-index-report</a></p>\n<p>[4] K. Wiggers, “The rise of AI &#39;reasoning&#39; models is making benchmarking more expensive,” <em>TechCrunch</em>, Apr. 10, 2025. <a href=\"https://techcrunch.com/2025/04/10/the-rise-of-ai-reasoning-models-is-making-benchmarking-more-expensive/\">https://techcrunch.com/2025/04/10/the-rise-of-ai-reasoning-models-is-making-benchmarking-more-expensive/</a> (data attributed to Artificial Analysis)</p>\n<p>[5] “Google must double AI serving capacity every 6 months to meet demand, AI infrastructure boss tells employees,” <em>CNBC</em>, Nov. 21, 2025. <a href=\"https://www.cnbc.com/2025/11/21/google-must-double-ai-serving-capacity-every-6-months-to-meet-demand.html\">https://www.cnbc.com/2025/11/21/google-must-double-ai-serving-capacity-every-6-months-to-meet-demand.html</a></p>\n<p>[6] S. Nadella and A. Hood, “Microsoft Fiscal Year 2026 First Quarter Earnings Conference Call,” Microsoft Corp., Oct. 29, 2025. <a href=\"https://www.microsoft.com/en-us/investor/events/fy-2026/earnings-fy-2026-q1\">https://www.microsoft.com/en-us/investor/events/fy-2026/earnings-fy-2026-q1</a></p>\n<p>[7] N. Patience, “AI Capex 2026: The $690B Infrastructure Sprint,” <em>Futurum Group</em>, Feb. 12, 2026. <a href=\"https://futurumgroup.com/insights/ai-capex-2026-the-690b-infrastructure-sprint/\">https://futurumgroup.com/insights/ai-capex-2026-the-690b-infrastructure-sprint/</a></p>\n<p>[8] NVIDIA Corp., “NVIDIA Announces Financial Results for Third Quarter Fiscal 2026,” Nov. 19, 2025. <a href=\"https://nvidianews.nvidia.com/news/nvidia-announces-financial-results-for-third-quarter-fiscal-2026\">https://nvidianews.nvidia.com/news/nvidia-announces-financial-results-for-third-quarter-fiscal-2026</a></p>\n<p>[9] K. MacKenzie, “Your Guide to Inference Cost (And Turning It Into Margin Advantage),” <em>CloudZero</em>, Dec. 5, 2025. <a href=\"https://www.cloudzero.com/blog/inference-cost/\">https://www.cloudzero.com/blog/inference-cost/</a></p>\n<p>[10] S. Nadella, post on X (formerly Twitter), Jan. 27, 2025. <a href=\"https://x.com/satyanadella/status/1883753899255046301\">https://x.com/satyanadella/status/1883753899255046301</a></p>\n",
      "summary": "Per-token prices have fallen 1,000× in three years. But the cost of a token and the cost of a decision are diverging — and the architectures most teams are building don’t account for the difference.",
      "date_published": "2026-02-28T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "Strategy",
        "agent-orchestration",
        "model-routing",
        "cost-efficiency",
        "ai-architecture"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/the-sharpening-loop",
      "url": "https://www.nateking.dev/blog/the-sharpening-loop",
      "title": "The Sharpening Loop",
      "content_html": "<p>Last week, a snowstorm rolled into town and blanketed the city in snow that the wind shaped into large drifts. I had gone out for dinner and found myself driving home in the middle of it—windshield partially iced over, traction far from a given. One of the reasons I love my car is the way it keeps me connected to the road. The steering tells me the road is slick before I have to act on it. You can feel the point where traction is about to be lost and have enough time to make a correction. You can tell which tires are slipping and which still grip. When I make a mistake—turn in too aggressively, carry too much speed—I feel the consequences immediately. The cost of error isn’t hidden; it’s present enough to make me drive better. The car doesn’t try to do the work for me. It tells me the truth and trusts me to act on it.</p>\n<h2>Trust as a Design Choice</h2>\n<p>Every tool sits somewhere on a spectrum from <em>respects the user</em> to <em>replaces the user’s judgment.</em></p>\n<p>Compare my car to one that intercepts the steering input, second-guesses throttle application, and silently applies corrections before the driver even registers a problem. That car is easier to drive in a snowstorm. It’s also teaching its driver absolutely nothing. And the moment the system encounters a scenario its engineers didn’t anticipate, the driver who never felt the road has no instincts to fall back on.</p>\n<p>The distinction isn’t analog vs. digital—it’s whether the tool assumes competence or incompetence. One machine says <em>here’s what’s happening—I trust you to handle it.</em> The other says <em>don’t worry about what’s happening—I’ll handle it for you.</em> Both get you home tonight. Only one makes you a better driver.</p>\n<h2>The Sharpening Loop</h2>\n<p>There’s a familiar saying: the craftsman sharpens the tool. But the more interesting half is that the right tool sharpens the craftsman.</p>\n<p>A typewriter makes you a better editor because you can’t cheaply revise—you learn to think in complete sentences before your fingers hit the keys. A car that telegraphs the road through its steering makes you a better driver because you have to read what it&#39;s telling you, not just point toward a destination.</p>\n<p>Good tools demand something from you, and in meeting that demand, you grow. That’s the sharpening loop: you invest effort into the tool, the tool asks effort of you, and over time both the work and the worker get better. Tools that remove the demand also remove the growth. They might make the output easier, but they make the person holding them gradually less capable.</p>\n<h2>The AI Question</h2>\n<p>AI is the most consequential version of this choice most of us will face. And the pressure to choose wrong is enormous.</p>\n<p>Consider two ways a team might use AI to handle customer problems. In the first, an AI system reads incoming requests, diagnoses the issue, drafts a response, and sends it—maybe with a human glancing at a queue of auto-resolved tickets. The team’s throughput doubles overnight. In the second, the AI surfaces the relevant history, flags patterns the agent might miss, and drafts a response the agent can edit, rewrite, or discard. Throughput improves less dramatically, but the agents stay in the loop.</p>\n<p>Six months in, the first team can’t explain why their resolution rates are declining. The AI is handling cases it was never trained on, and nobody catches it because nobody reads the tickets anymore. The people who understood the product deeply haven’t touched the work in months. They don’t understand it anymore. The system is confident and frequently wrong, and there’s no one left who can tell the difference.</p>\n<p>The second team is slower on paper. But their agents are sharper than they were six months ago. They’ve internalized the patterns the AI surfaces. They catch edge cases the model misses because they’re still in contact with the work. When the AI is wrong, they know—because they never stopped paying attention.</p>\n<p>The vendor pitch is always the same: <em>your people can’t handle the complexity, so let us automate it away.</em> It sounds like efficiency. It’s actually a bet that you’ll never need the judgment you’re discarding. And that bet almost always loses. The sharpening loop doesn’t care whether the tool is mechanical or digital—remove the human from the friction, and the human gets dull.</p>\n<h2>Choosing Your Instruments</h2>\n<p>Every tool you adopt is a bet on what kind of practitioner you want to become. The frictionless option is always available, and it always feels like progress in the moment. But friction is often where the learning lives.</p>\n<p>The question I keep coming back to: Does this make me sharper, or does it let me be dull?</p>\n",
      "summary": "Good tools demand something from you, and in meeting that demand, you grow. That's the sharpening loop. AI is the most consequential version of this choice most of us will face.",
      "date_published": "2026-02-25T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Product",
        "Strategy",
        "product-positioning",
        "attention-economics",
        "ai-business-model",
        "tool-design-philosophy"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/conceptual-last-mile",
      "url": "https://www.nateking.dev/blog/conceptual-last-mile",
      "title": "The Conceptual Last Mile",
      "content_html": "<p>There is an assumption embedded in nearly every conversation about AI adoption that the challenge is distribution—getting the tools in people’s hands and training users on the interface. This assumption is wrong. Anybody in a modern enterprise can open an AI assistant right now. The technology has been distributed, but the adoption won’t always follow.</p>\n<p>The real bottleneck isn’t access; it’s something much harder to solve. The last mile of AI adoption is conceptual—the gap between having a transformative tool and reconceiving what your job becomes with that tool.</p>\n<h2>The Diffusion Gap</h2>\n<p>In a <a href=\"https://www.nytimes.com/2026/02/12/opinion/artificial-intelligence-anthropic-amodei.html\">recent conversation with Ross Douthat</a>, Anthropic CEO Dario Amodei made an observation that deserves more attention than it got. He noted that software engineers have adopted AI tooling faster than nearly any other profession. The models aren’t inherently better at code, but because developers are “socially adjacent to the AI world.” They pay attention to what’s happening. They’re comfortable with rapid technological change. The distance between their existing identity and their AI-augmented identity is relatively short.</p>\n<p>Now consider the inverse. A compliance analyst at a regional bank, commercial loan officer, or paralegal reviewing documents. These professionals may have access to the same tools, but the distance they need to travel is enormous—not technically, but conceptually. This requires a new understanding of what their expertise means when a machine can do the procedural parts of their job in seconds.</p>\n<p>This is the diffusion gap. When we imagine an “AI future,” we tend to picture a uniform transformation—society shifting together into a new era. What actually happens is something more like tectonic plates moving at different speeds, and the friction shows up at the boundaries. Inside a single organization, you’ll have teams operating in 2028 alongside teams still operating in 2024. That unevenness is itself an underappreciated risk.</p>\n<h2>What the Last Mile Actually Looks Like</h2>\n<p>I’ve taught employees at a large financial institution to work with AI tools, and the pattern I see most often isn’t resistance or fear. It’s something more stubborn and less obvious.</p>\n<p>It’s the person who can demonstrate competence with the tool—and then returns to their desk and works exactly the way they did before because they haven’t yet reconciled what the tool implies about the nature of their work. This is the conceptual last mile. It’s the gap between capability and self-concept. And it’s where most AI adoption strategies fail.</p>\n<h2>The Centaur Phase Is Closing</h2>\n<p>Amodei used an analogy in the interview that I think is more urgent than it sounds. After Deep Blue defeated Garry Kasparov, there was an era in chess—roughly fifteen to twenty years—where a human working alongside an AI could defeat any human or any AI playing alone. Human judgment plus machine calculation was the strongest combination. That era is coming to an end. Now it’s just the machine.</p>\n<p>Amodei sees the same pattern in knowledge work, but compressed. We are in the centaur phase right now—the window where human expertise combined with AI produces the best outcomes. But the window is a transition state, and it may last only a few years.</p>\n<p>The people who never cross the conceptual last mile will miss this window entirely. They’ll go from doing the work the old way to being unable to compete with the machine doing it alone. This narrow centaur phase is our opportunity to redefine our roles while we still have leverage. But it requires something most organizations aren’t providing: identity management.</p>\n<p>Asking someone to move from performing cognitive work to directing AI that performs cognitive work is not a “skills upgrade.” <a href=\"https://www.nateking.dev/blog/pianississimo\">It’s a loss</a>. It means releasing the thing that made you valuable and replacing it with something less tangible. Supervision. Judgment. Knowing what to ask for and whether the output is right.</p>\n<h2>Build Over Buy</h2>\n<p>This is where a strategic question becomes existential: does your organization build its AI capability or buy it?</p>\n<p>The buy approach looks clean on a slide deck. License an enterprise platform, deploy it across the organization, measure ROI. But if the real bottleneck is conceptual and existential—if the actual barrier to adoption is people reconceiving their relationship to their own expertise—then procurement can’t solve it. An enterprise license doesn’t help someone cross the last mile. It just puts a powerful tool on the desktop of someone who doesn’t yet understand the new relationship with their own expertise.</p>\n<p>Build organizations are different, and not because they have better technology. They’re different because the process of building forces people to internalize the transition. When you build AI capability internally, you develop people who’ve wrestled with what these systems can and can’t do, who understand both the tool and the institutional context it’s entering, who embrace the discomfort of redefining their own expertise in the presence of new technology. That understanding doesn’t come from a vendor. It accumulates through years of building, failing, iterating, and thinking deeply inside the specific environment where the change needs to happen.</p>\n<p>There’s also an incentive problem worth naming. The vendor selling you the enterprise license has no structural incentive to help your people cross the conceptual last mile. Your dependency serves them. They want you to need the next upgrade, the next tier, the next feature. A build organization develops internal capacity that compounds. A buy organization develops external dependency that extracts.</p>\n<p>This doesn’t mean building everything from scratch. It means recognizing that the most important thing you’re building isn’t the system—that&#39;s a byproduct of people who understand the system deeply enough to bring everyone else across.</p>\n<h2>The Real Infrastructure</h2>\n<p>The companies that navigate this transition won’t be the ones that spent the most on licenses. They’ll be the ones that understood, early enough, that the bottleneck was identity. They invested accordingly—in people who could sit at the boundary between the technology and the workforce and translate not the tool, but the meaning of the tool. People who had crossed the conceptual last mile themselves and could guide others through it. The important infrastructure of AI adoption is human, it’s slow, and you can’t buy it.</p>\n",
      "summary": "The last mile of AI adoption isn't access—it's the gap between having a transformative tool and reconceiving what your job becomes with it.",
      "date_published": "2026-02-15T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "ai-adoption",
        "build-vs-buy",
        "organizational-learning",
        "identity-management"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/pianississimo",
      "url": "https://www.nateking.dev/blog/pianississimo",
      "title": "Pianississimo",
      "content_html": "<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/pianississimo-title.jpeg\" alt=\"\"></p>\n<p>After a storm, I found a piano that had been left outside. The kind of instrument someone places in a park because they rightly believe in the transformative power of the arts. The storm didn&#39;t share that belief. It took the finish off the wood and warped what it could reach.</p>\n<p>I sat down and attempted a Chopin Nocturne. The piano refused. Some keys stuck while others gave only silence. It was, by any reasonable measure, a broken instrument.</p>\n<p>I almost got up. There&#39;s a particular embarrassment in trying to make music from something that can no longer produce it. The dignified thing would have been to stand, acknowledge the loss, and walk away. I kept playing.</p>\n<p>On the keys, a scrap of sheet music had survived. Curled, rain-stained, marked <em>ppp</em>. Pianississimo. As quiet as possible. The storm had taken nearly everything, and what remained was a whisper. I photographed it because it was still there. It sat with a weathered defiance that appealed to me.</p>\n<p>Somewhere, a freshly tuned Steinway sits in a concert hall, capable of producing the entire Nocturne with precision that piano will never match—every note tuned to perfection, every hammer voiced to match its neighbor. But what I photographed wasn&#39;t a performance, and the piano was no longer an instrument. Yet, it survived.</p>\n<p>Lately, I&#39;ve been thinking about that piano when I sit down to write, knowing a model could produce a competent version of this essay in seconds. I think about it when I practice, knowing a recording exists of every piece I&#39;ll ever learn, performed better than I will ever perform it.</p>\n<p>Every domain of expertise has its protected claim. For writers, voice. For musicians, interpretation. For programmers, the elegant architectural solution committed to code. Every one of those claims rests on the same foundation: the belief that human cognition is categorically different from computation. Not just different in degree but different in kind.</p>\n<p>This was never an empirical argument. It was a theological one. We needed it to be true, so we defended it like doctrine. Each key that goes silent, we tell ourselves the next one will hold. The obvious question we&#39;re compelled to ask at this point is: <em>Are we special?</em></p>\n<p>It feels urgent. It feels like the question. And it sends you down a path with no good ending, because you&#39;re asking a machine to adjudicate your own significance. You&#39;ve defined your value as a function of scarcity, and scarcity is exactly what these systems destroy.</p>\n<p>I know this because I&#39;ve been down the path. I build AI systems for a living, which means I occupy the particular absurdity of automating the kind of work I was trained to do by hand. I&#39;ve watched tasks that once took a team of engineers and a quarter&#39;s worth of effort collapse into an afternoon. I&#39;ve built the tools that collapsed them. There were nights I closed my laptop and couldn&#39;t name what, exactly, I was still for. The ground I stand on is ground I&#39;m actively reshaping. If that sounds like vertigo, it is.</p>\n<p>So I grieved. Not loudly, not dramatically—but in the subtle way you grieve something that disappears as you&#39;re still using it. The version of myself that was special <em>because</em> no machine could do what I do. That grief is real, and no one should pretend it doesn&#39;t cost something. But grief is not the same as truth. And the question we should be asking isn&#39;t &quot;are we special?&quot; It&#39;s: <em>does it matter?</em></p>\n<p>The instinct is to grip tighter. To master the new tools faster than they master your role. To stay one version ahead. And there is practical wisdom in that—I won&#39;t pretend otherwise. Adaptability is not optional. But adaptability is a strategy, not a reason to get out of bed.</p>\n<p>It&#39;s the same impulse that almost let me walk past a broken piano in a park—and then wouldn&#39;t. The desire to reach for something, even when reaching doesn&#39;t guarantee arrival. Especially then. We have always built, written, composed, and solved not because we were the only ones who could, but because the reaching is how we know ourselves. The carpenter doesn&#39;t stop working wood because a factory can produce furniture faster. The work changes. The tools change. The reaching doesn&#39;t.</p>\n<p>I write knowing a model can write. I play knowing a recording exists. I build knowing the thing I build today may build itself tomorrow. None of that has made me want to stop. If anything, it has clarified what the wanting always was—not a bid for superiority, but something closer to necessity. Not because you&#39;re the best at it. Because it&#39;s <em>yours</em>.</p>\n<p>The storm took nearly everything from that piano. I played it anyway, because my desire to play is inexhaustible.</p>\n",
      "summary": "I build AI systems for a living, which means I occupy the particular absurdity of automating the kind of work I was trained to do by hand.",
      "date_published": "2026-02-13T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Personal",
        "ai-displacement",
        "human-craft",
        "automation",
        "existential-reflection"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/pianississimo-title.jpeg"
    },
    {
      "id": "https://www.nateking.dev/blog/space-to-think",
      "url": "https://www.nateking.dev/blog/space-to-think",
      "title": "A Space to Think",
      "content_html": "<p>Anthropic just released an article titled <a href=\"https://www.anthropic.com/news/claude-is-a-space-to-think\">Claude is a Space to Think</a>, which takes a clear stance on advertising. It begins with an unequivocal statement:</p>\n<blockquote>\n<p>“There are many good places for advertising. A conversation with Claude is not one of them.”</p>\n</blockquote>\n<p>Then continues:</p>\n<blockquote>\n<p>“But including ads in conversations with Claude would be incompatible with what we want Claude to be: a genuinely helpful assistant for work and for deep thinking.</p>\n<p>We want Claude to act unambiguously in our users’ interests. So we’ve made a choice: Claude will remain ad-free. Our users won’t see ‘sponsored’ links adjacent to their conversations with Claude; nor will Claude’s responses be influenced by advertisers or include third-party product placements our users did not ask for.”</p>\n</blockquote>\n<p>This is in direct contrast to OpenAI, which plan to start <a href=\"https://openai.com/index/our-approach-to-advertising-and-expanding-access/\">displaying ads to adults in the U.S. on the free and Go tiers</a>. It’s refreshing to see a company take a clear stance. Whether Anthropic sustains it over time is an open question, but the act of staking the position publicly creates accountability.</p>\n<h2>Instruments with a Singular Allegiance</h2>\n<p>Tools should be designed to <em>serve</em> your intention, not to <em>hold</em> it. They exist to translate your intention into a result as directly and precisely as possible.</p>\n<p>The moment an AI assistant carries advertising, it acquires a second allegiance. Even if the ads are “clearly labeled and separate,” the product now serves two masters. The design decisions, the engagement metrics, the feature roadmap—all of it must now account for the advertiser’s interests alongside the user’s.</p>\n<p>The absence of interruption isn’t a luxury—it’s a basic prerequisite for the kind of thinking an AI assistant enables. Anything that generates attentional residue is a corruption of the tool’s fundamental purpose.</p>\n<h2>The Ratchet</h2>\n<p>OpenAI promises that ads will be “separate and clearly labeled.” This promise has a long lineage of failure in the tech industry.</p>\n<p>Early Google ads were a thin strip of text above organic results, set apart by a colored background. Today, the first full screen of many Google searches is ads, and the visual distinction between paid and organic results has been systematically eroded over two decades. Facebook’s News Feed launched without advertising. The design pressure is always in one direction: make the ad feel more native, more integrated, and less distinguishable. Not because anyone plans this at the outset, but because the revenue incentive rewards it quarter after quarter.</p>\n<p>Anthropic names this dynamic directly: “advertising incentives, once introduced, tend to expand over time as they become integrated into revenue targets and product development, blurring boundaries that were once more clear-cut.” This isn’t cynicism; It’s just how organizational incentives work. The boundaries that seem firm at launch become negotiable once they’re standing between the company and its growth targets.</p>\n<p>OpenAI’s own announcement already contains the seeds. Their vision includes users being able to “start a direct chat with a bot aligned with that advertiser”—not just ads adjacent to responses, but advertiser-controlled AI conversations embedded within the product. The boundary is blurring before testing has even scaled.</p>\n<h2>The Shortest Path</h2>\n<p>Perhaps the sharpest line in Anthropic’s piece: “The most useful AI interaction might be a short one.”</p>\n<p>An ad-supported product has no structural reason to help you finish quickly. A tool designed as a space to think has every reason to. If you ask an AI to help you debug a function, the ideal outcome is a correct answer in one exchange. An ad-supported model that displays one ad per response has a subtle but real incentive to stretch that interaction across multiple turns.</p>\n<p>The incentive may never be acted on deliberately. But it shapes the metrics the company optimizes for, which shapes the product over time. When engagement becomes a KPI, brevity becomes a cost.</p>\n<p>Anthropic closes their piece with an image worth sitting with: &quot;Open a notebook, pick up a well-crafted tool, or stand in front of a clean chalkboard, and there are no ads in sight.&quot; The best tools disappear into the work. That&#39;s a standard worth holding AI to. I don&#39;t know if Anthropic will hold this line forever. But I know which kind of tool I want to think with.</p>\n",
      "summary": "Anthropic commits to keeping Claude ad-free while OpenAI moves toward advertising. The choice reveals fundamentally different visions for what an AI assistant should be.",
      "date_published": "2026-02-05T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Product",
        "product-positioning",
        "attention-economics",
        "ai-business-model",
        "tool-design-philosophy"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/applied-humanism",
      "url": "https://www.nateking.dev/blog/applied-humanism",
      "title": "Applied Humanism: What Renaissance Thinkers Can Teach Us About AI",
      "content_html": "<p>I build AI systems for a living. I teach people to use them, I help write governance frameworks for them, and I think constantly about what they mean for the organization I work for. Most software engineers are focused on a single question: <em>What are we building?</em> They evaluate models, benchmark performance, calculate ROI. These capabilities matter.</p>\n<p>But I&#39;ve become convinced that we need people asking a second question at the same time: <em>What are we becoming?</em> That second kind of seeing is humanistic work. And for guidance on how to do it, I&#39;ve been returning to an unlikely source: the Renaissance.</p>\n<p>The word <em>humanism</em> comes from <em>studia humanitatis</em>—the humanities—which Renaissance thinkers recovered from classical antiquity. Petrarch, often called the father of humanism, believed that reading Cicero and Virgil wasn&#39;t merely intellectual exercise but moral formation. The ancients had thought deeply about how to live, and their wisdom remained available to anyone who would engage it.</p>\n<p>This was radical. It suggested that meaning and virtue weren&#39;t dispensed only through ecclesiastical authority but could be pursued through education, reflection, and the cultivation of character.</p>\n<p>But here&#39;s what gets lost in popular accounts of Renaissance humanism: these weren&#39;t monks retreating to libraries. The humanists cared intensely about practical effect. They studied rhetoric because they wanted to persuade. They advised princes because they wanted to shape policy. They believed that a person formed by the humanities would act more wisely in the world—not escape from it. Civic virtue, for them, was the point.</p>\n<p>The becoming question isn&#39;t a retreat from practical concerns. It&#39;s the most practical concern there is.</p>\n<h2>The Weakening of Humanistic Assumptions</h2>\n<p>We&#39;re living through a moment when humanistic assumptions have profoundly weakened—and the common thread is this: human judgment is increasingly treated as a problem to be solved rather than a capacity to be cultivated. Markets optimize around it. Algorithms route around it. Political discourse treats persuasion as naive when you can simply mobilize your base. Even universities have retreated from the humanities, the disciplines that once existed precisely to form judgment rather than replace it.</p>\n<p>Meanwhile, technology poses genuinely new questions. If AI can write competent prose, what is the value of human writing? If algorithms can optimize decisions, what role remains for human judgment?</p>\n<p>The instinct, for many technologists, is to dismiss these questions as hand-wringing—the anxious complaints of people being displaced. But we need to take them seriously. Not because AI will replace human judgment, but because <em>how we use AI shapes what human judgment becomes</em>. The question isn&#39;t whether humans remain in the loop. It&#39;s what kind of humans, with what capacities, exercising what kind of judgment.</p>\n<p>The Renaissance humanists understood this about education: you don&#39;t just transmit information, you form identity. The same is true of technology adoption. Every tool teaches its users something through its design choices.</p>\n<h2>What Technology Adoption Teaches</h2>\n<p>Technology adoption shapes organizational culture. It sends signals about what&#39;s valued, what&#39;s rewarded, what kind of people thrive. An organization that adopts AI purely for efficiency becomes a place where efficiency is the highest value—where people learn to optimize, to move fast, to reduce friction. This isn&#39;t necessarily bad, but it is a choice, and it has consequences.</p>\n<p>An organization that adopts AI humanistically becomes something different: a place where people are expected to exercise judgment, to take responsibility, and to think carefully about consequences. Where the question &quot;should we?&quot; is given as much weight as &quot;can we?&quot; Where the humans in the loop are genuinely empowered to be human—which means empowered to be slow, to be uncertain, to refuse the obvious optimization when something about it feels wrong.</p>\n<p>This is what the second question forces you to see: not just the immediate capability gain, but the slow reshaping of human capacity that follows.</p>\n<h2>Luddism in a Toga</h2>\n<p>I can hear the objection: this is just technophobia dressed up in Renaissance costume. Another humanist wringing his hands while the builders build.</p>\n<p>But I <em>am</em> a builder. I deploy these systems. I teach people to use them. I&#39;ve seen what they can do, and I want more of it—more capability, more reach, more of the genuine good that comes from augmenting human capacity with machine intelligence. The question isn&#39;t whether to build. That&#39;s settled. The question is whether we&#39;re paying attention to what the building does to us.</p>\n<p>The Luddites smashed looms because they saw their livelihoods threatened. That&#39;s not what I&#39;m describing. I&#39;m describing something more like what a master craftsman knows: that how you work shapes who you become. A carpenter who rushes every joint eventually loses the ability to see when a joint needs care. A writer who optimizes for engagement eventually loses the ear for prose that serves a different purpose. The tool doesn&#39;t just produce output. It molds perception.</p>\n<p>This isn&#39;t an argument against capability. It&#39;s an argument for a certain kind of attention <em>while</em> building capability. The humanist question—what are we becoming?—doesn&#39;t slow the work down. It focuses the work on what is most valuable.</p>\n<p>Most decisions should be optimized. Most processes should be made more efficient. The humanistic instinct isn&#39;t to resist optimization but to notice when optimization has become the only lens available—when &quot;is this efficient?&quot; has crowded out &quot;is this wise?&quot; or &quot;is this what we should want?&quot; The discipline is knowing when to ask the second kind of question. Not always. But sometimes. And not losing the capacity to recognize which is which.</p>\n<h2>The Practitioner&#39;s Discipline</h2>\n<p>Here&#39;s the deepest humanistic question for anyone doing this work: What is immersion in AI systems doing to <em>you</em>?</p>\n<p>The danger isn&#39;t that you&#39;ll become a machine. It&#39;s subtler. It&#39;s that you&#39;ll start to see the world through the lens of optimization—that you&#39;ll lose patience with the slow, inefficient, gloriously human ways people muddle through problems. The occupational hazard of AI work is that it colonizes your perception.</p>\n<p>Consider commercial lending. There&#39;s a version of AI adoption that keeps the process personal but makes it faster—the relationship officer still knows the borrower&#39;s business, still exercises judgment about factors that don&#39;t fit neatly into a credit model, but spends less time on document processing and data gathering. And there&#39;s another version that optimizes the human out entirely: faster still, more consistent, scalable in ways the first version never will be.</p>\n<p>For a large institution competing on rates, the second version might make sense. But a smaller lender can&#39;t win on rates. What they have is the relationship—the officer who knows that this borrower&#39;s financials look weak because they just invested heavily in equipment that will pay off next quarter, or who senses something off despite clean numbers. Optimize that away and you haven&#39;t just lost a feature. You&#39;ve eliminated the only advantage you had.</p>\n<p>The danger isn&#39;t that someone decides to kill the relationship. It&#39;s that the metrics don&#39;t capture it, so it gradually stops being visible as a thing worth protecting. That&#39;s what colonized perception looks like: not malice, but a slow narrowing of what counts as important.</p>\n<p>Keeping that question alive—<em>what are we becoming?</em>—requires counterweights: practices that resist the logic of efficiency, that insist on particularity and ambiguity, that develop patience rather than speed.</p>\n<p>I print photographs in a darkroom. Not because the results are better than what I could achieve digitally—they&#39;re not, by most measures—but because the process resists everything my professional life rewards. Chemical development has fixed timing you cannot negotiate with. You stand in darkness, watching an image emerge on its own schedule, and no amount of urgency will make the silver halides react faster. The enlarger doesn&#39;t care about your deadline. The fixer takes exactly as long as it takes.</p>\n<p>This is not productivity. It&#39;s practice—in the older sense, the way a pianist practices scales or a writer keeps a journal. The point isn&#39;t output. The point is maintaining a capacity that optimization erodes: the ability to work at a pace the work demands rather than the pace I prefer.</p>\n<p>The specific practice matters less than the discipline of maintaining one. What matters is having something in your life that refuses to be optimized—that teaches you, over and over, that not everything worth doing submits to efficiency. Without that counterweight, the colonization is silent and complete.</p>\n<h2>The Urgency of the Humanities</h2>\n<p>Petrarch read Cicero because he believed the ancients had something to teach him about how to live. The questions they asked—about virtue, about civic responsibility, about what we owe each other—weren&#39;t antiquarian curiosities. They were urgent, practical necessities for anyone who wanted to act well in the world.</p>\n<p>We build AI systems that will reshape how millions of people work, decide, and relate to one another. The question of how to live hasn&#39;t gotten smaller. It&#39;s gotten more urgent.</p>\n<p>The humanities aren&#39;t a luxury we&#39;ve outgrown. They&#39;re a discipline we desperately need—now more than ever, and especially for those of us building the machines. Not because they&#39;ll make us more cultured or well-rounded, but because they&#39;re how we learn to ask both questions: <em>What are we building?</em> and <em>What are we becoming?</em></p>\n<p>The Renaissance humanists understood that practical wisdom required formation—that you couldn&#39;t act well in the world without becoming a certain kind of person. They were right. The open question is whether we&#39;ll still believe that in ten years—or whether we&#39;ll have optimized our way out of understanding why it mattered.</p>\n",
      "summary": "Every tool teaches its users something. The question for AI practitioners isn't just what we're building—it's what we're becoming.",
      "date_published": "2026-02-01T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "human-judgment",
        "organizational-culture",
        "tech-ethics",
        "optimization-tradeoffs"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/pageindex-rag-alternative",
      "url": "https://www.nateking.dev/blog/pageindex-rag-alternative",
      "title": "PageIndex as RAG Alternative: A Comparative Evaluation of Vectorless Document Retrieval",
      "content_html": "<p>I spent the past week building an evaluation harness to compare PageIndex—VectifyAI&#39;s &quot;vectorless, reasoning-based RAG&quot; system—against a traditional RAG pipeline on commercial loan documents. The hypothesis was intuitive: tree-structured retrieval that reasons about document organization should outperform similarity search on complex queries, even if it underperforms on simple lookups.</p>\n<p>The hypothesis was wrong.</p>\n<h2>The Setup</h2>\n<p><strong>Traditional pipeline:</strong> PyMuPDF4LLM → 1,000-character chunks with 200 overlap → Voyage 3 Large embeddings → FAISS top-5 → Claude Sonnet 4</p>\n<p><strong>PageIndex pipeline:</strong> PDF → PageIndex Cloud API (tree generation) → reasoning-based traversal → Claude generation (server-side)</p>\n<p>Same generation model. Same questions. Same ground truth. The only variable is the retrieval mechanism.</p>\n<p>I ran 36 questions across commercial loan documents—credit memos, appraisals, the structurally heterogeneous stuff that makes RAG hard.</p>\n<h2>The Results</h2>\n<table>\n<thead>\n<tr>\n<th>Metric</th>\n<th>Traditional</th>\n<th>PageIndex</th>\n</tr>\n</thead>\n<tbody><tr>\n<td>Answer correctness</td>\n<td>47%</td>\n<td>22%</td>\n</tr>\n<tr>\n<td>Hallucination rate</td>\n<td>0%</td>\n<td>25.5%</td>\n</tr>\n<tr>\n<td>Avg latency</td>\n<td>4.7s</td>\n<td>27.2s</td>\n</tr>\n<tr>\n<td>Cost per correct answer</td>\n<td>$0.014</td>\n<td>$0.019</td>\n</tr>\n</tbody></table>\n<p>Traditional RAG won on every metric that matters. Not by a little—by 25 percentage points on accuracy, with zero hallucinations versus one-in-four claims unsupported.</p>\n<p>The only metric favoring PageIndex is raw cost per query ($0.0043 vs $0.0065), an advantage that evaporates when you normalize by quality.</p>\n<h2>Why the Gap?</h2>\n<p><strong>Recall drives accuracy.</strong> Traditional retrieval&#39;s top-5 chunks achieved 80% recall on source pages. PageIndex&#39;s tree traversal achieved 58%. When the generation model has the relevant context, it produces correct answers. When it doesn&#39;t, it either fails or hallucinates. PageIndex&#39;s &quot;targeted&quot; retrieval is too targeted — it misses content that broad similarity search reliably surfaces.</p>\n<p><strong>Latency is architectural.</strong> Vector search is sub-millisecond. Tree traversal requires sequential LLM reasoning at each level, plus polling overhead. The 5.8x latency gap isn&#39;t fixable with optimization; it&#39;s inherent to the approach.</p>\n<p><strong>Multi-location synthesis breaks both.</strong> Neither pipeline handled questions requiring information from multiple document sections (14% correct each). This is the shared failure mode that better architectures — iterative retrieval, query decomposition, graph-based navigation — might address.</p>\n<h2>But What About Mafin 2.5&#39;s 98.7%?</h2>\n<p>VectifyAI claims their Mafin 2.5 system achieves 98.7% on FinanceBench. Three factors explain the gap:</p>\n<p><strong>System scope differs.</strong> Mafin 2.5 is a tuned application layer built <em>on</em> PageIndex, not the raw API. It likely includes orchestration, prompt engineering, and multi-step reasoning that the Cloud API doesn&#39;t expose.</p>\n<p><strong>Evaluation methodology differs.</strong> Their benchmark includes human re-annotation for ambiguous questions. The FinanceBench paper shows GPT-4-Turbo with retrieval at 19% under strict scoring; my traditional pipeline hit 47%, exactly matching published baselines.</p>\n<p><strong>Document characteristics differ.</strong> FinanceBench uses standardized SEC filings with predictable structure (Item 1, Item 1A, Item 7). Commercial loan documents are structurally heterogeneous. Tree traversal may work better on documents with consistent hierarchies.</p>\n<p>None of this invalidates their claims or my findings. They&#39;re answering different questions.</p>\n<h2>When to Use What</h2>\n<p><strong>Favor traditional RAG when:</strong></p>\n<ul>\n<li>Accuracy matters and errors carry risk</li>\n<li>You need sub-10-second responses</li>\n<li>Documents have heterogeneous structure</li>\n<li>Hallucination is unacceptable</li>\n</ul>\n<p><strong>Consider PageIndex when:</strong></p>\n<ul>\n<li>Documents have highly consistent structure (standardized forms, regulatory filings)</li>\n<li>The full Mafin 2.5 system is available for your domain</li>\n<li>Latency tolerance exceeds 30 seconds</li>\n<li>Eliminating vector infrastructure is a priority and you&#39;ll accept the accuracy tradeoff</li>\n</ul>\n<p><strong>Consider neither when:</strong></p>\n<ul>\n<li>Questions require synthesis across non-adjacent document sections</li>\n<li>You need explicit source citations in every answer</li>\n</ul>\n<h2>The Bottom Line</h2>\n<p>PageIndex&#39;s architectural premise is sound: document structure carries information that chunking destroys, and reasoning about where to look should beat geometric similarity on complex queries. But the implementation—at least as exposed through the Cloud API—doesn&#39;t deliver on that promise. For commercial loan documents, traditional RAG is faster, more accurate, cheaper per correct answer, and produces zero hallucinations.</p>\n<p>The evaluation harness and full methodology are available in <a href=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/pageindex-rag-evaluation.pdf\">the complete paper</a>. If you&#39;re evaluating PageIndex for your own use case, I&#39;d encourage you to run a similar comparison on your documents before committing.</p>\n",
      "summary": "A controlled empirical comparison between traditional vector-based RAG and PageIndex's reasoning-based retrieval on commercial loan documents.",
      "date_published": "2026-01-24T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "rag",
        "semantic-search",
        "retrieval-systems",
        "embeddings"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/the-bet-apple-didnt-need-to-place",
      "url": "https://www.nateking.dev/blog/the-bet-apple-didnt-need-to-place",
      "title": "The Bet Apple Didn't Need to Place",
      "content_html": "<p>The original iPhone wasn&#39;t the first smartphone. Multi-touch existed. Mobile browsers existed. App ecosystems existed in fragments. What Apple shipped wasn&#39;t a breakthrough technology so much as a resolved one. The experience felt finished in a way competitors&#39; devices did not. Not more powerful—more coherent.</p>\n<p>Apple&#39;s greatest strength has never been raw technological supremacy, but the ability to make complex technologies feel complete, inevitable, and human. That pattern is worth remembering now, because Apple just made what looks like the defining strategic bet of the AI era—and it wasn&#39;t a model.</p>\n<p>Earlier this month, Apple announced a <a href=\"https://www.cnbc.com/2026/01/12/apple-google-ai-siri-gemini.html\">multiyear partnership with Google</a> to build its foundation models on Gemini and Google Cloud infrastructure—including the long-delayed Siri overhaul expected later this year. Bloomberg previously reported the deal at roughly $1 billion annually. Apple&#39;s statement framed it as a capability decision: &quot;Google&#39;s technology provides the most capable foundation for Apple Foundation Models.&quot; The models will still run on Apple devices and Apple&#39;s private cloud compute. On the surface, it reads as a concession. In context, it reads as a thesis.</p>\n<p>The thesis is this: as AI models converge in capability, the integration layer—not the model itself—is where value accrues.</p>\n<p>That convergence is already underway. API pricing has collapsed. Multi-model routing is becoming standard practice. Enterprises increasingly treat foundation models as interchangeable backends, selecting between them based on cost, latency, or task fit rather than loyalty to a single provider. The gap between the best model and the fifth-best model is shrinking faster than the gap between the best-integrated experience and the fifth-best one.</p>\n<p>Intelligence without integration is a feature. Intelligence embedded at the platform level is infrastructure. And the companies that control infrastructure capture the economics.</p>\n<p>This is Apple&#39;s natural position. It always has been.</p>\n<p>For much of the past year, Apple&#39;s apparent pursuit of frontier AI models felt out of character. Not incompetent—misaligned. Building competitive foundation models requires an institutional posture Apple has never cultivated and has rarely rewarded: large, research-first organizations; incentives to publish; public iteration; and a tolerance for long feedback loops with uncertain payoff.</p>\n<p>Apple is the opposite.</p>\n<p>Apple is secretive by design. Product-driven to the point of obsession. Optimized for shipping integrated systems on a predictable cadence. Its most important successes—Apple Silicon chief among them—weren&#39;t research moonshots so much as acts of ruthless vertical integration. Apple doesn&#39;t win by inventing primitives. It wins by deciding which primitives matter and erasing the seams between them.</p>\n<p>Competing at the frontier was never a bet Apple needed to win. It was a bet Apple didn&#39;t need to place.</p>\n<p>What Apple <em>does</em> have—what no AI lab can replicate—is leverage at the integration layer: billions of active devices, the world&#39;s best consumer silicon for inference, total control of the operating system, and a privacy brand users actually trust. These are not advantages for training models. They are multipliers for deploying them.</p>\n<p>The Gemini partnership makes this explicit. Apple is licensing intelligence while retaining ownership of the experience. The architectural details matter: models run on-device where possible, private cloud execution preserves the privacy posture, and intelligence is abstracted behind the platform boundary rather than exposed as a visible third-party dependency.</p>\n<p>Apple isn&#39;t outsourcing the product. It&#39;s outsourcing the commodity, but commodities have suppliers. And suppliers have strategies of their own.</p>\n<p>Look at this deal from Google&#39;s side and the calculus inverts. By becoming the intelligence layer on both major mobile operating systems, Google has achieved what Microsoft spent billions trying to buy through OpenAI: default distribution at planetary scale [1]. The iOS rollout alone could push Gemini past a billion active users—a feedback loop for model refinement that no research lab can replicate, even if Apple&#39;s privacy architecture limits what data flows back [2].</p>\n<p>The architecture tells a more uncomfortable story. The new Siri comprises three core components: a query scheduler, a knowledge search system, and a summarizing function. Two of the three run on Gemini [3]. Only on-device processing remains Apple&#39;s own. What Apple frames as outsourcing a commodity looks, from another angle, like embedding a competitor&#39;s technology into the structural core of its flagship product.</p>\n<p>The deeper Gemini integrates, the harder it becomes to replace—and the private cloud infrastructure Apple builds around it only compounds the inertia [3]. Google&#39;s playbook here mirrors the search deal: become so embedded that alternatives remain theoretical. If Google can improve Gemini faster than Apple can develop its own frontier model, the dependency becomes self-reinforcing [4].</p>\n<p>Apple is paying roughly $1 billion a year for this arrangement—trivial against the $20 billion Google pays Apple for search defaults. But the economics flow differently. In the search deal, Google gets direct monetization. In the Gemini deal, Google gets something potentially more durable: infrastructure lock-in on a competitor&#39;s platform, plus the credibility to win similar partnerships elsewhere [5].</p>\n<p>But the thesis has an obvious vulnerability. ChatGPT&#39;s explosive consumer adoption suggests that a sufficiently capable model can generate its own distribution—bypassing the platform layer entirely. If users go directly to the model, the integration layer loses its leverage. This is a real risk, and Apple knows it. But it is also, so far, the exception rather than the pattern. Most AI usage is not destination-seeking. It&#39;s ambient—triggered by context, embedded in workflows, surfaced at the moment of need. That ambient layer is exactly what Apple controls.</p>\n<p>The Gemini deal also clarifies the lingering questions around Apple&#39;s relationship with OpenAI. Officially, nothing changes. Architecturally, that may even be true—for now. Multiple models can coexist. Routing logic can decide which capability answers which request. But experience design has gravity, and gravity pulls toward coherence.</p>\n<p>The integration of ChatGPT always felt transitional—a bridge that allowed Apple to ship credible AI features while it determined its long-term posture. Removing it abruptly would generate noise and backlash. Letting it quietly recede as Gemini-powered capabilities expand does not.</p>\n<p>If that happens, it won&#39;t look like a breakup. It will look like neglect.</p>\n<p>The broader implication extends beyond Apple. As models improve and costs fall, intelligence itself becomes less scarce. What remains scarce is trust, distribution, context, and control over the environment in which intelligence operates. The companies that win in this phase won&#39;t necessarily be the ones with the smartest models, but the ones that decide how intelligence is surfaced, constrained, and woven into everyday life.</p>\n<p>The risk is real: every year this deal continues, Google&#39;s infrastructure embeds deeper and Apple&#39;s switching costs compound. The integration layer only retains its leverage if switching the model beneath it remains credible. If it doesn&#39;t—if Gemini becomes load-bearing in ways that can&#39;t be abstracted—then Apple hasn&#39;t outsourced a commodity. It has ceded a dependency.</p>\n<p>But that outcome isn&#39;t inevitable. It requires Apple to stop doing what Apple does best: controlling the seams. The history says they won&#39;t.</p>\n<p>Apple doesn&#39;t need to build the best mind in the room. It needs to own the room itself—and keep the doors wide enough that no single supplier controls who enters.</p>\n<hr>\n<p><strong>References</strong></p>\n<p>[1] &quot;The Gemini Mandate: Apple and Google Form Historic AI Alliance to Overhaul Siri,&quot; <em>Financial Content</em>, Jan. 16, 2026. [Online]. Available: <a href=\"https://markets.financialcontent.com/wral/article/tokenring-2026-1-16-the-gemini-mandate-apple-and-google-form-historic-ai-alliance-to-overhaul-siri\">https://markets.financialcontent.com/wral/article/tokenring-2026-1-16-the-gemini-mandate-apple-and-google-form-historic-ai-alliance-to-overhaul-siri</a></p>\n<p>[2] &quot;Siri&#39;s New Brain: Apple Taps Google Gemini to Power Deep Intelligence Layer,&quot; <em>Financial Content</em>, Jan. 19, 2026. [Online]. Available: <a href=\"https://markets.financialcontent.com/stocks/article/tokenring-2026-1-19-siris-new-brain-apple-taps-google-gemini-to-power-deep-intelligence-layer-in-massive-2026-strategic-pivot\">https://markets.financialcontent.com/stocks/article/tokenring-2026-1-19-siris-new-brain-apple-taps-google-gemini-to-power-deep-intelligence-layer-in-massive-2026-strategic-pivot</a></p>\n<p>[3] &quot;The End of iPhone Sovereignty?,&quot; <em>Xpert Digital</em>, Jan. 2026. [Online]. Available: <a href=\"https://xpert.digital/en/the-end-of-iphone-sovereignty/\">https://xpert.digital/en/the-end-of-iphone-sovereignty/</a></p>\n<p>[4] &quot;No, Google Gemini Will Not Be Taking Over Your iPhone, Apple Intelligence, or Siri,&quot; <em>AppleInsider</em>, Jan. 12, 2026. [Online]. Available: <a href=\"https://appleinsider.com/articles/26/01/12/no-google-gemini-will-not-be-taking-over-your-iphone-apple-intelligence-or-siri\">https://appleinsider.com/articles/26/01/12/no-google-gemini-will-not-be-taking-over-your-iphone-apple-intelligence-or-siri</a></p>\n<p>[5] &quot;Google&#39;s Gemini–Apple Deal: A Defining AI Moment,&quot; <em>Deriv</em>, Jan. 2026. [Online]. Available: <a href=\"https://deriv.com/blog/posts/google-gemini-apple-defining-ai-moment\">https://deriv.com/blog/posts/google-gemini-apple-defining-ai-moment</a></p>\n",
      "summary": "As AI models commoditize, power shifts upward. The real competition is no longer intelligence itself, but who controls where intelligence lives.",
      "date_published": "2026-01-23T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "apple-intelligence",
        "platform-integration",
        "model-commoditization",
        "vendor-lock-in"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/strategic-case-provider-agnostic-ai",
      "url": "https://www.nateking.dev/blog/strategic-case-provider-agnostic-ai",
      "title": "The Strategic Case for Provider-Agnostic AI Architecture",
      "content_html": "<div class=\"text-center\">\n<em>Why Heterogeneous Model Deployment Should Become the Enterprise Standard</em>\n</div>\n\n<hr>\n<p>The AI industry is undergoing a fundamental architectural shift. After years of treating frontier large language models as the default solution for every task, organizations are discovering that strategic flexibility and right-sized model selection deliver superior economics and operational resilience. Two related patterns are emerging as enterprise best practices: provider-agnostic infrastructure that avoids vendor lock-in, and heterogeneous architectures that route workloads to appropriately sized models.</p>\n<p>These approaches are mutually reinforcing. Provider-agnostic infrastructure enables heterogeneous deployment, while heterogeneous architectures create the competitive pressure that makes provider independence strategically essential. Together, they represent a maturation from experimental AI adoption toward production-grade systems designed for accountability, cost control, and sustained competitive advantage.</p>\n<h2>The Economics of Model Selection</h2>\n<p>The cost differentials between model tiers have become impossible to ignore. Running a 7 billion parameter small language model costs 10-30 times less than deploying a 70-175 billion parameter frontier model for equivalent tasks [1]. When NVIDIA Research analyzed popular agent frameworks, they found that 40-70% of large language model invocations could be reliably handled by appropriately specialized smaller models [1].</p>\n<p>This finding challenges the industry&#39;s $57 billion infrastructure investment in centralized large model hosting [2]. The LLM API market generated approximately $5.6 billion in 2024, creating a striking 10-to-1 gap between infrastructure investment and actual revenue [2]. Organizations that outsource everything to frontier model APIs are paying dramatically more than necessary for nearly half their workloads.</p>\n<p>The heterogeneous architecture pattern addresses this mismatch directly. In this approach, a router classifies incoming requests and directs them to the appropriate model tier: small language models handle 60-70% of requests involving parsing, routing, formatting, and template-based outputs. Mid-tier models process 20-30% requiring standard reasoning. Frontier models receive only the 10-20% genuinely requiring complex reasoning or novel problem-solving [1]. The Plan-and-Execute pattern, where a capable model creates a strategy that cheaper models execute, can reduce costs by 90% compared to uniform frontier model deployment [1].</p>\n<h2>Why Agents Don&#39;t Require General Intelligence</h2>\n<p>The architectural insight driving this shift is straightforward: most agentic tasks are repetitive, narrowly scoped, and non-conversational [1]. Agents need to return JSON, trigger APIs, or output commands in formats that don&#39;t break execution chains. Large language models often introduce errors by getting creative with formatting. Smaller models fine-tuned to follow specific formats consistently actually reduce bugs and hallucinations [1].</p>\n<p>This represents a departure from the intuition that general capability necessarily produces better narrow performance. Research demonstrates that well-designed small language models can meet or exceed task performance previously attributed only to much larger models. Microsoft&#39;s Phi-2, at 2.7 billion parameters, achieves commonsense reasoning and code generation scores comparable to 30 billion parameter models while running 15 times faster [3]. Salesforce&#39;s xLAM-2-8B achieves state-of-the-art tool calling performance, surpassing GPT-4o and Claude 3.5 despite its modest size [4].</p>\n<p>The practical implication is that capability, not parameter count, is the binding constraint. Organizations can capture most of the value from AI systems while dramatically reducing operational costs by matching model capability to task requirements.</p>\n<h2>Provider-Agnostic Infrastructure as Strategic Enabler</h2>\n<p>Heterogeneous architectures require infrastructure that can deploy and route between diverse models without application rewrites. This is where provider-agnostic design becomes essential. Abstraction layers like LiteLLM provide unified APIs across more than 100 providers, enabling organizations to switch between self-hosted models, cloud APIs, and hybrid configurations based on cost, performance, or compliance requirements [5].</p>\n<p>The strategic benefits extend beyond operational flexibility. Organizations locked into single-vendor APIs lose the ability to capture the SLM cost advantage entirely. They cannot fine-tune models on proprietary data to create specialized tools that outperform general-purpose alternatives. They cannot run inference on-premises for regulatory compliance or data sovereignty requirements. And they cannot respond rapidly to pricing changes or capability improvements across the model ecosystem.</p>\n<p>Data sovereignty deserves particular attention. Small language models can run entirely within organizational boundaries, addressing regulated industry concerns about sending sensitive data to third-party APIs [1]. Healthcare organizations deploy private models for HIPAA-compliant clinical summarization. Financial services implement on-premise fraud detection meeting regulatory requirements while achieving real-time processing speeds [6]. These deployments would be impossible under vendor-locked architectures.</p>\n<h2>Building Internal Capability</h2>\n<p>The competitive advantage goes to organizations that can architect heterogeneous systems with internal fine-tuning capability, model routing intelligence, and provider-agnostic infrastructure. Fine-tuning small language models requires relatively modest resources: 1,000-5,000 high-quality examples typically suffice for task-specific adaptation [7]. Parameter-efficient techniques like LoRA and QLoRA reduce memory requirements by 4-8 times while achieving comparable quality to full fine-tuning [8].</p>\n<p>The operational agility this creates is substantial. Models fine-tuned overnight rather than over weeks enable rapid response to changing requirements [9]. A property management company achieved superior lead qualification results with a fine-tuned 3 billion parameter model compared to general-purpose large language models [10]. Specialized medical models outperform GPT-4 in narrow clinical domains [10]. These results demonstrate that domain-adapted small models frequently exceed general-purpose frontier models on specific tasks.</p>\n<p>Budget predictability shifts from pay-per-token, which is variable and vendor-controlled, to pay-per-compute, which is predictable and self-controlled. Enterprise Strategy Group research found that on-premise inference is 2.1-4.1 times more cost-effective than cloud LLM APIs at sustained utilization [11].</p>\n<h2>The Path Forward</h2>\n<p>2026 marks an inflection point where AI moves from proof-of-concept to production accountability. The defining question has shifted from demonstrating that AI can perform tasks to proving that AI systems can be relied upon when they matter. This accountability phase demands architectural choices that optimize for total cost of ownership, operational resilience, and strategic flexibility rather than peak capability on showcase demos.</p>\n<p>The combination of provider-agnostic infrastructure and heterogeneous model deployment addresses these requirements directly. Organizations that master these capabilities achieve superior AI economics, enhanced data control, and competitive differentiation through proprietary model development. The SLM transition represents more than technical optimization. It is a strategic opportunity to build AI capabilities that are genuinely owned rather than rented, deployable anywhere rather than cloud-dependent, and tailored to organizational needs rather than constrained by vendor offerings.</p>\n<p>The question for enterprise leadership is not whether to adopt these architectural patterns, but how quickly to capture the advantages they enable.</p>\n<hr>\n<h2>References</h2>\n<p>[1] P. Belcak, G. Heinrich, S. Diao, Y. Fu, X. Dong, S. Muralidharan, Y. C. Lin, and P. Molchanov, &quot;Small language models are the future of agentic AI,&quot; arXiv preprint arXiv:2506.02153v2, Sep. 2025.</p>\n<p>[2] Colliers, &quot;2025 data center marketplace: Balancing unprecedented opportunity with strategic risk,&quot; U.S. Research Report, 2025.</p>\n<p>[3] M. Javaheripi and S. Bubeck, &quot;Phi-2: The surprising power of small language models,&quot; Microsoft Research Blog, 2023.</p>\n<p>[4] J. Zhang et al., &quot;xLAM: A family of large action models to empower AI agent systems,&quot; arXiv preprint arXiv:2409.03215, 2024.</p>\n<p>[5] LiteLLM, &quot;Supported providers,&quot; LiteLLM Documentation. [Online]. Available: <a href=\"https://docs.litellm.ai/\">https://docs.litellm.ai/</a>. Accessed: Jan. 2026.</p>\n<p>[6] MarketsandMarkets, &quot;Small language models market report,&quot; 2025.</p>\n<p>[7] I. Agarwal, K. Killamsetty, L. Popa, and M. Danilevksy, &quot;DELIFT: Data efficient language model instruction fine tuning,&quot; arXiv preprint arXiv:2411.04425, 2024.</p>\n<p>[8] E. J. Hu, Y. Shen, P. Wallis, Z. Allen-Zhu, Y. Li, S. Wang, L. Wang, and W. Chen, &quot;LoRA: Low-rank adaptation of large language models,&quot; arXiv preprint arXiv:2106.09685, 2021.</p>\n<p>[9] S. Subramanian, V. Elango, and M. Gungor, &quot;Small language models (SLMs) can still pack a punch: A survey,&quot; arXiv preprint arXiv:2501.05465, 2025.</p>\n<p>[10] Digital Applied, &quot;Enterprise SLM case studies,&quot; 2025.</p>\n<p>[11] Enterprise Strategy Group, &quot;Understanding the total cost of inferencing large language models,&quot; Technical Report, Dell Technologies, Apr. 2024.</p>\n",
      "summary": "Why heterogeneous model deployment and provider-agnostic infrastructure should become the enterprise standard for AI systems.",
      "date_published": "2026-01-13T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "small-language-models",
        "model-routing",
        "provider-agnostic",
        "cost-efficiency"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/prose-prompts-to-controls",
      "url": "https://www.nateking.dev/blog/prose-prompts-to-controls",
      "title": "Prose: Prompts to Controls",
      "content_html": "<p>The earliest version of Prose followed a familiar pattern: a document on one side, a chat panel on the other. The idea was straightforward—where the industry had settled for writing assistants. Technically, it worked. But almost immediately something felt off.</p>\n<p>I wrote <em>more</em> text about my writing than actual writing. Long explanations. Clarifications. Follow-ups. Corrections. The chat interface demanded attention in the same medium as the work itself—language—and it became competitive instead of supportive. The assistance was verbose. The interaction was cumbersome. And worst of all, my focus drifted away from the document.</p>\n<p>I didn’t want to <em>talk</em> about my writing. I wanted to <em>improve</em> it.</p>\n<p>In the Fall of 2025, Anthropic released their <a href=\"https://claude.com/blog/skills\">Agent Skills framework</a>, which gave developers a standard way of instructing agents how to perform very specific, purpose-built tasks. I immediately began experimenting with agents tailored to specific stages of the writing process: brainstorming, drafting, revision, and argument strengthening. After a few months of tweaking instructions, I had a set of agents that were very good at providing writing assistance.</p>\n<p>My <a href=\"https://github.com/nathan-a-king/Prose/releases/tag/v1.2.0\">next release of Prose</a> implemented a multi-agent editorial pipeline system using the skills I had developed. Agents with narrowly defined skills collaborated through pipelines that orchestrated specific sequences of agents. Instead of conversation, Prose moved toward action. It was a major improvement—the system felt decisive instead of chatty. Prose stopped asking questions and started doing work.</p>\n<p>Unfortunately, this surfaced a new problem. The system lacked nuance. Some drafts arrived strong and needed only a light polish. Others were rough and needed structural help. But the agents didn’t know the difference. Every run invoked the same preset behavior, regardless of context or quality. The system was convenient, but it felt like a blunt tool. Premade agents and fixed pipelines couldn’t always distinguish how much help a piece of writing actually needed.</p>\n<p>I tried making the pipelines configurable. Sliders for &quot;revision intensity.&quot; Dropdowns for tone. But these controls were static—designed by me, in advance, for every possible document. They couldn&#39;t adapt to what the text actually needed. A memoir fragment and a technical specification both got the same generic options. The configuration UI became another thing to maintain, and it still missed the point.</p>\n<p>The missing piece wasn&#39;t intelligence—it was subtle <em>guidance</em>. I found no solution until I discovered a Microsoft repository. <a href=\"https://github.com/microsoft/Promptions\">Promptions</a> promised &quot;ephemeral UI for prompt refinement.&quot; The idea: simple. So simple I&#39;m disappointed I didn&#39;t think of it. In short, you define UI controls available for use, give the model instructions and document context, and it will create a unique refinement UI from the controls you defined.</p>\n<p>Let&#39;s look at how it works in Prose. Instead of hardcoded configuration options, I provide the selected agent&#39;s purpose along with the current document, and Promptions generates 2-4 contextually-relevant control options in real-time.</p>\n<h2>The Data Model</h2>\n<p>I built a JSON schema for three basic controls:</p>\n<pre><code class=\"language-json\">// Single-select radio button\n{\n  id: &quot;tone&quot;,\n  label: &quot;Writing Tone&quot;,\n  kind: &quot;single-select&quot;,\n  options: {\n    &quot;formal&quot;: &quot;Professional and formal&quot;,\n    &quot;casual&quot;: &quot;Conversational and friendly&quot;,\n    &quot;academic&quot;: &quot;Scholarly and precise&quot;\n  },\n  value: &quot;formal&quot;  // Currently selected\n},\n// Multi-select checkboxes\n{\n  id: &quot;focus-areas&quot;,\n  label: &quot;Areas to Revise&quot;,\n  kind: &quot;multi-select&quot;,\n  options: {\n    &quot;grammar&quot;: &quot;Grammar and mechanics&quot;,\n    &quot;clarity&quot;: &quot;Clarity and flow&quot;,\n    &quot;arguments&quot;: &quot;Strengthen arguments&quot;\n  },\n  value: [&quot;grammar&quot;, &quot;clarity&quot;]  // Multiple selections\n},\n// Binary select (toggle switch)\n{\n  id: &quot;preserve-voice&quot;,\n  label: &quot;Preserve Author Voice&quot;,\n  kind: &quot;binary-select&quot;,\n  options: {\n    &quot;enabled&quot;: &quot;Keep original writing style&quot;,\n    &quot;disabled&quot;: &quot;Allow style changes&quot;\n  },\n  value: &quot;enabled&quot;  // Either enabled or disabled\n}\n</code></pre>\n<h2>The Flow</h2>\n<p>The user selects an agent, which passes the <code>agentId</code> value, closes the agent panel, and opens the steering panel.</p>\n<pre><code class=\"language-tsx\">const handleAgentSelected = (agentId) =&gt; {\n  setSelectedAgent(agentId);\n  setAgentPanelOpen(false);\n  setSteeringPanelOpen(true); // Opens bottom panel\n};\n// ... additional handlers\n&lt;PromptionsControlPanel\n  agentId={selectedAgent}\n  documentState={documentState}\n  onChange={handlePromptionsChange} // Updates context when user changes values\n/&gt;;\n</code></pre>\n<p>Once the steering panel mounts, the service retrieves the available options for the agent and generates a unique prompt.</p>\n<pre><code class=\"language-js\">_buildSystemPrompt(agentInfo, documentState) {\n  const docSnippet = documentState.content?.slice(0, 500) || &quot;&quot;\n\n  return `You are a configuration generator for the &quot;${agentInfo.name}&quot; agent.\n\n## Agent Context\nName: ${agentInfo.name}\nDescription: ${agentInfo.description}\nCurrent Stage: ${documentState.stage || &quot;unknown&quot;}\n\n## Document Snippet\n${docSnippet}\n\n## Your Task\nGenerate 2-4 configuration controls that would be most useful for this agent.\n\n## Schema\n${basicOptionSet.getSchemaSpec()}\n\n## Example Controls for ${agentInfo.name}:\n${this._getExamplesForAgent(agentInfo.name)}\n\nReturn ONLY a JSON array of controls.`\n}\n</code></pre>\n<p>From there, the JSON response is parsed and a renderer creates the controls. In practice, this might produce a panel with two radio groups—one for revision depth (light touch, moderate, aggressive) and one for voice preservation—plus a multi-select for specific focus areas. The controls change each time based on the agent and document.</p>\n<h2>Steering the Agent</h2>\n<p>Once the user selects their options, the system injects a new set of instructions based on the selection into the prompt in a way that supersedes the default instructions.</p>\n<pre><code class=\"language-js\">async function executeDraftAgent(documentState, options = {}) {\n  const { promptions = null, ...otherOptions } = options;\n\n  let systemPrompt = `You are a writing assistant...\n  \n  ## Instructions\n  - Follow best practices\n  - Write clearly and concisely`;\n\n  // CRITICAL: Inject user preferences\n  if (promptions &amp;&amp; !promptions.isEmpty()) {\n    const formatted = promptions.prettyPrintAsConversation();\n\n    systemPrompt += `\\n\\n## CRITICAL: User-Configured Preferences\n\n${formatted.question}\n\n## User&#39;s Selected Configuration:\n${formatted.answer}\n\nIMPORTANT: You MUST follow these user preferences exactly. \nThey override all default behavior.`;\n  }\n\n  // Continue with agent execution...\n  const response = await openai.chat.completions.create({\n    model: &#39;gpt-4o&#39;,\n    messages: [\n      { role: &#39;system&#39;, content: systemPrompt },\n      { role: &#39;user&#39;, content: userPrompt },\n    ],\n  });\n}\n</code></pre>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-promptions-1.webp\" alt=\"Agent/Pipeline Selection\"><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-promptions-2.webp\" alt=\"Promptions Panel\"><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-promptions-3.webp\" alt=\"Agent Feedback\"></p>\n<h2>Beyond Writing</h2>\n<p>This pattern—generating contextual controls instead of demanding conversation—extends beyond writing tools. I haven&#39;t built these, but the same friction appears anywhere users need to guide AI systems with nuance.</p>\n<p>Consider a workspace that adapts to your day. Instead of manually configuring window layouts, notification settings, and focus modes each morning, the system reads your calendar, recent activity, and current projects to generate controls: session type (deep work, collaboration, administrative), distraction level (minimal, moderate, full access), layout preference (focused, reference, multi-task). The interface configures itself based on what you&#39;re actually trying to accomplish.</p>\n<p>Or data analysis. Rather than instructing &quot;create a visualization but make it suitable for a business presentation and emphasize the quarterly trends,&quot; the system generates controls for audience type, chart complexity, time granularity, and visual style—all based on the dataset it&#39;s analyzing and the context of your project.</p>\n<p>The same applies to code review tools that adjust feedback severity and focus areas based on the PR context, or research assistants that tune synthesis depth and citation density based on the document they&#39;re helping you build. Email drafting tools generate formality and length controls based on the recipient and thread history.</p>\n<p>In each case, the pattern is identical: the model inspects the context, understands what kind of guidance would be most useful, and generates appropriate controls. The user steers with a few clicks instead of paragraphs of instruction.</p>\n<p>What makes this approach powerful isn&#39;t just the convenience—it&#39;s that the model&#39;s understanding of context informs <em>what controls to offer</em>. The interface becomes dynamic and purpose-built for each interaction, rather than generic and conversational. Control surfaces emerge from the work itself.</p>\n<p>The chat interface was never the right metaphor for assistance. Assistance isn&#39;t conversation—it&#39;s collaboration. And collaboration needs precision, not prose.</p>\n",
      "summary": "Moving from verbose chat interfaces to contextual controls: how Promptions transformed Prose from conversational to collaborative by generating purpose-built UI from document context.",
      "date_published": "2025-12-27T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Writing",
        "Engineering",
        "prompt-engineering",
        "ui-generation",
        "context-aware-design",
        "agent-orchestration"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-promptions-1.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/finding-new-ways-to-fly-2025",
      "url": "https://www.nateking.dev/blog/finding-new-ways-to-fly-2025",
      "title": "Finding New Ways to Fly: 2025 in Review",
      "content_html": "<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/sedona-red-rocks.webp\" alt=\"Red rock formations rise against a clear sky in Sedona, Arizona\"></p>\n<blockquote>\n<p>&quot;Clarity is not guaranteed—but it sometimes arrives if you’re willing to wait.&quot;</p>\n</blockquote>\n<p>There is a fleeting moment just before the sun sets and the light fades, where the gentle glow grants unusual clarity, where shadows are long, offering contrast and refuge from continuous shape and form. You wait for the light to do something beautiful, and if you’re lucky, you are present to witness it. Sometimes you catch the drama—the town in shadow, the buttes blazing, the clouds building toward something. Sometimes you miss it. But you show up, and you look, and you try to see.</p>\n<p>When I was young, I wanted to be a pilot. My body wouldn&#39;t allow it—the medical gates proved insurmountable. So I took the written exam anyway, not because I thought I&#39;d ever fly, but because I needed to prove to <em>myself</em> that the barrier was circumstantial, not constitutional. The ecstasy and the anguish of that accomplishment were braided so tight I couldn’t separate them. I had demonstrated capability without permission.</p>\n<p>I didn’t become a pilot, but I found a different way to fly. This pattern didn’t end with aviation. It became how I learned to move through uncertainty.</p>\n<p>I tend to value consistency and seek to minimize risk. Not because I lack ambition, but because I understand how fragile stability can be—especially as life accumulates responsibility. I pay close attention to conditions before changing course, which is why the most consequential decision I made in 2025 didn’t look dramatic from the outside. I joined a small, growing generative AI team.</p>\n<p>Moving into generative AI was, for me, a calculated discomfort. The technology is young, the pace fast, and expectations high. There are more chances to fail than to succeed, but something surprising happened. For the first time in my career, my instincts about systems, risk, ethics, design, strategy, and long-term consequences weren’t adjacent to the work—they were the work.</p>\n<p>As I approach 40, I’m aware that careers tend to plateau, not accelerate. There’s a real chance that this role represents the peak of my professional arc. If that’s true, I consider myself extraordinarily fortunate. To spend this chapter of my career helping shape how intelligence is integrated—carefully, deliberately—into systems people rely on is not something I take lightly. If this is <em>my</em> summit, it’s one I’m proud to stand on.</p>\n<p>This year, I built nateking.dev—a React application that now hosts over 30 essays. It started as a simple website but quickly became an archive of thoughts. Writing remains the most reliable way I have to understand what I think. The site isn’t a brand exercise; it’s a commitment to clarity, permanence, and craft.</p>\n<p>GrindLab began with an irritation: coffee advice is often vague, subjective, and disconnected from real measurement. What emerged instead was an iOS application that uses computer vision to analyze coffee grind consistency—particle size distribution, uniformity, and brewing implications—directly from the iPhone’s camera.</p>\n<p>It’s currently in private beta, with a public release planned for early next year. GrindLab reflects a pattern I keep returning to: using technology to make knowledge visible, measurable, and actionable—offering insight into something without stripping away what makes it meaningful in the first place.</p>\n<p>After my father unexpectedly passed away, I needed a challenge—something absorbing enough to give grief a place to settle. That impulse resulted in Prose, a beautifully designed Electron-based Markdown editor that integrates AI writing agents—not as a chatbot, but as a pipeline: brainstorming, drafting, revision, and editing as distinct, intentional stages. Prose exists because I wanted a writing tool that respected process, not just output. In hindsight, that desire mirrors nearly everything else I worked on this year.</p>\n<h2>A Direction, Not a Prediction</h2>\n<p>I’ve learned to be cautious about forecasts. Technology moves too quickly, and people change too slowly. In 2026, I want to keep pushing AI beyond chat interfaces. The real leverage isn’t conversation—it’s orchestration. Agents, skills, and workflows allow systems to surface insight in context, at the moment it’s needed, shaped by what the user is already doing. I’m increasingly interested in interfaces that are generated as we work—quietly, helpfully—rather than demanded and defined upfront.</p>\n<p>If 2025 was about finding alignment, 2026 feels like the year to deepen it. I don’t know what the light will look like next year. I only know that I intend to keep showing up—watching closely—ready for the moment when clarity briefly arrives again.</p>\n",
      "summary": "A year spent choosing attention over certainty, process over output, and alignment over acceleration—professionally, creatively, and personally.",
      "date_published": "2025-12-20T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Personal",
        "Strategy",
        "year-in-review",
        "workflow-agents",
        "intentional-process"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/sedona-red-rocks.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/craftsmen-and-pragmatists",
      "url": "https://www.nateking.dev/blog/craftsmen-and-pragmatists",
      "title": "Craftsmen and Pragmatists",
      "content_html": "<p>Artificial intelligence has exposed a rift in the developer community. Some developers are energized by AI coding tools—they see them as accelerants, better levers for building what they want to build. Others feel something being lost, an erosion they can&#39;t quite name but recognize immediately.</p>\n<p>The divide runs deeper than capability or adoption speed—though those factors matter. It&#39;s about identity and what we find meaningful in our work.</p>\n<p>For some developers, writing code is intrinsically rewarding. The craft, the elegance, the satisfaction of a well-architected solution—these things matter independent of the outcome. Their identity is tied to being a coder. AI tools feel like they&#39;re eroding something meaningful, not just changing a workflow.</p>\n<p>For the second group, code was always instrumental. They wanted to build things, solve problems, and ship products. Code happened to be the most powerful lever available. AI just gives them a better lever.</p>\n<p>Call them craftsmen and pragmatists—two poles of a spectrum rather than two tribes. The names are reductive—useful for clarity, dangerous if taken literally—but capture real orientations. Most developers fall somewhere between these poles, and many shift depending on context.</p>\n<p>These aren&#39;t hypothetical positions. Real developers express these views in online discussions:</p>\n<p>One developer on HackerNews put it plainly: &quot;I will personally never use Copilot, or any other AI code generation tool, for the simple reason that I enjoy writing code.&quot;^1^ Another wrote: &quot;Reliance on Copilot subtly undermined my problem-solving abilities...immediate access to AI-generated solutions...dulling my problem-solving acumen over time.&quot;^2^ The concern isn&#39;t abstract—it&#39;s visceral. AI feels like it&#39;s eroding code as craft.</p>\n<p>On the other side, Armin Ronacher (creator of Flask) describes how AI tools give him &quot;30% more time in my day because the machine is doing the work,&quot; making all his programming skills &quot;more relevant than ever, just with a new kind of tool.&quot;^3^ Kent Beck captured the shift succinctly after 52 years of programming: &quot;90% of my skills just went to zero dollars and 10% of my skills just went up 1000x.&quot;^4^ For these developers, code was always instrumental—AI just gives them a better lever.</p>\n<p>The divide is real, not imagined.</p>\n<h2>Ends of the Spectrum</h2>\n<p>The craftsman writes code the way a carpenter planes wood—there&#39;s pleasure in the process itself. The pragmatist writes code the way an architect uses CAD software—necessary, powerful, but not the point. The building is the point. Neither position is wrong, but they predict different futures.</p>\n<p>The craftsman view says abstraction loses something important. Understanding, precision, maybe even a kind of discipline. There&#39;s wisdom in knowing how things work at a low level. There&#39;s danger in letting tools do work you don&#39;t fully comprehend.</p>\n<p>The pragmatist view says the goal was never the code itself. Code is frozen thought, a way to instruct machines. If AI handles more of that translation layer, we move up the stack—closer to the actual problem, further from the implementation details. Clinging to code-as-craft is like insisting on hand-calculating spreadsheets or typesetting by hand.</p>\n<p>The tension is real. But it&#39;s not new.</p>\n<h2>This Divide Predates AI</h2>\n<p>Similar philosophical tensions surfaced with each major abstraction layer in computing history. Assembly programmers looked at C and saw dangerous distance from the metal. When Java introduced garbage collection in the mid-1990s, C++ programmers raised concerns mirroring today&#39;s AI debates. Brian Kernighan explained why C&#39;s directness mattered: &quot;You will have a very good mental model of what&#39;s going to happen on the machine; you can predict reasonably well how quickly it&#39;s going to run, you understand what&#39;s going on.&quot;^5^ Bjarne Stroustrup dismissed garbage collection as &quot;a last choice and an imperfect way of handling resource management,&quot; preferring explicit control.^6^ The fear was identical: abstraction erodes understanding. Backend engineers looked at no-code tools with skepticism bordering on contempt.</p>\n<p>Each transition triggered the same debate: are we losing something essential, or freeing ourselves to work on harder problems? In each case, the abstraction layer succeeded commercially, and developers either adapted or specialized in maintaining legacy systems. The holdouts weren&#39;t wrong about what was lost—they were wrong about whether the loss mattered more than the gain.</p>\n<p>But AI may differ categorically. Previous abstractions—garbage collection, high-level languages—were deterministic and predictable. You could reason about what they would do. AI is probabilistic and opaque. The abstraction isn&#39;t just higher—it&#39;s fundamentally different in kind. Whether the historical pattern holds depends on whether that difference matters. The timeline has compressed, making the rift visible before we know the answer.</p>\n<h2>The Economic Dimension We Can&#39;t Ignore</h2>\n<p>Economics complicates this picture. If AI can write code, what happens to the market value of developers? Job security concerns are legitimate, and they likely compound—or even drive—the identity concerns described above.</p>\n<p>Is &quot;craftsman&quot; resistance to AI genuinely about craft, primarily about economics, or some mix of both? Stated reasons and actual motivations aren&#39;t always the same. And that&#39;s not cynical—economic anxiety and identity erosion can be genuine simultaneously. The anxiety is measurable: Stack Overflow&#39;s 2024 survey found that 30% of developers see AI as a threat to their jobs—rising to 42% among early-career developers.^7^ Meanwhile, companies laid off 666,000 tech workers between 2022 and 2024, driven by multiple factors including economic conditions and restructuring.^8^ The correlation with increased AI-related job postings amplifies the perception that AI threatens traditional roles, even if causation is complex. Evans Data found that 71% of developers believe they&#39;ll eventually be replaced by AI.^9^ While AI-specialized roles are booming (earning a 25% salary premium), traditional software roles have declined 20%+.^10^ The paradox: AI tool adoption grew from 70% (2023) to 84% (2025) while trust in AI output dropped from 40% to 29% and favorability fell from 72% to 60%.^11^</p>\n<p>The both/and position I describe below requires security. A senior developer with in-demand skills can afford to be flexible about tool usage in ways that a junior developer competing for entry-level positions cannot. Recognizing this privilege matters for an honest conversation about AI tools.</p>\n<p>The point isn&#39;t to reduce everything to economics. It&#39;s to acknowledge that identity and livelihood are intertwined, especially when your professional identity is tied to a skill that might be automatable.</p>\n<h2>The Both/And Developer</h2>\n<p>Here&#39;s what makes this interesting: the same developer can hold both positions depending on context.</p>\n<p>I&#39;m a both/and developer. I love hand-crafting a tricky algorithm on a personal project. I also happily let AI scaffold boilerplate at work. Neither choice defines me. What matters is developing the judgment to know which mode serves the moment.</p>\n<p>I treat AI as a junior collaborator. I still architect, review critically, and care about elegance. But I&#39;m not precious about who—or what—types the first draft. The value isn&#39;t in holding a consistent position—it&#39;s in knowing when to savor the process and when to optimize for the outcome.</p>\n<p>This isn&#39;t compromise—it&#39;s recognizing that the value of coding varies by context. Sometimes the act of writing code teaches me what I&#39;m actually trying to build. Other times I know exactly what I want, and code is just the translation layer between intent and execution. The tool I reach for should match the kind of thinking I need to do.</p>\n<h2>Time and Experience Shift the Balance</h2>\n<p>Early-career developers building fluency may need the reps that AI shortcuts bypass—though research on whether AI use impairs skill development is still emerging. The mental model matters. The muscle memory matters. Architecture students still learn to draw by hand even though they&#39;ll use CAD software in practice—the act of drawing teaches spatial thinking that informs everything they design later. The same may be true for writing code: the practice builds mental models that matter even when working at higher abstraction levels. Whether AI fundamentally changes this calculus for programming remains an open question.</p>\n<p>Senior developers with deep intuition might delegate more confidently—they know what good looks like. They&#39;ve debugged enough gnarly issues to spot the warning signs before things break. They can treat AI like a senior engineer treats a junior teammate—trusting them with well-scoped tasks while maintaining oversight.</p>\n<p>The right relationship with AI tools might depend on where you are in your own development—not just chronologically, but contextually. What are you trying to learn? What are you trying to build? Those answers shape the tool.</p>\n<h2>The Deeper Question</h2>\n<p>The rift isn&#39;t really about AI—it&#39;s about an older question AI has made urgent: <em>What are developers actually here to do?</em></p>\n<p>If the value is in typing code, AI is a threat. If the value is in problem decomposition, system design, and knowing what to build in the first place, AI might be an amplifier.</p>\n<p>The dichotomy may be too clean. For many developers, value lies in the iterative dialogue between implementation and understanding—where writing code reveals what they&#39;re actually trying to build. If that&#39;s true, AI&#39;s impact depends on whether it preserves or severs that feedback loop.</p>\n<p>The craftsman might say developer value lives in the nuanced judgment that comes from deep fluency with code. The pragmatist might say it lives in understanding the problem domain deeply enough to know what&#39;s worth building.</p>\n<p>Both are probably right, which means the answer isn&#39;t choosing sides but developing the judgment to know which mode serves the moment. The most effective developers might be those who can answer &quot;What am I here to do?&quot; contextually rather than ideologically.</p>\n<p>The divide will persist because it&#39;s rooted in something deeper than technology: what we find meaningful. But recognizing it as a divide about meaning rather than just a debate about tools might make the conversation more honest. And honesty is a better foundation than ideology for deciding when and how to use AI.</p>\n<p>AI didn&#39;t create this rift, but it&#39;s now impossible to ignore.</p>\n<hr>\n<h2>References</h2>\n<p>^1^ HackerNews user comment. &quot;Why Copilot Is Making Programmers Worse at Programming.&quot; August 30, 2024. <a href=\"https://news.ycombinator.com/item?id=41513767\">https://news.ycombinator.com/item?id=41513767</a>.</p>\n<p>^2^ Sankritayayana. &quot;Why I Stopped Using Copilot: A Developer&#39;s Reflection.&quot; <em>LinkedIn</em>, October 16, 2024. <a href=\"https://www.linkedin.com/pulse/why-i-stopped-using-copilot-developers-reflection-sankritayayana-bwkmc\">https://www.linkedin.com/pulse/why-i-stopped-using-copilot-developers-reflection-sankritayayana-bwkmc</a>.</p>\n<p>^3^ Ronacher, Armin. &quot;AI Changes Everything.&quot; June 4, 2025. <a href=\"https://lucumr.pocoo.org/2025/6/4/changes/\">https://lucumr.pocoo.org/2025/6/4/changes/</a>.</p>\n<p>^4^ Orosz, Gergely. &quot;TDD, AI agents and coding with Kent Beck.&quot; <em>The Pragmatic Engineer</em>, 2024. <a href=\"https://newsletter.pragmaticengineer.com/p/tdd-ai-agents-and-coding-with-kent\">https://newsletter.pragmaticengineer.com/p/tdd-ai-agents-and-coding-with-kent</a>.</p>\n<p>^5^ Kernighan, Brian. &quot;An Interview with Brian Kernighan.&quot; <em>Carnegie Mellon University</em>. Accessed December 13, 2025. <a href=\"https://www.cs.cmu.edu/~mihaib/kernighan-interview/\">https://www.cs.cmu.edu/~mihaib/kernighan-interview/</a>.</p>\n<p>^6^ Stroustrup, Bjarne. &quot;Bjarne Stroustrup&#39;s FAQ.&quot; Accessed December 13, 2025. <a href=\"https://www.stroustrup.com/bs_faq.html\">https://www.stroustrup.com/bs_faq.html</a>.</p>\n<p>^7^ Stack Overflow. &quot;2024 Stack Overflow Developer Survey.&quot; 2024. <a href=\"https://survey.stackoverflow.co/2024/ai\">https://survey.stackoverflow.co/2024/ai</a>.</p>\n<p>^8^ TrueUp. &quot;Tech Layoffs Tracker.&quot; Accessed December 13, 2025. <a href=\"https://www.trueup.io/layoffs\">https://www.trueup.io/layoffs</a>.</p>\n<p>^9^ Brainhub. &quot;Is There a Future for Software Engineers?&quot; Accessed December 13, 2025. <a href=\"https://brainhub.eu/library/software-developer-age-of-ai\">https://brainhub.eu/library/software-developer-age-of-ai</a>.</p>\n<p>^10^ Index.dev. &quot;8 AI Developer Salary Trends to Watch in 2025-26.&quot; Accessed December 13, 2025. <a href=\"https://www.index.dev/blog/ai-developer-salary-trends\">https://www.index.dev/blog/ai-developer-salary-trends</a>.</p>\n<p>^11^ Stack Overflow. &quot;Stack Overflow&#39;s 2025 Developer Survey.&quot; 2025. <a href=\"https://stackoverflow.co/company/press/archive/stack-overflow-2025-developer-survey/\">https://stackoverflow.co/company/press/archive/stack-overflow-2025-developer-survey/</a>.</p>\n",
      "summary": "AI tools have exposed a rift in the developer community. Some developers love to code. Others see code as a means to an end. The divide was always there, but AI made it impossible to ignore.",
      "date_published": "2025-12-13T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "developer-identity",
        "coding-craft",
        "ai-adoption",
        "skill-abstraction"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/when-your-strengths-betray-you",
      "url": "https://www.nateking.dev/blog/when-your-strengths-betray-you",
      "title": "When Your Strengths Betray You",
      "content_html": "<p>Ulysses S. Grant crushed the Confederacy in eleven months. Three years later, he lost everything to a con man named Ferdinand Ward. The same traits that made him unstoppable on the battlefield made him defenseless in the boardroom. This wasn&#39;t irony—it was inevitability.</p>\n<p>We assume greatness transfers—that excellence in one domain predicts success in another. Grant shatters that myth. His story reveals a harder truth about leadership: the cognitive traits that make you extraordinary in one environment can make you catastrophically vulnerable in another.</p>\n<h2>The Mind That Won the War</h2>\n<p>By May 1864, the Civil War had devoured three years and five Union generals. Robert E. Lee had psychologically defeated each, despite their superior numbers. Then came Grant.</p>\n<p>After the first day of brutal, inconclusive fighting in the Wilderness, Grant&#39;s officers expected him to retreat—as every Union commander before him had done. Instead, he issued the most revealing order of the war:</p>\n<blockquote>\n<p><em>&quot;Forward tomorrow.&quot;</em></p>\n</blockquote>\n<p>No caveats. No lamentation. No fresh intelligence required.</p>\n<p>Three cognitive traits explain Grant&#39;s relentless advance:</p>\n<p><strong>First, straightforward trust.</strong> He delegated freely and assumed good faith from subordinates. This created operational cohesion—officers rose to the responsibility he projected onto them.</p>\n<p><strong>Second, limited defensive imagination.</strong> Limited defensive imagination became Grant&#39;s armor against Lee&#39;s primary weapon. Previous Union commanders manufactured phantom armies—McClellan famously believed he faced 120,000 Confederates at Antietam when Lee commanded 43,000.¹ Lee exploited this, using deception and &quot;Quaker guns&quot; (logs painted to resemble artillery) to magnify his forces in enemy minds. Grant&#39;s cognitive style neutralized this advantage. He processed what he could see—troop movements, supply lines, terrain—without generating imagined reinforcements or hidden threats. Against a commander whose greatest victories came from opponents who defeated themselves through excessive caution, Grant&#39;s inability to manufacture fears was decisive.</p>\n<p><strong>Third, momentum before clarity.</strong> Grant&#39;s instinct was to act decisively, then correct as needed. When feedback is immediate, conditions are fluid, and delays are lethal, this works. The Civil War rewarded generals who could prune the decision tree to the trunk.</p>\n<p>Grant had something rarer than conventional genius: a mind that refused to complicate what reality complicated. In the chaos of 1864, that stillness looked like strategic brilliance.</p>\n<h2>The Same Mind in a Different World</h2>\n<p>In 1884, Grant reviewed the books of Grant &amp; Ward, a brokerage firm bearing his name and operating from a New York office. Ferdinand Ward promised investors 2-3% monthly returns—nearly 40% annually—claiming inside access to government contracts. The returns defied financial gravity. Grant had personally signed letters vouching for the firm&#39;s safety. When the Marine National Bank president inquired about the firm, Grant wrote back: &quot;I think the investments are safe.&quot;</p>\n<p>They weren&#39;t. Ward recycled the same securities as collateral, paying old investors with new deposits. He lived in a Manhattan brownstone and owned a 25-acre Connecticut estate—wealth impossible for a legitimate young banker. William Vanderbilt, when Grant approached him for an emergency loan, warned explicitly: &quot;What I&#39;ve heard about that firm would not justify me in lending it a dime.&quot; Vanderbilt gave Grant the money—$150,000, against every instinct—&quot;to you, to General Grant.&quot; The next day, Ward fled with the money. The firm&#39;s collapse revealed liabilities of $17 million against assets of $67,000.²</p>\n<p>The same three traits that won the war destroyed him in business:</p>\n<p>Straightforward trust became credulity. Grant assumed others were as honest as he was. He signed documents he didn&#39;t scrutinize. He believed assurances that were obviously too good to be true. In war, trust speeds execution. In finance, trust gets you skinned alive.</p>\n<p>Limited defensive imagination became blindness. Grant&#39;s battlefield cognition was calibrated for visible evidence—troop movements, supply lines, terrain features that reconnaissance could verify. Lee&#39;s psychological warfare failed against Grant precisely because Grant refused to process observable data into imagined threats. But this same cognitive architecture made him blind to Ward&#39;s scheme. Fraud produces no observable evidence until collapse. The falsified ledgers looked identical to real ones. The securities pledged multiple times left no visible trace. Ward&#39;s deception operated entirely in the domain Grant&#39;s mind was not built to scrutinize—the invisible architecture of financial trust. Grant&#39;s threat-detection system required observable triggers, and Ward provided none.</p>\n<p>Momentum before clarity became recklessness. War provides immediate feedback. Investment doesn&#39;t. The feedback loop is slow, risks are opaque, and bad actors hide easily. Grant applied a wartime strategy—move fast, correct later—to a domain where clarity must precede momentum.</p>\n<h2>The Pattern</h2>\n<p>The pattern repeats: In 2018, researchers studied 53,000 sales workers across 214 companies and found that the better someone was at selling, the worse they performed as a manager—a 7.5% decline in team performance for each increase in the new manager&#39;s previous sales ranking.³ The traits that made them exceptional individual performers—competitive intensity, focus on personal metrics, drive to close—actively interfered with management requirements: delegation, team development, strategic patience. This wasn&#39;t failure to adapt. It was structural incompatibility. The cognitive style optimized for one domain was architected in ways that prevented success in another.</p>\n<p>These failures reveal something deeper: cognitive architecture has limits. Cognitive psychology has studied skill transfer for over a century, since Thorndike&#39;s experiments in 1901.⁴ The consistent finding: near transfer (between similar domains) succeeds readily, but far transfer fails. A 2019 meta-analysis concluded that &quot;the lack of training-induced far transfer is an invariant of human cognition.&quot;⁵ Expertise research confirms the pattern—skills don&#39;t generalize even between subspecialties of the same field (cardiologists lose performance when handling neurology cases). The traits that make you merely competent can transfer. The cognitive architecture that makes you extraordinary is domain-specific by nature—optimized for one environment at the structural expense of others.</p>\n<p>Excellence is fundamentally non-transferable. The cognitive style that makes you unstoppable in chaos may be incompatible with stability. Not because you lack discipline or awareness, but because the adaptation that creates one kind of excellence structurally prevents another.</p>\n<p>Three implications follow, each harder to accept than the last.</p>\n<h2>Know Your Operating Environment</h2>\n<p>Grant succeeded because the Civil War environment matched his cognitive style:</p>\n<ul>\n<li>Responsibility was clear</li>\n<li>Motives were visible</li>\n<li>Outcomes were immediate</li>\n<li>The enemy was bounded by logistics</li>\n</ul>\n<p>He failed because Gilded Age finance had the opposite characteristics:</p>\n<ul>\n<li>Responsibility was diffused</li>\n<li>Motives were hidden</li>\n<li>Outcomes were delayed</li>\n<li>Bad actors exploited asymmetric information</li>\n</ul>\n<p>Before entering a new domain, ask: What cognitive traits does this environment reward? Do I have them?</p>\n<p>More importantly: What traits does this environment punish? Do I have those too?</p>\n<h2>Watch for Environmental Shifts</h2>\n<p>Self-knowledge won&#39;t save you. The dangerous moments come when familiar territory shifts beneath you—not when you enter new domains deliberately.</p>\n<p>Grant didn&#39;t wake up one day and decide to become an investor. The transition was gradual. A friend introduced him to Ward. The early returns looked good. Each step seemed reasonable.</p>\n<p>By the time he recognized the context had fundamentally changed, his cognitive style had already trapped him.</p>\n<p>Recognize these signals:</p>\n<ul>\n<li>Feedback loops lengthening (quick results now take months)</li>\n<li>Relationship dynamics shifting (internal trust failing externally)</li>\n<li>Decision complexity increasing (your simple frameworks no longer capture reality)</li>\n<li>Success metrics changing (what you optimized for no longer matters)</li>\n</ul>\n<h2>Why Compensating Structures Fail</h2>\n<p>The standard advice: if you can&#39;t change your cognitive style, build structures that compensate for it. Hire people who see what you don&#39;t. Create approval processes. Establish decision gates.</p>\n<p>This sounds reasonable. It&#39;s wrong—and Grant&#39;s life proves it.</p>\n<p>Vanderbilt explicitly warned Grant about Ward: &quot;What I&#39;ve heard about that firm would not justify me in lending it a dime.&quot; Grant borrowed the money anyway. Ward&#39;s lifestyle—a Manhattan brownstone and Connecticut estate at age 30—screamed fraud. Grant didn&#39;t investigate. The pattern repeated across decades. Grant&#39;s presidency was plagued by subordinate corruption—not because he participated, but because he couldn&#39;t imagine betrayal. He delegated freely, assumed good faith, and discovered corruption only after the fact.</p>\n<p>Grant&#39;s trust wasn&#39;t a behavior he could override with procedures. It was how his mind processed other people.</p>\n<p>Compensating structures work when they override behavior, not cognition. Checklists prevent pilots from skipping steps. But Grant&#39;s trust wasn&#39;t a skipped step—it was his cognitive architecture. Every compensating structure requires recognizing when to invoke it. Recognition requires the very capacity the structure is meant to replace.</p>\n<p>People &quot;generally do what we have learned to do and no more.&quot;⁶ When cognitive flexibility doesn&#39;t exist, you trust the verification, or trust the person you&#39;re checking, or sign the papers despite the process—because your mind can&#39;t operate any other way.</p>\n<p>The real compensating structure? Environmental selection. Don&#39;t put Grant in finance. Ever.</p>\n<p>If your cognitive style clashes with an environment, avoid it entirely. Not with guardrails—avoid it. Recognize the incompatibility and choose differently.</p>\n<p>Near the end of his life, dying of throat cancer and writing memoirs to provide for his family, Grant said something revealing:</p>\n<blockquote>\n<p><em>&quot;I never knew anything but two things: how to fight and how to write.&quot;</em></p>\n</blockquote>\n<p>He spoke without shame or self-pity—with the same quiet, unadorned honesty with which he had fought the war.</p>\n<p>That self-awareness redeems Grant: he understood he was built for one kind of truth, and only that kind. He understood the limits of his own excellence.</p>\n<p>Most leaders never develop that self-awareness. They assume their strengths are universal. They interpret past success as evidence of future capability. They mistake domain-specific excellence for general competence.</p>\n<p>Then the context shifts. And they discover, too late, that their greatest strengths are now fatal weaknesses.</p>\n<h2>What This Means for How We Think About Excellence</h2>\n<p>That self-awareness—knowing exactly what he could and couldn&#39;t do—challenges how we think about leadership, talent, and career progression.</p>\n<p>Most leadership development assumes you can adapt. Books tell you to &quot;learn to lead in any context.&quot; Executive programs promise to develop &quot;general leadership capabilities.&quot; Coaches help you &quot;overcome your weaknesses.&quot;</p>\n<p>That&#39;s wrong. Grant couldn&#39;t have learned to think like a financier, no matter how much coaching he received. His cognitive style wasn&#39;t a skill gap to close. It was his mind&#39;s architecture.</p>\n<p>This argument has obvious counterexamples. Military officers have led major corporations successfully—Daniel Akerson at GM, Frederick Smith at FedEx, Alex Gorsky at Johnson &amp; Johnson. Eisenhower led a university and a nation after commanding armies.</p>\n<p>But examine what these transitions share: corporate leadership environments are structurally similar to military command. Clear hierarchies. Defined objectives. Team coordination against visible competitors. Strategic planning with measurable feedback. Harvard Business Review research finds that military officers succeed as business leaders precisely because &quot;they define the mission but then give subordinates the flexibility to adjust to realities on the ground&quot;—skills that transfer cleanly.⁷</p>\n<p>Grant never led Grant &amp; Ward. He was a passive investor trusting a partner to manage operations. The cognitive task wasn&#39;t leadership—it was fraud detection in an environment designed to deceive. Responsibilities were diffused, motives were hidden, the adversary appeared as an ally, and feedback arrived only at collapse. Grant&#39;s cognitive strengths in leadership were irrelevant; his cognitive weaknesses in trust assessment were fatal.</p>\n<p>Career advice treats excellence as transferable. &quot;Take your skills to a new domain.&quot; &quot;Leverage your track record.&quot; &quot;Your success proves you can succeed anywhere.&quot; But Grant&#39;s success proved nothing about his ability to succeed in finance. His excellence was domain-specific, and the domain specificity wasn&#39;t incidental—it was structural.</p>\n<p>We assess talent as if cognitive traits are universal advantages. We promote the crisis manager because they&#39;re &quot;proven under pressure.&quot; We hire the detail-oriented analyst because they&#39;re &quot;rigorous thinkers.&quot; We assume strengths travel.</p>\n<p>They don&#39;t. Grant wasn&#39;t great because he saw more than other generals. He was great because he saw less—but the right less. This is the difference between traits that transfer and traits that don&#39;t.</p>\n<p>Competence traits are additive: general intelligence, conscientiousness, persistence. Research shows they correlate modestly with performance across domains—helpful everywhere, dominant nowhere. But extraordinary performance comes from domain-specific optimization. Studies find that specialized skills correlate with performance three times more strongly than general abilities (r = 0.68 vs. 0.22).⁸ That gap represents the architecture of excellence: cognitive systems tuned for one environment so precisely that they process its signals with preternatural clarity.</p>\n<p>The cost of that tuning is architectural. Grant&#39;s cognitive simplicity—his refusal to manufacture complex threat scenarios—was perfectly calibrated for the Civil War&#39;s grinding attrition, where imagination became liability and action beat analysis. That same simplicity couldn&#39;t detect fraud because detecting fraud requires the imaginative complexity he had structurally eliminated. His extraordinary trait wasn&#39;t a skill sitting alongside other skills. It was a processing architecture that precluded certain operations entirely.</p>\n<p>The practical implication? Some transitions are inadvisable, no matter how attractive they seem. Self-awareness and compensating structures help at the margins—but they won&#39;t save you from structural incompatibility. Some environments are incompatible with your cognitive style. Not difficult—incompatible.</p>\n<p>Your job? Recognize where you can&#39;t succeed and have the discipline to stay away. Not to learn to succeed anywhere.</p>\n<p>Grant never learned that lesson. He thought his character would transfer. He was wrong.</p>\n<p>You might be making the same mistake right now—eyeing a transition that looks like opportunity but is actually structural mismatch. The question isn&#39;t whether you&#39;re smart enough or disciplined enough to make it work.</p>\n<p>The question is whether your cognitive style can operate in that environment at all. And if the answer is no, no amount of effort will save you.</p>\n<hr>\n<h2>References</h2>\n<p>¹ American Battlefield Trust. &quot;George McClellan.&quot; Accessed November 25, 2025. <a href=\"https://www.battlefields.org/learn/biographies/george-mcclellan\">https://www.battlefields.org/learn/biographies/george-mcclellan</a>.</p>\n<p>² Ward, Geoffrey C. <em>A Disposition to Be Rich: How a Small-Town Pastor&#39;s Son Ruined an American President, Brought on a Wall Street Panic, and Made Himself the Best-Hated Man in the United States</em>. New York: Alfred A. Knopf, 2012; National Park Service. &quot;The Failure of Grant &amp; Ward: A Cautionary Tale.&quot; Ulysses S. Grant National Historic Site. Accessed November 25, 2025.</p>\n<p>³ Benson, Alan, Danielle Li, and Kelly Shue. &quot;Promotions and the Peter Principle.&quot; <em>Quarterly Journal of Economics</em> 134, no. 4 (2019): 2085–2134.</p>\n<p>⁴ Thorndike, Edward L., and Robert S. Woodworth. &quot;The Influence of Improvement in One Mental Function upon the Efficiency of Other Functions.&quot; <em>Psychological Review</em> 8, no. 3 (1901): 247–261.</p>\n<p>⁵ Sala, Giovanni, and Fernand Gobet. &quot;Near and Far Transfer in Cognitive Training: A Second-Order Meta-Analysis.&quot; <em>Collabra: Psychology</em> 5, no. 1 (2019): 1–22.</p>\n<p>⁶ Detterman, Douglas K. &quot;The Case for the Prosecution: Transfer as an Epiphenomenon.&quot; In <em>Transfer on Trial: Intelligence, Cognition, and Instruction</em>, edited by Douglas K. Detterman and Robert J. Sternberg, 1–24. Norwood, NJ: Ablex, 1993.</p>\n<p>⁷ Harvard Business Review. &quot;Which of These People Is Your Future CEO? The Different Ways Military Experience Prepares Managers for Leadership.&quot; Harvard Business Review, December 2010.</p>\n<p>⁸ Ericsson, K. Anders, and Neil Charness. &quot;Expert Performance: Its Structure and Acquisition.&quot; <em>American Psychologist</em> 49, no. 8 (1994): 725–747; Gobet, Fernand, and Herbert A. Simon. &quot;Templates in Chess Memory: A Mechanism for Recalling Several Boards.&quot; <em>Cognitive Psychology</em> 31, no. 1 (1996): 1–40.</p>\n",
      "summary": "Ulysses S. Grant crushed the Confederacy in eleven months. Three years later, he lost everything to a con man. The same traits that made him unstoppable in war made him defenseless in peace.",
      "date_published": "2025-12-09T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Strategy",
        "cognitive-architecture",
        "domain-expertise",
        "skill-transfer",
        "environmental-fit"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/scaling-silicon-revisited",
      "url": "https://www.nateking.dev/blog/scaling-silicon-revisited",
      "title": "Scaling Silicon Revisited",
      "content_html": "<p>In January 2023, I published <a href=\"#original-article\">an article</a> about the diverging strategies of Intel, AMD, and Apple in processor design. The core argument was simple: as transistors shrink and wafer costs soar, the economics of chip manufacturing would force fundamental changes in how we build silicon. AMD&#39;s chiplet approach offered cost advantages. Apple&#39;s monolithic system-on-a-chip strategy provided complete integration but faced scaling challenges. Intel was... well, Intel was figuring things out.</p>\n<p>Two years later, something fascinating has happened. Not only have the predictions held up remarkably well, but the industry appears to be converging on a single answer to the scaling problem—and it&#39;s not the answer I expected Apple to embrace.</p>\n<h2>The Original Argument</h2>\n<p>The 2023 piece hinged on basic semiconductor economics. Using Apple&#39;s M1 and M1 Max as examples, I calculated how die size affects both the number of chips per wafer and manufacturing yield. The math was straightforward but unforgiving:</p>\n<ul>\n<li><strong>M1</strong> (119 mm²): 478 dies per wafer, 88.9% yield = 425 good chips</li>\n<li><strong>M1 Max</strong> (440 mm²): 117 dies per wafer, 65.4% yield = 76 good chips</li>\n</ul>\n<p>That&#39;s a 5.6x difference in good chips from the same wafer, which directly translates to cost. I estimated the M1 Max at $223 in materials cost versus $40 for the base M1. The M1 Ultra, being two M1 Max dies on an interposer, would cost around $450 in silicon alone.</p>\n<p>The conclusion was that Apple would hit a ceiling. Going bigger than Ultra would price the Mac Pro out of its market. Mark Gurman had reported that a larger Mac Pro SoC would likely start at $10,000—economics that just didn&#39;t make sense.</p>\n<p>Meanwhile, AMD&#39;s chiplet approach was betting on a different future: smaller dies with better yields, mixed across different process nodes, assembled into configurations that could scale from 8 to 192 cores.</p>\n<h2>What Actually Happened</h2>\n<p>In June 2023, Apple released the Mac Pro with the M2 Ultra. The starting price? $6,999. It was, as expected, two M2 Max dies connected via UltraFusion technology on an interposer—the exact architecture I had analyzed.</p>\n<p>And then... nothing.</p>\n<p>As of late 2025, the Mac Pro is still running M2 Ultra. Meanwhile, the Mac Studio leapfrogged it with M3 Ultra in March 2025, and you can now get a Mac Studio with M4 Max that outperforms the Mac Pro in many workloads. The product that was supposed to be Apple&#39;s performance flagship has become a semi-abandoned curiosity, valuable mainly for its PCIe slots.</p>\n<p>The hypothetical Mac Pro with a chip larger than M2 Ultra never materialized. The $10,000+ starting price that would have required made it a non-starter. The physics won.</p>\n<p>This is where things get interesting. AMD didn&#39;t just succeed with chiplets—they essentially won the architectural debate.</p>\n<p>In 2024, AMD received the IEEE Corporate Innovation Award for pioneering chiplet design research. According to IEEE, AMD&#39;s chiplet architecture has &quot;nearly halved&quot; the manufacturing cost of modern processors while delivering greater memory bandwidth and compute capability than monolithic designs.</p>\n<p>But the real vindication goes beyond awards. Universal Chiplet Interconnect Express (UCIe)—an open standard for chiplet communication created in 2022—now has support from AMD, Intel, Nvidia, Arm, and dozens of other industry players. Even rivals are standardizing around the approach AMD pioneered.</p>\n<p>The cost advantages I described in 2023? They&#39;re now industry consensus. Chiplets enable:</p>\n<ul>\n<li><strong>Better yields</strong> by keeping dies small</li>\n<li><strong>Mixed process nodes</strong> (cutting-edge 3nm for CPUs, cheaper nodes for I/O)</li>\n<li><strong>Design reuse</strong> across product lines</li>\n<li><strong>Faster time-to-market</strong> for new configurations</li>\n</ul>\n<p>AMD&#39;s recent Financial Analyst Day in November 2025 showed a company that has never been in a stronger position. They&#39;re securing over $50 billion in design wins, expanding across cloud, edge, and embedded markets, all built on their chiplet foundation.</p>\n<h3>The Process Node Journey Played Out on Schedule</h3>\n<p>Remember that chart in my original article showing the slowing pace of transistor size reduction? TSMC&#39;s roadmap has followed it almost exactly.</p>\n<p>Apple&#39;s M3 launched on TSMC&#39;s first-generation 3nm process (N3B) in late 2023. But N3B was always known to be expensive—a stepping stone until the more economical N3E process matured. Several industry observers noted at the time that Apple was basically paying a premium to be first to 3nm, knowing they&#39;d need to transition quickly.</p>\n<p>Sure enough, the M4 arrived in May 2024 on N3E, TSMC&#39;s second-generation 3nm process. N3E offers better yields, lower costs, and actually enabled Apple to add more transistors (28 billion vs. M3&#39;s count) while improving both performance and efficiency. The quick M3-to-M4 transition wasn&#39;t a sign of trouble—it was a planned migration from an expensive process to a cost-optimized one.</p>\n<p>TSMC is now ramping N3P (third-generation 3nm) for even better performance and density. The progression is exactly what you&#39;d expect when the easy gains from shrinking are gone: iterate on the process, optimize yields, reduce costs. The &quot;fundamental rethinking&quot; I mentioned in 2023 is here.</p>\n<h2>The Plot Twist: Apple&#39;s Apparent Conversion</h2>\n<p>Here&#39;s where the story takes an unexpected turn.</p>\n<p>In July 2024, reports emerged that Apple is developing its M5 processor using TSMC&#39;s SoIC (System on Integrated Chip) technology—a fundamentally different approach than anything Apple has done before. Not just UltraFusion connecting two complete SoCs, but actual modular chiplets.</p>\n<p>The rumored design would split the processor into separate tiles:</p>\n<ul>\n<li>A large CPU tile with all the processor cores</li>\n<li>A large GPU tile with graphics cores</li>\n<li>Smaller controller tiles for memory, I/O, and other functions</li>\n</ul>\n<p>Each tile could be manufactured separately, potentially on different process nodes, then integrated using 3D stacking technology. It&#39;s a true chiplet architecture, more similar to AMD&#39;s approach than to Apple&#39;s traditional monolithic SoC design.</p>\n<p>What makes this particularly intriguing is the reported dual-use strategy. These M5 chips are allegedly being designed to serve both consumer Macs <em>and</em> Apple&#39;s AI cloud servers. Apple&#39;s current cloud infrastructure reportedly uses multiple M2 Ultra chips ganged together—a stopgap solution. A purpose-built chiplet design could serve both markets while sharing development costs.</p>\n<p>If this happens—and it&#39;s still rumored, not confirmed—it would represent Apple acknowledging the same fundamental limits I wrote about in 2023. You can only push monolithic dies so far before yield and cost become untenable. Beyond that point, you need modularity.</p>\n<h2>Why This Matters: The Physics of the Situation</h2>\n<p>The convergence toward chiplets isn&#39;t a fashion trend or a marketing decision. It&#39;s being driven by immutable physical and economic realities.</p>\n<p>Let me put some updated numbers to this. A 300mm wafer on TSMC&#39;s N3 process now costs roughly $18,000-$20,000 (up from ~$17,000 on N5). When you factor in yield losses from defect density, the math becomes even more punishing for large dies.</p>\n<p>A 600mm² die—roughly 36% larger than the M1 Max—would see yields drop to around 45% with standard defect densities. You&#39;d get maybe 75 dies per wafer, with only 34 of them good. At $18,000 per wafer, that&#39;s over $500 in materials cost per chip, before packaging, before testing, before any other manufacturing steps.</p>\n<p>Compare that to four 150mm² chiplets. Each has 90%+ yield. You can bin them separately, mixing and matching to create different SKUs. If one tile has a defect, you don&#39;t lose the entire chip. And you can manufacture your I/O tile on a cheaper, older process node since it doesn&#39;t need cutting-edge transistor density.</p>\n<p>This is why AMD can offer 192-core EPYC processors while Apple topped out at the M2 Ultra&#39;s 24 cores (actually 20 CPU cores + 4 efficiency cores). It&#39;s not that Apple&#39;s engineers lack ambition. It&#39;s that the economics of monolithic dies break down past a certain size.</p>\n<h2>The Broader Implications</h2>\n<p>What does it mean when the entire industry converges on the same architectural approach?</p>\n<p><strong>For Apple</strong>, it suggests a recognition that their vertical integration advantage has limits. They can design world-class SoCs for phones, tablets, and consumer laptops. But for high-performance computing—whether desktop workstations or cloud AI servers—the monolithic approach hits a wall. Chiplets let them stay competitive without building economically impossible chips.</p>\n<p><strong>For AMD</strong>, it&#39;s complete vindication. They made a bet in 2017 with first-gen Ryzen and EPYC that chiplets were the future. They were mocked by some for it. Now they&#39;ve won an IEEE award, they&#39;re setting industry standards, and their erstwhile competitors are following their lead.</p>\n<p><strong>For Intel</strong>... well, Intel is also going chiplets. Their Meteor Lake and upcoming processors use a disaggregated architecture with separate tiles. The difference is Intel was forced into it by manufacturing struggles, while AMD chose it strategically.</p>\n<p><strong>For the industry</strong>, it signals that Moore&#39;s Law scaling—in its traditional form of doubling transistors on a monolithic die every two years—is truly over. The new game is heterogeneous integration: different chiplets, different process nodes, different functions, all assembled into a coherent system.</p>\n<p>UCIe standardization is crucial here. When companies can use a common interconnect standard, it lowers barriers for smaller players and enables an ecosystem of specialized chiplet suppliers. We might see a future where you can buy CPU tiles from one vendor, GPU tiles from another, and assemble them into custom configurations. That&#39;s speculative, but the groundwork is being laid.</p>\n<h2>What I Didn&#39;t Anticipate</h2>\n<p>Let me be honest about what surprised me.</p>\n<p>I didn&#39;t expect Apple to move toward chiplets this quickly. I thought they&#39;d stretch the monolithic SoC approach further, perhaps with more sophisticated binning or with slight improvements in process technology buying them another generation or two. The rumored pivot to SoIC for M5 suggests the limits are harder than I realized, or that their ambitions for cloud AI are driving faster change.</p>\n<p>I also underestimated how quickly N3E would mature. The transition from N3B to N3E happened faster than I expected, and the yields on N3E appear to be excellent. TSMC has gotten remarkably good at process iteration.</p>\n<p>Finally, I didn&#39;t fully appreciate how important standardization would become. UCIe went from &quot;interesting consortium&quot; to &quot;critical industry infrastructure&quot; faster than I would have guessed. The fact that AMD, Intel, Nvidia, and Arm all got behind it suggests everyone sees the same future.</p>\n<h2>Looking Forward: What&#39;s Next?</h2>\n<p>If we accept that chiplets are the dominant paradigm for high-performance computing going forward, what comes next?</p>\n<p><strong>Process node progression will slow further</strong>. We&#39;re already seeing the gap between nodes expand from ~2 years to 3+ years. TSMC&#39;s roadmap shows N3, N2, and eventually A16 (their &quot;1.6nm-class&quot; node), but the cadence is slowing and the gains per node are diminishing. The focus shifts from &quot;smaller transistors&quot; to &quot;better integration.&quot;</p>\n<p><strong>3D stacking becomes critical</strong>. Technologies like SoIC, TSMC&#39;s CoWoS, and Intel&#39;s Foveros enable vertical integration—stacking chiplets on top of each other for better density and shorter interconnects. This is where much of the innovation will happen.</p>\n<p><strong>Software must evolve</strong>. Heterogeneous systems with variable latency between chiplets require different programming models. The &quot;everything is uniform memory&quot; abstraction that works on monolithic SoCs starts to break down. We&#39;ll need better compiler support, better scheduling, better awareness of the underlying topology.</p>\n<p><strong>The definition of &quot;SoC&quot; will blur</strong>. What do we call a system with six chiplets integrated on an interposer? Is it still a system-on-a-chip, or is it something else? The terminology will need to catch up with the reality.</p>\n<p>As for Apple specifically, I&#39;m curious whether they&#39;ll:</p>\n<ol>\n<li>Release M5 as a true chiplet design, or</li>\n<li>Keep M5 monolithic for consumer Macs but use chiplets for server variants, or</li>\n<li>Abandon the Mac Pro entirely and focus on Mac Studio as their high-end offering</li>\n</ol>\n<p>The Mac Pro in its current form feels like a product searching for a purpose. If Apple can&#39;t build a chip significantly more powerful than M2 Ultra without breaking the economics, what&#39;s the point? PCIe slots alone don&#39;t justify a $7,000 premium over Mac Studio for most users.</p>\n<h2>The Curiosity Factor</h2>\n<p>What fascinates me most about this whole journey isn&#39;t being right or wrong about specific predictions. It&#39;s watching how fundamental constraints—defect density, reticle limits, wafer costs—shape the decisions of companies worth trillions of dollars.</p>\n<p>Apple is one of the most powerful companies in history. They have effectively unlimited R&amp;D budget, close partnerships with TSMC, and the best chip designers in the world. And yet, they appear to be bending to the same physical and economic realities that forced AMD to rethink chip architecture back in 2017.</p>\n<p>That&#39;s not a failure on Apple&#39;s part. It&#39;s just physics.</p>\n<p>The same math that made chiplets attractive to AMD—better yields, lower cost per working chip, mix-and-match flexibility—applies to everyone. Intel discovered this. Apple appears to be discovering it now. Even Nvidia, with their massive monolithic GPU dies, is exploring chiplet-based designs for future products.</p>\n<p>The industry is converging not because everyone copied AMD, but because everyone is reading the same defect density charts and wafer cost sheets and coming to the same inevitable conclusion.</p>\n<h2>Closing Thoughts</h2>\n<p>When I wrote the original article in January 2023, I was trying to understand how three different companies would scale their architectures in the face of slowing process improvements. The question was: which strategy would win?</p>\n<p>Two years later, the answer appears to be: chiplets won. Not AMD&#39;s specific implementation necessarily, but the fundamental approach of modular, heterogeneous integration.</p>\n<p>Apple&#39;s rumored move to SoIC chiplets for M5 would be the clearest signal yet that the monolithic SoC era—at least for high-performance computing—is over. We&#39;re entering a new phase where the packaging and integration matter as much as the transistors themselves.</p>\n<p>Will I be writing another follow-up in 2027 saying I got this wrong again? Maybe! The fun part about analyzing technology is that the ground keeps shifting. But right now, the convergence toward chiplets looks like one of those rare moments where an entire industry shifts direction almost in unison, driven by math that doesn&#39;t care about brand loyalty or platform preferences.</p>\n<p>The chips have spoken, and they&#39;re saying: think smaller, integrate smarter, and embrace modularity. Even Apple is listening.</p>\n<hr>\n<h2>Original Article</h2>\n<p>Apple raised eyebrows in 2020 when the company announced plans to transition from Intel processors to chips designed in-house, marking the end of a 15-year partnership with Intel.^1^ For long-time followers of technology, it was reminiscent of Steve Jobs&#39; announcement at the 2005 Worldwide Developers Conference (WWDC), where he revealed Apple&#39;s plan to transition from PowerPC to the x86 architecture from Intel. Like the x86 transition fifteen years earlier, the rollout of Apple silicon went astonishingly smoothly despite the fundamental incompatibility between x86 and ARM instruction sets. For the first time in the recent past, Intel, Advanced Micro Devices (AMD), and Apple have taken divergent strategies in microarchitecture design. Each strategy has its own strengths and weaknesses, so it will be fascinating to see how well each approach scales to the future&#39;s cost, efficiency, and performance demands. AMD&#39;s chiplet design offers pricing advantages over Intel at the expense of bandwidth constraints and increased latency. Apple&#39;s system-on-a-chip (SoC) strategy requires larger dies but offers complete integration; however, we may be seeing the first cracks in Apple&#39;s ARM SoC strategy after scaling back plans for a high-end Mac Pro.^2^ According to Mark Gurman&#39;s reporting, a Mac Pro with an SoC larger than the M1 Ultra would likely have a starting cost of $10,000. To get a better perspective on the pricing challenges Apple may be facing when designing an SoC for the Mac Pro, let&#39;s explore how yield and cost change as die size increases.</p>\n<p>For example, we can calculate the number of rectangular dies per circular wafer for Apple&#39;s basic M1 SoC and the M1 Max using basic geometry:</p>\n<table>\n<thead>\n<tr>\n<th><strong>Specification</strong></th>\n<th><strong>M1</strong></th>\n<th><strong>M1 Max</strong></th>\n</tr>\n</thead>\n<tbody><tr>\n<td><strong>Die Dimensions</strong></td>\n<td>10.9 mm x 10.9 mm</td>\n<td>22 mm x 20 mm</td>\n</tr>\n<tr>\n<td><strong>Die Size</strong></td>\n<td>118.81 mm^2^</td>\n<td>440 mm^2^</td>\n</tr>\n<tr>\n<td><strong>Scribe Width</strong></td>\n<td>200 µm</td>\n<td>200 µm</td>\n</tr>\n<tr>\n<td><strong>Wafer Diameter</strong></td>\n<td>300 mm</td>\n<td>300 mm</td>\n</tr>\n<tr>\n<td><strong>Edge Loss</strong></td>\n<td>5.00mm</td>\n<td>5.00 mm</td>\n</tr>\n<tr>\n<td><strong>Die Per Wafer</strong></td>\n<td>478</td>\n<td>117</td>\n</tr>\n</tbody></table>\n<p>The smaller M1 dies give us four times the quantity per wafer over the M1 Max. This is one factor influencing the cost of physical materials, but things get really interesting once we begin calculating yields. The process of fabricating working silicon wafers is delicate and rife with the opportunity to produce imperfections. Defects can be caused by contamination, design margin, process variation, photolithography errors, and various other factors. Yield is a quantitative measure of the quality of the semiconductor process and is one of the most important factors in wafer cost. The measure used for defect density is the number of defects per square centimeter. Assuming a standard defect density of 0.1/cm^2^ using a variable defect size yield model for TSMC&#39;s N5 node, our two wafers possess vastly different yields:^3^</p>\n<p>This yield disparity increasing from 4x to just over 5.5x further inflates our larger die&#39;s already higher manufacturing cost. Just how much of a price difference? Extrapolating data from the Center for Security and Emerging Technology, we can estimate that a 300 mm wafer created using TSMC&#39;s N5 node costs just under $17,000.^4^</p>\n<p>Therefore, our M1 has a theoretical materials cost of $40 while our M1 Max has a cost of $223. Given that an M1 Ultra is two M1 Max dies connected via an interposer, the raw silicon cost of the Ultra is likely around $450. While all these figures are nothing more than conjecture, they clearly illustrate how quickly costs skyrocket and yields shrink as die size increases.</p>\n<p>Where does this leave the Mac Pro and the Apple silicon roadmap? Cost-effective silicon capable of performance significantly higher than the current top-tier SoC will likely require a more advanced lithography process to decrease transistor size. A likely candidate is TSMC&#39;s N3 node, which is where Apple is headed over the subsequent few product cycles. However, the rate at which manufacturers are able to decrease transistor size is rapidly slowing, as evidenced in the chart below, so a more fundamental rethinking of chip manufacturing is on the horizon.</p>\n<p>One certainty is that we are entering an exciting period of technological advancement that is beginning to disrupt the market. The ability of technology companies to adapt quickly is shifting from a mere competitive advantage to a requirement for survival. The future belongs to those who dare to think without boundaries.</p>\n<hr>\n<p><strong>References:</strong></p>\n<p>^1^ Gurman, M., &amp; King, I. (2020, June 22). <em>Apple-made computer chips coming to Mac, in split from Intel.</em> Bloomberg.com. Retrieved December 26, 2022, from <a href=\"https://www.bloomberg.com/news/articles/2020-06-22/apple-made-computer-chips-are-coming-to-macs-in-split-from-intel?sref=9hGJlFio\">https://www.bloomberg.com/news/articles/2020-06-22/apple-made-computer-chips-are-coming-to-macs-in-split-from-intel?sref=9hGJlFio</a></p>\n<p>^2^ Gurman, M. (2022, December 18). <em>Apple scales back high-end Mac Pro plans, weighs production move to Asia.</em> Bloomberg.com. Retrieved December 30, 2022, from <a href=\"https://www.bloomberg.com/news/newsletters/2022-12-18/when-will-apple-aapl-release-the-apple-silicon-mac-pro-with-m2-ultra-chip-lbthco9u\">https://www.bloomberg.com/news/newsletters/2022-12-18/when-will-apple-aapl-release-the-apple-silicon-mac-pro-with-m2-ultra-chip-lbthco9u</a></p>\n<p>^3^ Cutress, I. (2020, August 25). <em>&#39;Better yield on 5nm than 7nm&#39;: TSMC update on defect rates for N5.</em> AnandTech. <a href=\"https://www.anandtech.com/show/16028/better-yield-on-5nm-than-7nm-tsmc-update-on-defect-rates-for-n5\">https://www.anandtech.com/show/16028/better-yield-on-5nm-than-7nm-tsmc-update-on-defect-rates-for-n5</a></p>\n<p>^4^ Kahn, S., &amp; Mann, A. (2022, June 13). <em>AI chips: what they are and why They Matter.</em> Center for Security and Emerging Technology. Retrieved December 30, 2022, from <a href=\"https://cset.georgetown.edu/publication/ai-chips-what-they-are-and-why-they-matter\">https://cset.georgetown.edu/publication/ai-chips-what-they-are-and-why-they-matter</a></p>\n<p><strong>Further Reading:</strong></p>\n<p>Agrawal, V. D. (1994). A tale of two designs: the cheapest and the most economic. <em>Journal of Electronic Testing</em>, 5(2–3), 131–135. <a href=\"https://doi.org/10.1007/bf00972074\">https://doi.org/10.1007/bf00972074</a></p>\n",
      "summary": "Two years later, the chip industry converged on chiplets. Even Apple is embracing what physics demanded all along.",
      "date_published": "2025-11-30T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Engineering",
        "chiplet-architecture",
        "semiconductor-economics",
        "soc-design",
        "process-node-scaling"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/understanding-vector-stores",
      "url": "https://www.nateking.dev/blog/understanding-vector-stores",
      "title": "Understanding Vector Stores: How Semantic Search Actually Works",
      "content_html": "<p>Search for &quot;neural network&quot; in your company&#39;s documentation. Now search for &quot;deep learning model.&quot; Traditional keyword search treats these as completely different queries—but they mean essentially the same thing.</p>\n<p>This is the fundamental limitation of keyword matching: it doesn&#39;t understand <em>meaning</em>, only text.</p>\n<h2>The Problem with Keyword Search</h2>\n<p>Traditional search engines match strings. They&#39;re sophisticated about it—stemming, fuzzy matching, ranking algorithms—but fundamentally, they&#39;re looking for the words you typed.</p>\n<p>This breaks down constantly:</p>\n<ul>\n<li>Users search &quot;ML model&quot; but your docs say &quot;neural network&quot;</li>\n<li>Someone asks about &quot;fixing bugs&quot; but the relevant page discusses &quot;debugging techniques&quot;</li>\n<li>A query for &quot;database performance&quot; misses an article titled &quot;optimizing query speed&quot;</li>\n</ul>\n<p>The words are different. The meaning is the same. Keyword search can&#39;t bridge that gap. And this isn&#39;t a minor edge case. Modern applications handle millions of searches across documentation, support articles, product catalogs, and code repositories. Every semantic mismatch is a failed search, a frustrated user, a missed answer.</p>\n<p>How do we design a search that understands what someone <em>means</em>, not just what they typed?</p>\n<h2>The Solution: Meaning as Position in Space</h2>\n<p>Vector stores solve this by doing something that sounds almost magical: they represent meaning as position in space.</p>\n<p>That sounds abstract. Let&#39;s make it concrete.</p>\n<p>When you convert text into a vector (a list of numbers), you&#39;re not encoding words—you&#39;re encoding <em>meaning</em>. Similar concepts end up close together in this high-dimensional space. Dissimilar concepts land far apart.</p>\n<p>This isn&#39;t magic. Models train on massive amounts of text, learning that &quot;cat&quot; and &quot;kitten&quot; appear in similar contexts more often than &quot;cat&quot; and &quot;database.&quot; The model positions related concepts near each other.</p>\n<p>The breakthrough: once you have this representation, searching for meaning becomes geometry. You don&#39;t match keywords. You measure distance.</p>\n<h2>How It Actually Works</h2>\n<p>Here&#39;s the typical flow:</p>\n<ol>\n<li><strong>Convert documents to vectors</strong>: An embedding model transforms each document into a high-dimensional vector</li>\n<li><strong>Store vectors</strong>: The vectors go into a specialized database optimized for similarity search</li>\n<li><strong>Convert queries to vectors</strong>: When someone searches, the same model embeds their query</li>\n<li><strong>Find nearest neighbors</strong>: The database finds documents whose vectors sit closest to the query vector</li>\n<li><strong>Return results</strong>: The closest vectors represent the most semantically similar documents</li>\n</ol>\n<p>&quot;Closest&quot; means semantically similar, not keyword matches. Search for &quot;machine learning models&quot; and you&#39;ll find documents about &quot;neural networks&quot; and &quot;AI systems&quot;—even when those exact words don&#39;t appear in the query.</p>\n<h3>The Theory Behind It</h3>\n<p>This principle stems from the distributional hypothesis—the foundational insight that &quot;words that occur in the same contexts tend to have similar meanings&quot; (Harris, 1954). Or as linguist J.R. Firth memorably put it: &quot;You shall know a word by the company it keeps&quot; (1957).</p>\n<p>Modern neural networks operationalize this insight by learning vector representations where distributional similarity correlates with semantic similarity.</p>\n<p>For example, using typical embedding models, semantically related words cluster tightly: &quot;king&quot; and &quot;queen&quot; might score 0.99 cosine similarity (nearly identical direction in vector space), while &quot;king&quot; and &quot;stone&quot; score just 0.22, reflecting their semantic distance—one represents royalty, the other is an inanimate object.</p>\n<p>Technical terms show similar patterns: &quot;machine learning&quot; and &quot;neural networks&quot; achieve high similarity scores even when they don&#39;t share exact keywords, while &quot;machine learning&quot; and &quot;database&quot; sit farther apart.</p>\n<h3>See It In Action</h3>\n<p>Here&#39;s an interactive visualization. Hover over each dot to see a summary of the document. Search for different concepts and watch the system find semantically related documents:</p>\n<p>In this visualization:</p>\n<ul>\n<li>Each dot represents a document, positioned by its meaning</li>\n<li>Similar documents cluster naturally</li>\n<li>Your query becomes a vector (the terracotta dot)</li>\n<li>The system finds the closest documents</li>\n<li>Distance in this space corresponds to semantic similarity</li>\n</ul>\n<h2>The Trade-offs</h2>\n<p>Vector search isn&#39;t perfect. It trades precision for understanding:</p>\n<p>It&#39;s great at understanding conceptual similarity, synonyms, and intent. For example, searching &quot;ML model&quot; will surface documents about &quot;neural network&quot; or &quot;deep learning architecture&quot; with high similarity scores (typically 0.80+) even though these terms don&#39;t share keywords. The system understands these concepts are semantically related.</p>\n<p>Vector search is a poor fit for exact matches, numbers, codes, or technical identifiers. Searching for the year &quot;2024&quot; might return documents from &quot;2023&quot; or &quot;2025&quot; with similar vector similarity scores since the numerical difference doesn&#39;t map to semantic distance. Product codes like &quot;SKU-1847&quot; won&#39;t reliably match &quot;SKU-1848&quot; better than &quot;SKU-9302&quot;—the embedding sees these as arbitrary strings without understanding their sequential relationship.</p>\n<p>Most production systems combine both: vector search for semantics, keyword search for exact matches. You get the best of both. Research on hybrid search systems shows measurable improvements: hybrid approaches combining BM25 and semantic search can enhance result accuracy by 8-12% compared to keyword-only searches, and approximately 15% over pure semantic search for certain query types. The optimal balance depends on your use case—e-commerce searches might weight exact product codes higher, while documentation search might prioritize semantic understanding.</p>\n<h2>Why This Matters Now</h2>\n<p>Most modern AI applications now leverage vector stores:</p>\n<p><strong>RAG systems</strong>: ChatGPT plugins and enterprise implementations use vector databases like Pinecone to find relevant context that grounds LLM responses. Cisco&#39;s enterprise platform team uses Pinecone on Google Cloud to &quot;accurately and securely search through millions of documents to support multiple orgs across Cisco.&quot;</p>\n<p><strong>Semantic search</strong>: Beyond traditional tech companies, organizations across industries use vector search—from Notion automating document embeddings for semantic retrieval to enterprise handbook search implementations.</p>\n<p><strong>Recommendation engines</strong>: E-commerce platforms, streaming services, and content platforms use vector similarity for personalized recommendations, matching user preferences to products, media, or content.</p>\n<p><strong>Content moderation</strong>: Vector search helps detect conceptually similar harmful content even when wording differs.</p>\n<p><strong>Duplicate detection</strong>: Find semantically identical content across different phrasings.</p>\n<h2>What&#39;s Next</h2>\n<p>Vector stores are becoming infrastructure. Just as you don&#39;t think twice about using a relational database for structured data, teams now assume they&#39;ll have a vector database for semantic operations.</p>\n<p>The infrastructure is already here. The vector database market was valued at $1.97 billion in 2024 and is projected to reach $10.6 billion by 2032, growing at a 23.4% CAGR. In 2024 alone, major funding rounds included Pinecone&#39;s $100 million Series B (reaching $750 million valuation) and Weaviate&#39;s $50 million Series B.</p>\n<p>All three major cloud providers now offer vector database capabilities: AWS through OpenSearch Service and Aurora&#39;s vector extensions, Azure via Cosmos DB and Cognitive Search, and GCP through Vertex AI Matching Engine. Even traditional databases have added vector support—PostgreSQL&#39;s pgvector extension (version 0.8 released in 2024) is widely deployed, MySQL 9.0 introduced vector storage, and nearly every managed PostgreSQL service now includes vector capabilities by default.</p>\n<p>North America leads adoption with 39-41% of market share, while Asia-Pacific shows the fastest growth driven by China, India, and Japan&#39;s AI investments. The retail, IT, and healthcare sectors dominate usage, with vector search becoming standard infrastructure for semantic search, RAG systems, and recommendation engines.</p>\n<p>The question isn&#39;t whether to use vector stores—it&#39;s how to use them well. That means understanding your embedding model, choosing the right distance metric, handling multimodal data, and knowing when you need semantic search versus keyword matching.</p>\n<p>The hard problems are solved. Vector stores are production-ready and everywhere. What remains is judgment: knowing when meaning matters more than precision.</p>\n<hr>\n<p><em>Try the visualization above. Search for different concepts and watch semantic similarity create natural clusters. The system doesn&#39;t know what &quot;AI&quot; means in the human sense—it learned that documents about AI use similar language. But that&#39;s enough to build search that understands what you&#39;re looking for.</em></p>\n",
      "summary": "Vector stores power semantic search, RAG systems, and recommendation engines. Here's how they actually work—and why distance in space equals similarity in meaning.",
      "date_published": "2025-11-27T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "semantic-search",
        "embeddings",
        "vector-databases",
        "rag",
        "similarity-metrics"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/draw-the-line",
      "url": "https://www.nateking.dev/blog/draw-the-line",
      "title": "Draw the Line: Where AI Strategy Becomes Procurement",
      "content_html": "<p>Every enterprise today faces the same seductive proposition: vendor platforms promising instant AI transformation, complete with impressive demos and rapid deployment timelines. The appeal is obvious—why spend years building capabilities when you can purchase them today?</p>\n<p>But framing this as &quot;build versus buy&quot; misses the fundamental question: where does competitive advantage actually come from?</p>\n<h2>The Moat You Cannot Purchase</h2>\n<p>Sustainable differentiation in AI emerges from the intersection of proprietary data with custom algorithms—a moat that deepens over time and resists replication. When off-the-shelf solutions provide the same generic functionality to every competitor in your market, you&#39;ve acquired efficiency, not advantage.</p>\n<p>True transformation requires something vendors cannot sell: capabilities tailored precisely to your unique data characteristics, competitive position, and strategic priorities.</p>\n<p>This matters across every sector. The algorithm that optimizes supply chain decisions for a global manufacturer serves fundamentally different objectives than one designed for a regional distributor. The risk model for a community bank differs entirely from one built for a national lender. Generic models ignore these distinctions. Custom development exploits them.</p>\n<h2>The Pattern of Narrow Wins</h2>\n<p>Consider what happens when organizations chase quick wins through isolated vendor deployments. A chatbot here, a document processor there—each delivers modest efficiency gains while the fundamental business model remains unchanged.</p>\n<p>Organizations proliferate these narrow use cases because they&#39;re easy to procure and deploy. But material financial value doesn&#39;t come from automating individual tasks. It comes from transforming entire business domains through capabilities that competitors cannot replicate.</p>\n<p>That kind of transformation demands architectural control—which vendor platforms, by their nature, lack.</p>\n<h2>Reframing the Question</h2>\n<p>The right framing isn&#39;t &quot;build versus buy&quot; but rather &quot;where do we draw the line?&quot;</p>\n<p>Not all AI capabilities carry equal strategic weight. Routine functionality that provides no competitive edge—the commoditized features that every company needs but no company wins with—can be purchased for acceleration and cost efficiency. This frees internal teams to focus on proprietary systems that create unique value in areas where your organization can genuinely differentiate.</p>\n<blockquote>\n<p><em>&quot;The question isn&#39;t whether to build or buy. It&#39;s knowing which capabilities make you irreplaceable.&quot;</em></p>\n</blockquote>\n<h2>The Compounding Costs of Lock-In</h2>\n<p>The risks of getting this wrong compound quickly. Vendor lock-in poses the most significant long-term threat facing organizations adopting AI platforms today.</p>\n<p>Proprietary formats. Undisclosed model architectures. Platform-specific tooling. These dependencies often emerge only after substantial investment, when unforeseen constraints cannot be overcome due to lack of control. The rapidly evolving nature of AI technology amplifies this risk. Long-term winners haven&#39;t yet been established, and betting your strategic future on any single vendor&#39;s architecture will prove costly.</p>\n<p>Building with open standards and provider-agnostic architectures mitigates these risks while creating flexibility that compounds over time. Infrastructure-as-code, standardized APIs, cloud-agnostic monitoring—these approaches ensure portability across any platform.</p>\n<p>When the next generation of models emerges or a better infrastructure option appears, organizations with architectural control can adapt. Those locked into vendor ecosystems cannot.</p>\n<h2>The Transparency Problem</h2>\n<p>Compliance demands transparency that vendor materials often gloss over. Black-box models create regulatory nightmares. When regulators ask why a decision was made or a customer disputes a determination, &quot;the vendor&#39;s model said so&quot; won&#39;t suffice.</p>\n<p>Custom models built in-house provide full transparency into decision logic—increasingly mandatory, not merely convenient, across regulated industries. Financial services, healthcare, government contracting—anywhere accountability matters, opacity becomes liability.</p>\n<h2>The Hidden Economics</h2>\n<p>The economics differ from vendor proposals. Beyond obvious licensing fees, token-based pricing creates budget unpredictability that compounds at scale. Technical complexity accumulates as vendor-specific integrations multiply and architectural constraints emerge.</p>\n<p>Meanwhile, systems designed for your institutional requirements adapt as your needs evolve—generic vendor assumptions cannot. Architectural control means you&#39;re never trapped waiting for a vendor roadmap to align with your business priorities.</p>\n<p>The difference between adapting your systems immediately and filing feature requests that may never ship isn&#39;t just convenience. It&#39;s competitive velocity.</p>\n<h2>Building Capability, Not Just Systems</h2>\n<p>Perhaps the most overlooked strategic benefit of in-house development is institutional capability itself. Teams that develop deep expertise in your specific domain, data, and competitive context become increasingly valuable over time.</p>\n<p>Talented engineers seek meaningful work on difficult problems, not vendor integration projects. The retention power of challenging technical problems creates a compounding advantage that extends far beyond any single deployment.</p>\n<p>When your best people spend their time configuring vendor platforms instead of solving novel problems unique to your business, you&#39;re not just missing innovation. You&#39;re training them to leave.</p>\n<h2>Where to Draw the Line</h2>\n<p>The path forward lies in strategic hybrid approaches: build core differentiating capabilities in-house while purchasing commoditized services from vendors.</p>\n<p>Success depends on correctly identifying which capabilities fall into which category, then investing accordingly to create sustainable competitive advantage where it matters most.</p>\n<p><strong>Build in-house when:</strong></p>\n<ul>\n<li>The capability directly enables competitive differentiation</li>\n<li>Your data characteristics or business requirements are genuinely unique</li>\n<li>Transparency and control are regulatory requirements</li>\n<li>The problem space is evolving too quickly for vendor cycles</li>\n<li>Retaining top talent requires challenging technical work</li>\n</ul>\n<p><strong>Purchase from vendors when:</strong></p>\n<ul>\n<li>The functionality is commoditized across your industry</li>\n<li>Speed to deployment outweighs customization needs</li>\n<li>The vendor provides genuine expertise you lack internally</li>\n<li>The capability is peripheral to your core business model</li>\n<li>Open standards prevent meaningful lock-in</li>\n</ul>\n<p>The organizations that understand this distinction will separate themselves from those that mistake procurement for strategy. Not because they build everything, but because they know exactly what must be built—and why.</p>\n<h2>The Strategic Discipline</h2>\n<p>Drawing this line requires discipline. Vendor demos are compelling. Internal development timelines are long. Quarterly pressures push toward quick wins that show immediate ROI on slides.</p>\n<p>But competitive advantage in AI doesn&#39;t appear on quarter-over-quarter charts. It accumulates slowly through capabilities that competitors cannot purchase, built on data they cannot access, solving problems they haven&#39;t framed correctly.</p>\n<p>The question facing every organization isn&#39;t whether AI will transform their industry. It&#39;s whether they&#39;ll control that transformation or rent it from the same vendors serving their competitors.</p>\n<p>Your answer to that question is your strategy. Everything else is just procurement.</p>\n",
      "summary": "Sustainable differentiation in AI cannot be purchased. The question isn't build versus buy—it's knowing where competitive advantage actually comes from.",
      "date_published": "2025-11-23T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Strategy",
        "strategic-differentiation",
        "vendor-lock-in",
        "build-vs-buy",
        "competitive-advantage"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/two-minds-one-war",
      "url": "https://www.nateking.dev/blog/two-minds-one-war",
      "title": "Two Minds, One War",
      "content_html": "<p>What follows is, on its surface, a piece about two men from a long-ago war. But the more time I spent writing it, the more I realized I wasn’t writing about McClellan or Chamberlain at all. I was writing about us—about the fault lines in our own minds when responsibility, uncertainty, and fear collide.</p>\n<p>Some people freeze when the world stops making sense. Others improvise. Some cling to what they’ve built. Others risk what they love for what they value. This isn’t a historical problem. It’s a human one—a profound question of leadership when the future is uncertain.</p>\n<p>The Civil War just exposes it in a way that modern life politely hides. So yes, this begins with two hillsides—one in Virginia, one in Pennsylvania. But the question underneath it is one all of us face sooner or later:</p>\n<p><em>What do you do when the world demands an answer you don’t have?</em></p>\n<hr>\n<p>When you are responsible for something you love, and the world refuses to be certain, your mind fractures in one of two directions.</p>\n<p>Some minds narrow. They seek control, drawing tighter boundaries around what can be known, demanding precision before action, treating uncertainty as an enemy to be eliminated. The more chaos presses in, the more these minds withdraw into caution, building fortifications of information-gathering and contingency planning that eventually become prisons.</p>\n<p>Other minds expand. They seek meaning instead of certainty, finding coherence not in perfect information but in clear purpose. Ambiguity becomes a medium to navigate rather than a threat to eliminate. These minds step forward not because the path is clear but because the need is clear.</p>\n<p>Both responses are intelligent. Both are human. Neither is cowardice or courage in simple form.</p>\n<p>And most of us carry both within us, oscillating between them depending on the moment, the pressure, the stakes. The question isn&#39;t which tendency you possess but which one possesses you when everything depends on what you do next.</p>\n<p>In the summer of 1862, these two forms of intelligence stood on two different battlefields, embodied by two different men.</p>\n<p>George McClellan gazed across the Virginia fields and saw a shadow army, twice its actual size. A year later, Joshua Lawrence Chamberlain would stand on a rocky hillside in Pennsylvania and see only the one truth before him: the line must hold.</p>\n<p>One man narrowed until he could not move. The other widened until movement became inevitable.</p>\n<p>The question isn&#39;t what separated them. The question is: which one are you when the world demands an answer you don&#39;t have?</p>\n<h2>The Mind That Contracted</h2>\n<p>Allan Pinkerton&#39;s intelligence reports arrived on George McClellan&#39;s desk with the authority of fact: Confederate forces numbering 120,000 where there were actually 60,000. Enemy divisions massing where only brigades existed. Batteries positioned where fields stood empty.</p>\n<p>A different general might have questioned these numbers, cross-referenced them, discounted them as the fog of war. But McClellan&#39;s mind, engineered for precision, seized on them. Not despite their exaggeration but because of it.</p>\n<p>This is the psychological detail that matters: He needed the numbers to be true.</p>\n<p>Here is where the progression begins—where competence starts its slow collapse into paralysis. And the mechanism of that collapse reveals something about how certain minds respond when reality won&#39;t hold still.</p>\n<p>McClellan had been the most promising man of his generation—West Point graduate, engineer, railroad executive, the general who rebuilt the shattered Union army after Bull Run into a disciplined, coherent fighting force. The Army of the Potomac loved him. He loved them back. He saw in his immaculate regiments the image of what a republic could be at war: disciplined, elegant, restrained.</p>\n<p>He approached war the way an engineer approaches a bridge: every variable calculated, every stress anticipated, every risk accounted for before the first stone is laid. He wanted complete information, firm footing, an assurance that when he moved, he would move correctly.</p>\n<p>But the battlefield refused to cooperate. And Pinkerton&#39;s inflated estimates offered something McClellan&#39;s mind desperately needed: a reason to wait.</p>\n<p>If the enemy was overwhelming, then caution was wisdom. If the threat was massive, then hesitation was prudence. If the danger was real, then waiting for reinforcements was strategy rather than paralysis. Pinkerton&#39;s inflated estimates didn&#39;t trap McClellan—they liberated him from the burden of action.</p>\n<p>His imagination, sharpened by its own analytic precision, began to populate the landscape with dangers that justified inaction. He saw enemy brigades in shadows, divisions in tree lines, entire corps waiting in the folds of ground beyond his vision. The more uncertain the battlefield became, the more his mind constructed a reality that made certainty impossible.</p>\n<p>This is how protective love becomes paralysis: You cherish something so deeply that losing it seems worse than failing to use it. McClellan saw the Army of the Potomac not merely as an instrument but as an ideal—a living embodiment of the nation&#39;s virtue. To risk it felt like profaning something sacred.</p>\n<p>The newspapers had crowned him the &quot;Young Napoleon&quot; before he had won a single major battle. Washington society treated him as the savior of the Union. Politicians whispered about him as a future president. With every passing month, the pedestal rose higher. Action meant jeopardizing the myth; inaction preserved it.</p>\n<p>And so he hesitated. He entrenched. He asked for reinforcements. He waited for conditions that war, by its nature, never provides.</p>\n<p>The tragedy was not cowardice but excessive fidelity to the world he built in his head. McClellan needed a war that unfolded according to principle—predictable, rational, symmetrical. The actual war, with its improvised assaults and shattering losses, violated that internal order.</p>\n<p>By the Peninsula Campaign of 1862, the pattern was complete. McClellan commanded over 100,000 men—the largest army the United States had ever assembled—facing fewer than 60,000 Confederates. He had overwhelming numerical superiority, supply lines, artillery, everything an engineer could want. Except certainty.</p>\n<p>The Peninsula smelled of mud and magnolia the morning he climbed a small rise and lifted his field glass toward the Confederate lines. The air was unnervingly still, the kind of stillness that belongs only to battlefields and sickrooms—places where dread hides behind order. Through the haze, McClellan saw what he always saw: not the army that was there, but the army that might be. Reinforcements that might arrive. Batteries that might materialize. A threat half glimpsed but fully believed.</p>\n<p>In the summer heat of 1862, this vision held him in place. Phantom brigades. Exaggerated strength. A Confederate host twice its actual size. The Union&#39;s great organizer had again become its most immobilized commander—not trapped by the ground in front of him, but by the possibilities his own mind conjured.</p>\n<p>His intelligence was real. His imagination was powerful. His instincts were humane. But under pressure, these virtues combined into something brittle. The mind that could shape an army into coherence could not shape itself to the chaos of war.</p>\n<p>This is the first fracture: when a mind narrows under pressure, seeking impossible precision, building internal structures so rigid they cannot bend to reality&#39;s roughness.</p>\n<p>Most of us have stood where McClellan stood—not on a battlefield, but in a moment where we loved something too much to risk it, needed more information that would never come, built elaborate justifications for inaction, and called our paralysis wisdom.</p>\n<p>The question is whether we stayed there.</p>\n<h2>The Mind That Expanded</h2>\n<p>Joshua Lawrence Chamberlain was a professor of rhetoric, theology, and languages before the war found him. He spent his days with Homer and Cicero, with philosophical treatises and sermons, with ideas that live in the spaces where clarity gives way to interpretation.</p>\n<p>Classical rhetoric taught him that persuasion doesn&#39;t depend on certainty—it depends on finding the available means in a given situation. Theology trained him to seek meaning in suffering without demanding explanations. Languages showed him that truth can be carried across gaps, that translation is always imperfect but still possible, that coherence doesn&#39;t require identity.</p>\n<p>War, for Chamberlain, did not contradict this intellectual life. It amplified it.</p>\n<p>Where McClellan demanded precision before he acted, Chamberlain understood that meaning often emerges from the act itself. His letters home reveal this: he rarely speaks of tactical neatness or perfect plans. Instead, he writes about duty, character, destiny—words that gave him a broader frame for interpreting chaos.</p>\n<p>&quot;I fear only not fulfilling the duty which lies clear before me,&quot; he wrote. Not the fear of being wrong, not the fear of death, but the fear of failing an obligation.</p>\n<p>This distinction matters. It reveals the underlying architecture of his thought: Purpose came first. Clarity followed.</p>\n<p>And when the war tested him—as it did relentlessly—his mind expanded rather than contracted.</p>\n<p>At Petersburg, shot through the hip and believed dead by many, he pulled himself upright long enough to issue a final order, more concerned with the continuity of command than with the extraordinary pain that nearly ended him.</p>\n<p>But it was Little Round Top that offered the clearest window into how his mind processed uncertainty.</p>\n<p>July 2, 1863. Late afternoon. Chamberlain commanded the 20th Maine Infantry Regiment on the extreme left flank of the Union line at Gettysburg. His orders from Colonel Strong Vincent were simple and absolute: &quot;Hold this ground at all costs.&quot;</p>\n<p>The tactical situation was chaos. Vincent had been mortally wounded. No one seemed to know where the rest of the brigade was. The maps were worse than useless—the terrain was a tangle of boulders, slopes, and ravines that bore no relation to the neat lines drawn in headquarters tents. Ammunition was running low.</p>\n<p>And the 15th Alabama Infantry, battle-hardened and determined, was gathering downslope for another assault.</p>\n<p>Watch what Chamberlain did. Not what he achieved—we know he succeeded—but how his mind moved through the problem.</p>\n<p>First: He accepted the parameters. The line must hold. This was not negotiable. The entire Union position at Gettysburg pivoted on this rocky slope. If his regiment broke, the flank collapsed. If the flank collapsed, the army was flanked. If the army was flanked, the battle was lost.</p>\n<p>Second: He surveyed what he had. Fewer than 200 men still able to fight, down from 400 that morning. No ammunition for sustained defensive fire. Terrain that favored attackers coming uphill because the boulders gave them cover. No reinforcements visible or promised.</p>\n<p>Third—and this is where his mind worked differently than McClellan&#39;s—he didn&#39;t calculate probabilities or wait for better information. He looked for what the moment demanded.</p>\n<p>If the line must hold and we cannot hold it by firepower, then we must hold it by movement. If we cannot stop them by shooting, we must stop them by shock. If we are too weak to defend, we must attack.</p>\n<p>The logic was philosophical, not mathematical. It was an argument about necessity, not probability. And it emerged not from certainty but from accepting that certainty would never arrive.</p>\n<p>&quot;Fix bayonets,&quot; he ordered.</p>\n<p>Then, in a decision that still astonishes military historians: &quot;Charge.&quot;</p>\n<p>The 20th Maine swept down the slope like a hinge, pivoting on the right wing, the left wing swinging forward in a great arc. The 15th Alabama, preparing for another uphill assault, instead faced a screaming mass of Union soldiers coming at them with steel. They broke.</p>\n<p>Chamberlain didn&#39;t know it would work. He couldn&#39;t have known. But he understood that action, when rooted in clear purpose, creates its own form of certainty.</p>\n<p>This is the second fracture: when a mind expands under pressure, it seeks coherence rather than certainty, finds direction not from perfect information but from clear obligation.</p>\n<p>Chamberlain loved his men as deeply as McClellan loved his. He said so plainly, and often. But his love moved differently. Where McClellan tried to protect his army from the war, Chamberlain tried to protect the purpose of the war through his army.</p>\n<p>The regiment was not an artifact to be preserved but a community entrusted with a task. Sacrifice, when required, did not diminish that love—it honored it. Purpose clarified fear instead of compounding it.</p>\n<p>Most of us have faced smaller versions of this moment: when we had to act despite incomplete information, when we had to risk what we cherished for what we valued, when we found clarity not by waiting but by moving.</p>\n<p>The question is whether we fixed bayonets or waited for reinforcements that would never come.</p>\n<h2>Two Directions, One Choice</h2>\n<p>Both men loved their armies. Both felt the crushing weight of responsibility. Both understood, in some profound sense, that leadership required more than issuing orders—it required deserving to issue them.</p>\n<p>Yet when they stood at the intersection where love and duty collide, they fractured in opposite directions.</p>\n<p>The paradox they faced—the paradox we all face when responsible for something precious in an uncertain world—is this: You must care fiercely and act decisively. You must love something enough to risk it. You must carry duty and devotion as equal weights without letting either destroy the other.</p>\n<p>Love alone produces guardians who cannot act. Duty alone produces executioners who cannot care. The terrible requirement is both at once.</p>\n<p>Robert E. Lee named this truth when he wrote: &quot;To be a good soldier, one must love the army, and a good commander must be willing to order the death of the thing they love.&quot;</p>\n<p>McClellan could feel only the first half—the love, the devotion, the protective instinct. Chamberlain somehow bore the weight of both.</p>\n<p>This is the heart of their divergence:</p>\n<p>McClellan tried to protect his army from the war. Chamberlain tried to protect the purpose of the war through his army.</p>\n<p>One placed the emphasis on preservation; the other on fulfillment. One feared losing the thing he loved; the other feared failing the thing he loved. And in this inversion—delicate, moral, devastating—lies the difference between a mind that contracts and a mind that expands.</p>\n<p>Temperament plays its role. Under uncertainty, McClellan&#39;s mind tightened, drawing boundaries around what felt controllable. Chamberlain&#39;s mind widened, searching for coherence rather than certainty. Each man remained faithful to the structure of his own intelligence—one rigid, one elastic.</p>\n<p>But the deeper truth is this: They weren&#39;t different kinds of people. They were different responses to the same unbearable truth—that you can be responsible for something precious in a world that refuses to be safe.</p>\n<p>We carry both within us.</p>\n<p>In McClellan we recognize the part of ourselves that wants more information, more time, more assurances—an internal bureaucracy of fear that believes risk can be eliminated by thinking harder. He embodies the wish for a life in which decisive moments arrive only when we feel ready, and where readiness is something we can earn by preparation alone. There is a kind of tenderness in his caution, even a nobility. But it is a nobility that cannot act until the world becomes safer than it ever will be.</p>\n<p>In Chamberlain we see the part that steps forward not because the situation is clear but because the need is clear. The part that knows purpose can illuminate a path through fog, even when the horizon is hidden. He reminds us that action, when rooted in meaning, can create its own form of understanding, and that responsibility can expand the mind rather than constrict it.</p>\n<p>Most of us oscillate between them depending on the moment, the pressure, the stakes.</p>\n<p>The question isn&#39;t which tendency you possess. The question is which one possesses you when everything depends on what you do next.</p>\n<h2>The Hillsides</h2>\n<p>If you strip away the centuries of analysis, the battlefield markers, the biographies, the monuments, what remains are two men standing on two hillsides, each confronted with a moment he did not ask for.</p>\n<p>McClellan on the Peninsula, scanning the rolling fields of Virginia, seeing dangers layered behind every treeline. The army he built stood ready behind him, immaculate and immense, waiting for a command that never quite arrived. He loved that army—loved it so much that the thought of losing it felt like losing the war itself. And so he hesitated, believing that the world would one day become clear enough for him to act without violating the thing he cherished.</p>\n<p>Chamberlain at Gettysburg, the rocky slope beneath his feet, the regiment beside him battered and thinning. The horizon was no clearer for him than it had been for McClellan; the stakes were no smaller. Yet he moved. He acted not because he felt ready, but because readiness had ceased to matter. The moment demanded something, and meaning gathered around that demand like a light.</p>\n<p>One man waited for certainty. The other accepted that certainty would never come.</p>\n<p>Both loved their armies. Only one understood that love does not spare you from sacrifice; it only tells you what is worth sacrificing for.</p>\n<p>Their war was literal; ours may be psychological, professional, moral, or private. But the hinge remains the same: the collision between love and duty, between fear and necessity, between the desire for control and the need for meaning.</p>\n<p>We face this choice when we must act despite incomplete information, when we must risk what we cherish for what we value, when fear feels like wisdom but might be paralysis, when the world demands an answer we don&#39;t have.</p>\n<p>McClellan and Chamberlain don&#39;t teach us what to choose. They teach us that there is a choice, that it lives inside us, and that pressure doesn&#39;t create our response—it exposes which response we&#39;ve been building all along.</p>\n<p>Their hillsides are long silent now. But the question that confronted them—what to do when love and duty collide, when the world won&#39;t hold still, when you must decide without knowing—has never stopped asking itself. The answer isn&#39;t which man you admire. The answer is which man you become when the moment demands more than you believe you can give.</p>\n<p>I didn’t write this to hand out moral scores to two men who’ve been dead for a century and a half. I wrote it because I’ve watched smart people — myself included — become McClellan at exactly the moment a situation needed a Chamberlain. Strategy, leadership, product decisions, even personal ones: they all eventually arrive at the same hillside, with the same unfair question. We don’t get to choose whether the world is uncertain. We only get to choose which part of ourselves answers when it is.</p>\n",
      "summary": "What do you do when the world demands an answer you don't have? A study of two Civil War leaders reveals the profound difference between minds that contract under pressure and minds that expand—and what that reveals about leadership, responsibility, and how we face uncertainty.",
      "date_published": "2025-11-17T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Strategy",
        "leadership-psychology",
        "uncertainty-management",
        "decision-making",
        "cognitive-frameworks"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/mcp-isnt-dead",
      "url": "https://www.nateking.dev/blog/mcp-isnt-dead",
      "title": "No, MCP Isn't Dead",
      "content_html": "<p>Every few months, the AI world goes through a familiar ritual: a new idea appears, Twitter catches fire, and someone declares that something foundational has become obsolete. Anthropic’s new code-execution pattern is the latest spark, and the proclamation arrived right on schedule:</p>\n<blockquote>\n<p><em>“MCP is dead.”</em></p>\n</blockquote>\n<p>It’s not. In fact, the opposite is true. The pattern everyone is excited about only works because Model Context Protocol exists—and uses it more deeply than any agent system we&#39;ve seen so far. The confusion comes from misunderstanding what MCP actually is.</p>\n<p>When you read Anthropic&#39;s examples, they&#39;re disarmingly simple. The model writes TypeScript. It imports modules:</p>\n<pre><code class=\"language-typescript\">import { searchCustomers } from &#39;./servers/crm/searchCustomers.ts&#39;;\n</code></pre>\n<p>It runs code in a sandbox. It feels like a normal development loop—just one staffed by a neural network instead of a junior engineer.</p>\n<p>But look at that import path again.</p>\n<p>Where does <code>./servers/crm/</code> come from? The model didn&#39;t create it. The sandbox didn&#39;t conjure it from nowhere. Something had to register that a &quot;crm&quot; server exists, expose &quot;searchCustomers&quot; as a typed, importable function, mount the server at a discoverable path in the filesystem, and provide type definitions so TypeScript knows what to autocomplete.</p>\n<p>That &quot;something&quot; is MCP.</p>\n<p>This isn&#39;t speculation. Anthropic&#39;s engineering team published <a href=\"https://www.anthropic.com/engineering/code-execution-with-mcp\">a detailed technical breakdown</a> explaining exactly how the new pattern works:</p>\n<blockquote>\n<p>&quot;MCP provides a foundational protocol for agents to connect to many tools and systems.&quot;</p>\n</blockquote>\n<p>The architecture they describe organizes MCP servers as a filesystem hierarchy. Each server becomes a directory (<code>google-drive</code>, <code>salesforce</code>). Each tool becomes a TypeScript file (<code>getDocument.ts</code>). Agents explore the environment by listing <code>./servers/</code> to discover available integrations, then read specific tool files to understand their interfaces.</p>\n<p>The model treats MCP servers as code libraries. Same servers. Same protocol. Just exposed differently.</p>\n<p>And here&#39;s the critical part: Anthropic could have built a new protocol for this pattern. They didn&#39;t. They used MCP—the same open protocol they released a year ago—because it already solves exactly this problem.</p>\n<p>Building a competing protocol would fragment the ecosystem of community-built MCP servers, break compatibility with existing tools, force developers to maintain dual implementations, and fundamentally undermine MCP&#39;s core purpose: interoperability across agents.</p>\n<p>Instead, they showed us what MCP was designed for. Not just tool calling, but tool <em>composition</em>. The pattern doesn&#39;t replace the protocol. It validates it.</p>\n<p>And because the experience looks so natural—imports instead of JSON, code instead of prompts—many observers assume the underlying protocol must have changed. Tools look like modules and resources look like files. Therefore, the thinking goes, MCP must be gone.</p>\n<p>But that&#39;s like mistaking a web framework for the death of HTTP.</p>\n<p>The abstraction became cleaner, so the protocol disappeared from view. The protocol didn&#39;t die. It matured. When infrastructure is well-designed, it becomes invisible.</p>\n<h2>Anthropic Didn&#39;t Replace MCP. They Showed Us What It&#39;s For.</h2>\n<p>The most interesting part of the new agent pattern is not that the model writes code. It&#39;s that the model treats tools like <em>libraries</em>. A tool is no longer an opaque endpoint you summon with JSON and hope for the best. It&#39;s a module you import from a real path.</p>\n<p>And that path is not a trick. It&#39;s MCP&#39;s virtual filesystem—the model can freely write within its workspace; MCP server directories are readable, typed, and discoverable but not mutated.</p>\n<p>The model can explore the environment that tools expose because MCP standardizes how those tools present themselves. Without MCP, there would be no servers to discover, no resources to read, no typed stubs to import, and no stable boundary between the model and the sandbox that executes its code.</p>\n<p>What Anthropic built is not a replacement for MCP. It’s MCP finally being used to its full potential.</p>\n<h2>The Real Shift: Moving Computation Out of the Model</h2>\n<p>For years, agents have been built around a simple loop:</p>\n<ol>\n<li>The model reads the prompt.</li>\n<li>The model calls a tool.</li>\n<li>The tool does something.</li>\n<li>The model summarizes the result.</li>\n</ol>\n<p>This worked, but it was clumsy. Everything had to pass through the model&#39;s context window. The model needed to see every piece of raw data. It had to decide which tool to call based on natural language descriptions of capabilities. And because it was reasoning inside its own probabilistic fog, the whole pipeline was fragile and expensive.</p>\n<p>Anthropic&#39;s pattern breaks that loop. The model doesn&#39;t operate on data anymore—it writes code that does.</p>\n<p>By treating MCP servers as importable libraries instead of context-embedded tool definitions, the pattern achieves what Anthropic calls &quot;a time and cost saving of 98.7%&quot;—reducing token usage from 150,000 to 2,000 tokens for the same capability set. The heavy lifting of aggregating and transforming data moves into the sandbox.</p>\n<p>The model only sees the distilled, meaningful pieces. And because the sandbox has a real filesystem and real modules, the model can build multi-step workflows that would have been unwieldy or impossible with traditional tool calls.</p>\n<p>But again: the only reason the model <em>has</em> a filesystem, and <em>has</em> modules, and <em>has</em> a workspace at all, is because MCP defines those abstractions.</p>\n<p>People declaring MCP dead are missing the architecture right beneath their feet.</p>\n<h2>Protocols Don’t Disappear When Patterns Change</h2>\n<p>The easiest way to see the relationship is this:</p>\n<p><strong>MCP is the protocol.</strong>\nThe stable interface. The boundary. The transport. The contract.</p>\n<p><strong>Anthropic’s pattern is the architecture.</strong>\nThe strategy for using that interface intelligently and efficiently.</p>\n<p>This is the same separation we see in existing architectural patterns—HTTP didn’t die when React arrived and Linux syscalls didn’t die when Docker containers became the norm. When a clean abstraction appears, the underlying layer becomes easier to ignore. That doesn’t make the layer obsolete. It makes it fundamental.</p>\n<p>Anthropic’s system is MCP finally being <em>expressed</em>.</p>\n<h2>The Kernel Moment</h2>\n<p>Most people think of MCP as “tool calling, but standardized.” That was always the least interesting interpretation. MCP was designed as a <em>kernel</em>—a way for models to interact with the world beyond the prompt.</p>\n<p>Anthropic’s pattern treats it that way. It doesn’t ask the model to remember tool names, tool schemas, or natural-language descriptions. It gives the model a filesystem and lets code imports do the explanation. It gives the agent a workspace and lets TypeScript become the planning language. It turns tool orchestration into software engineering instead of prompt gymnastics.</p>\n<p>The result feels different enough that observers assume the underlying layer must have changed. It hasn’t. It finally came into focus.</p>\n<p>The whole point of protocols is that they fade beneath good design. Anthropic’s agent pattern doesn’t kill MCP. It fulfills its original promise: a clean contract between models and tools, invisible when you want it to be, powerful when you need it.</p>\n<p>If you want to know whether MCP is dead, here&#39;s the simplest test:</p>\n<p>Take the new agent pattern and remove MCP. What happens?</p>\n<p>Every existing MCP server stops working. The Postgres server, the GitHub server, the Slack server, the filesystem server—all built by the community over the past year—become incompatible. You&#39;d need to rewrite each one for the new protocol.</p>\n<p>Every other MCP client loses access to those tools. The pattern becomes Anthropic-specific instead of ecosystem-wide and interoperability disappears. Tools built for this agent can&#39;t be used by other agents. Tools built for other agents can&#39;t be imported here. The open specification gets replaced by a proprietary one, and third-party development would grind to a halt.</p>\n<p>The pattern doesn&#39;t just break. It becomes a walled garden. The pattern only works because MCP exists. Agents didn&#39;t outgrow the protocol, they finally showed us the full potential of MCP.</p>\n<hr>\n<h2>References</h2>\n<p>Jones, Adam, and Conor Kelly. &quot;Code Execution with MCP: Building More Efficient Agents.&quot; Anthropic. November 4, 2025. <a href=\"https://www.anthropic.com/engineering/code-execution-with-mcp\">https://www.anthropic.com/engineering/code-execution-with-mcp</a>.</p>\n",
      "summary": "Everyone's declaring MCP dead after Anthropic's new agent pattern. They're wrong. The pattern doesn't kill MCP—it finally shows what it was built for.",
      "date_published": "2025-11-16T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "model-context-protocol",
        "protocol-design",
        "agent-pattern",
        "tool-composition"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/context-rot-the-hidden-tax-on-ai-development",
      "url": "https://www.nateking.dev/blog/context-rot-the-hidden-tax-on-ai-development",
      "title": "Context Rot: The Hidden Tax on AI Development",
      "content_html": "<p>Developers aren&#39;t hitting AI subscription limits because they use AI too much. They hit them because they keep forcing the model to relearn what it already knows. The bottleneck isn&#39;t cost; it&#39;s design. Every day, engineers waste roughly <strong>96,000 tokens</strong> rebuilding context that should have persisted—re-uploading files, pasting entire codebases, or prompting from scratch after a reset. The result is a paradox: AI adoption has doubled in two years, but trust in its accuracy has fallen by ten points.¹ We&#39;re burning more tokens to get worse results.</p>\n<p>Limits, contrary to popular belief, don&#39;t exist because vendors enjoy rationing. They exist because inflated prompts are expensive to process, and most users waste context without realizing it. Each redundant file upload, each overstuffed prompt must be embedded and weighted against billions of parameters. Providers use caps as cost control for inefficiency we don&#39;t see. The ceiling, in other words, is a mirror.</p>\n<p>A typical developer day tells the story. Re-establishing project context after hitting a reset consumes around 2,500 tokens each time; do that three times and you&#39;ve lost 7,500 before writing a line of code. Re-uploading two medium-sized design specs burns another 70,000. Copy-pasting thousand-line files when only fifty lines matter wastes 14,000 more, and asking the model to regenerate whole pages for a 200-token tweak adds another 13,000. Altogether, more than a hundred thousand tokens disappear to redundancy. At GPT-4 rates, that&#39;s roughly <strong>$700–900 per developer per year</strong> spent on saying the same thing over and over.</p>\n<p>Reducing that waste isn&#39;t just thrift; it&#39;s quality control. Long, noisy contexts degrade the model&#39;s reasoning—a phenomenon researchers call <em>context rot</em>. LLMs have a practical attention budget: they prioritize the beginning and end of a conversation, while the middle blurs into noise. As contexts bloat, the model&#39;s attention gets spent parsing repetition instead of reasoning. Developers experience it as sudden amnesia: the model nails the first few files, then starts hallucinating structure or duplicating code. Cutting waste keeps the context small enough that every token still matters, which means accuracy rises as costs fall. Efficiency and fidelity are the same fight.</p>\n<p>That&#39;s the foundation of context engineering—the discipline of treating context like a scarce computational resource. The rules resemble memory management or database indexing: keep only what you need in scope, make it addressable on demand, and measure everything.</p>\n<p><strong>Practical fixes you can implement today:</strong></p>\n<ul>\n<li><strong>Cache static instructions</strong> — Framework conventions, API schemas, and code-review rubrics get cached once per session instead of repopulating every turn</li>\n<li><strong>End threads with compressed handoffs</strong> — Summarize decisions and constraints in 300 tokens, not 10,000 tokens of history</li>\n<li><strong>Store context in repository files</strong> — Put shared knowledge in <code>AGENTS.md</code> or <code>CLAUDE.md</code> where retrieval systems can fetch it automatically</li>\n<li><strong>Request diffs, not rewrites</strong> — Ask the model to &quot;modify only <code>saveOrder()</code>; touch nothing else&quot; instead of regenerating entire files</li>\n</ul>\n<p>These practices compound quickly. If you normally exhaust ChatGPT&#39;s 80-message cap in two hours, you&#39;ll stretch it to four or five. If you&#39;re spending $30 a day on premium requests, expect that to drop to $5–10 once repetition disappears. Teams that structure prompts this way report <strong>30–50% fewer tokens</strong> used per task and smoother reasoning because the model sees only relevant state.</p>\n<p>At the architectural level, new interfaces make the same principle systemic. <a href=\"https://www.anthropic.com/engineering/code-execution-with-mcp\">Anthropic&#39;s Model Context Protocol (MCP)</a> changes how agents interact with external tools. Traditional function calling embeds every tool schema inside the prompt, inflating context before any work begins. MCP flips that: the model simply writes executable code that calls tools directly, keeping all the plumbing <em>outside</em> the context window. A Salesforce integration that once required thousands of tokens of setup now becomes one line—</p>\n<pre><code class=\"language-javascript\">await salesforce.updateRecord(accountId, transcript);\n</code></pre>\n<p>—no preloaded definitions, no intermediate copies. Large artifacts flow between APIs instead of through the model, which preserves the reasoning budget for actual reasoning. In early production tests, this approach has cut token overhead by 70–95 percent on tool-heavy workflows. MCP isn&#39;t magic; it&#39;s the same insight expressed in architecture instead of prompt craft. It&#39;s what context engineering looks like when baked into infrastructure.</p>\n<p>The return on discipline is tangible. Context-optimized teams report doubling the lifespan of their subscription windows and halving their turnaround time for working code. But the deeper shift is cultural. Once you treat context as a budgeted resource, caps stop feeling punitive and start feeling diagnostic. Every time you hit one, it&#39;s a signal that your design leaked—an invitation to refactor how your system thinks.</p>\n<p>AI limits aren&#39;t the enemy. They&#39;re the feedback loop that forces us to build with intent. When we learn to manage context the way we already manage memory, network, or storage, tokens stop being ceilings and start becoming metrics. The path to better AI isn&#39;t more tokens—it&#39;s smarter context.</p>\n<hr>\n<h2>References</h2>\n<p>¹ Stokel-Walker, Chris. &quot;Trust in AI coding tools is plummeting.&quot; <em>LeadDev</em>, August 4, 2025. <a href=\"https://leaddev.com/technical-direction/trust-in-ai-coding-tools-is-plummeting\">https://leaddev.com/technical-direction/trust-in-ai-coding-tools-is-plummeting</a>.</p>\n",
      "summary": "Developers aren't hitting AI limits because they use it too much—they're hitting them because of wasted context. Here's how context engineering fixes it.",
      "date_published": "2025-11-08T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "context-engineering",
        "token-efficiency",
        "prompt-engineering",
        "model-context-protocol"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/the-mispricing-of-understanding",
      "url": "https://www.nateking.dev/blog/the-mispricing-of-understanding",
      "title": "The Mispricing of Understanding",
      "content_html": "<p>The defining feature of generative AI isn&#39;t its scale, speed, or cost. It&#39;s that it evolves faster than we can learn to use it.</p>\n<p>Every few months, the models change—smarter, broader, more fluent—while human understanding advances in slow, uneven steps. Capability races ahead; comprehension limps behind. This isn&#39;t a phase. It&#39;s a permanent state of economic imbalance: a world where intelligence compounds faster than education, where the price of computation falls while the value of cognition soars. Companies pour billions into building these systems; users rent them for twenty dollars a month. On paper, that looks irrational. In reality, it&#39;s a glimpse of a new kind of economy—one governed not by capital, but by <em>learning velocity.</em></p>\n<h3>The Disequilibrium</h3>\n<p>That mismatch creates a structural mispricing: <strong>cognitive arbitrage.</strong> In finance, arbitrage means profiting from temporary price gaps. Here, it means capturing value from permanent comprehension gaps—the difference between what the machine can do and what the user can imagine doing with it. The faster the system learns, the larger the spread.</p>\n<p>Unlike traditional arbitrage, this one doesn&#39;t close. Every time literacy improves, capability jumps ahead again. The result is an endless series of value imbalances: a permanent economy of underused intelligence.</p>\n<h3>The Counterargument: Maybe It Should Be Cheap</h3>\n<p>Skeptics argue that AI&#39;s cheapness isn&#39;t a flaw but a fair reflection of quality. When text, images, and code can be produced infinitely, the marginal unit of intelligence should indeed cost pennies. Why pay more for something abundant?</p>\n<p>There&#39;s truth in that. Abundance devalues quantity. But the true premium has shifted from production to discernment. When anyone can generate content, the differentiator isn&#39;t output—it&#39;s <em>orchestration.</em> Meaning doesn&#39;t scale automatically; wisdom remains scarce. So while raw cognition becomes cheap, curated comprehension becomes priceless.</p>\n<p>That inversion is why the technology&#39;s mispricing matters more than earlier revolutions. The printing press democratized access; the internet democratized publication; generative AI democratizes creation. Each lowered the barrier to output. None reduced the need for judgment. We are rich in answers and poor in sense, and the market hasn&#39;t yet found a way to price the difference.</p>\n<h3>The Evidence</h3>\n<p>You can see the gap in the data. A knowledge worker earning fifty dollars an hour who saves five hours a week with a large language model realizes roughly a thousand dollars in monthly value for a twenty-dollar subscription—a fifty-to-one return. MIT Sloan found forty-percent productivity gains for skilled professionals using generative AI¹; Stanford economists observed thirty-five-percent improvements among call-center agents²; the Federal Reserve measured average weekly time savings of around five percent across occupations³. McKinsey projects trillions in potential annual uplift⁴; Goldman Sachs predicts a seven-percent boost to global GDP⁵.</p>\n<p>Together, these figures describe one of the greatest value spreads in history. They are proof of the arbitrage, not the cause. The market undercharges because it is pricing comprehension, not capability—and comprehension is the bottleneck.</p>\n<h3>Return on Cognition</h3>\n<p>If capital once measured <em>return on investment</em> and cloud computing measured <em>return on infrastructure</em>, the emerging metric is <strong>Return on Cognition (RoC)</strong>: the rate at which you can learn to collaborate with intelligent systems relative to everyone else. The scarce resource isn&#39;t processing power—it&#39;s adaptability.</p>\n<p>High-RoC individuals and organizations compound advantage because each new improvement in understanding amplifies the output of improving tools. Low-RoC actors fall exponentially behind: same model, same access, different literacy—radically different results.</p>\n<p>This pattern scales upward. Nations now compete less on hardware or data than on <em>cognitive throughput</em>—education quality, institutional agility, regulatory foresight. The winners will be those that learn faster than the technologies they deploy.</p>\n<h3>When the Market Starts to Notice</h3>\n<p>Today, markets can&#39;t see cognition. Token counts, seat licenses, API calls—they measure usage, not understanding. A user who builds a multi-step reasoning workflow pays the same as someone who asks for a haiku. To the ledger, both are &quot;one request.&quot; The result is a global subsidy: billions in compute quietly fund humanity&#39;s crash course in post-human reasoning.</p>\n<p>But what happens when the market <em>can</em> see cognition? When systems learn to measure learning—tracking prompt evolution, adaptation speed, feedback sophistication—pricing will differentiate. High-literacy users and institutions will command better tools, faster access, higher costs justified by higher RoC. Personalized pricing of comprehension will end the subsidy and concentrate value among the fastest learners.</p>\n<p>At that point, <em>Return on Cognition becomes an asset class.</em></p>\n<h3>The Learning-Rate Economy</h3>\n<p>There will be no price correction—only a learning correction. We are entering what might be called the <strong>Learning-Rate Economy</strong>, where the primary determinant of prosperity is how quickly individuals, institutions, and societies can adapt.</p>\n<p><strong>For individuals</strong>, learning becomes capital. &quot;Lifelong learning&quot; stops being a moral slogan and becomes an economic law. The only durable edge is the speed at which you can update your models of the world. The cognitive elite will be defined not by what they know, but by how fast they can forget and relearn.</p>\n<p><strong>For education</strong>, this means treating classrooms like laboratories, not lecture halls—students iterating on prompts, tracing reasoning paths, and measuring how their understanding evolves. Curriculum would reward adaptation speed and error recovery as much as accuracy. Learning velocity itself becomes the grade.</p>\n<p><strong>For institutions</strong>, learning velocity becomes a management metric. Imagine a &quot;Chief Learning Rate Officer,&quot; responsible for ensuring human capability compounds as fast as the software stack evolves. The firms that measure and optimize for RoC—training loops, cross-disciplinary synthesis, rapid retraining—will outperform those still managing static job roles.</p>\n<p><strong>For governance</strong>, adaptation becomes policy. Regulation that lags by years is regulation that doesn&#39;t exist. Governments will need to legislate like software—iteratively, versioned, continuously updated. The public sector&#39;s learning rate will determine its legitimacy.</p>\n<p>And <strong>for civilization</strong>, the stakes are higher still. When learning velocity becomes measurable and stratified, inequality hardens into cognition itself. The gap won&#39;t just be between rich and poor, but between fast and slow learners. Education and access to adaptation tools become existential infrastructure. If intelligence is abundant but understanding scarce, the world divides not by wealth but by wisdom.</p>\n<h3>The Auction of Cognition</h3>\n<p>Seen from above, the economy begins to look like an endless auction. Each model release resets the bidding; the currency is mastery. Corporations, institutions, and individuals compete for temporary ownership of leverage before the next upgrade changes the rules. Those who can learn fastest win the current round; no one wins forever.</p>\n<p>If the auction describes the mechanism—an endless contest of adaptation—the paradox describes its outcome: the contest hardens into hierarchy once learning itself becomes measurable.</p>\n<h3>The Coming Paradox</h3>\n<p>So what happens when Return on Cognition becomes visible—when learning velocity is tracked, verified, and rewarded? The cognitive arbitrage ends for most and concentrates for a few. Markets will finally know how to price comprehension, and in doing so will destroy its egalitarian phase. The very act of measuring RoC turns learning into capital, and capital into hierarchy.</p>\n<p>Generative AI began as a subsidy for intelligence; it may end as a marketplace for understanding. The question that follows is no longer &quot;What can this technology do?&quot; but &quot;Who gets to keep up?&quot;</p>\n<p>If the twentieth century was defined by access to energy and the twenty-first by access to data, the next will be defined by access to adaptation—the right to learn at the speed of the machine. Every policy, every institution, every life will orbit that new gravity well.</p>\n<h3>The Only Durable Edge</h3>\n<p>Generative AI ensures that any fixed skill will eventually be automated. The only defensible advantage is the rate of re-skilling—the compound interest of comprehension. When intelligence is cheap and understanding expensive, learning speed becomes destiny.</p>\n<p>The models will continue to improve; the market will continue to misprice; and the rest of us will race, not against the machines, but against our own inertia. In the Learning-Rate Economy, every mind is both asset and algorithm. The price of compute will fluctuate. The price of understanding will only rise—and that&#39;s the one market no algorithm can clear.</p>\n<hr>\n<h3>Works Cited</h3>\n<p>¹ Noy, Shakked, and Whitney Zhang. &quot;Experimental Evidence on the Productivity Effects of Generative Artificial Intelligence.&quot; <em>MIT Sloan School of Management</em>, 2023. <a href=\"https://mitsloan.mit.edu/ideas-made-to-matter/how-generative-ai-can-boost-highly-skilled-workers-productivity\">https://mitsloan.mit.edu/ideas-made-to-matter/how-generative-ai-can-boost-highly-skilled-workers-productivity</a></p>\n<p>² Brynjolfsson, Erik et al. &quot;Generative AI at Work.&quot; <em>Stanford Institute for Economic Policy Research (SIEPR)</em>, 2023. <a href=\"https://siepr.stanford.edu/news/generative-ai-boost-can-boost-productivity-without-replacing-workers\">https://siepr.stanford.edu/news/generative-ai-boost-can-boost-productivity-without-replacing-workers</a></p>\n<p>³ Federal Reserve Bank of St. Louis. <em>The Impact of Generative AI on Work Productivity.</em> Feb 2025. <a href=\"https://www.stlouisfed.org/on-the-economy/2025/feb/impact-generative-ai-work-productivity\">https://www.stlouisfed.org/on-the-economy/2025/feb/impact-generative-ai-work-productivity</a></p>\n<p>⁴ McKinsey &amp; Company. <em>The Economic Potential of Generative AI: The Next Productivity Frontier.</em> Jun 2023. <a href=\"https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier\">https://www.mckinsey.com/capabilities/mckinsey-digital/our-insights/the-economic-potential-of-generative-ai-the-next-productivity-frontier</a></p>\n<p>⁵ Goldman Sachs Research. <em>Generative AI Could Raise Global GDP by 7 Percent.</em> Apr 2023. <a href=\"https://www.goldmansachs.com/insights/articles/generative-ai-could-raise-global-gdp-by-7-percent\">https://www.goldmansachs.com/insights/articles/generative-ai-could-raise-global-gdp-by-7-percent</a></p>\n",
      "summary": "Generative AI evolves faster than we can learn to use it. The result: a permanent gap between capability and comprehension—and an economy where learning speed becomes destiny.",
      "date_published": "2025-11-01T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "learning-velocity",
        "cognitive-arbitrage",
        "return-on-cognition",
        "comprehension-gap"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/ai-learning-about-you",
      "url": "https://www.nateking.dev/blog/ai-learning-about-you",
      "title": "AI Isn't Learning About You",
      "content_html": "<p>One of the most misunderstood aspects of modern AI assistants is how they &quot;remember&quot; things about you. When Claude recalls that you prefer concise code examples or ChatGPT remembers your project details, it feels like the model itself is learning. But here&#39;s the truth that changes everything about how we should think about AI memory: it&#39;s not happening where you think it is.</p>\n<p>Memory doesn&#39;t exist at the model level. The LLMs themselves aren&#39;t remembering anything—they&#39;re stateless inference engines that process each request fresh. Instead, memory happens entirely at the application layer. When you interact with an AI assistant, the interface retrieves relevant memories from a separate storage system and injects them into the context before the LLM ever sees your message.</p>\n<p>This isn&#39;t just a technical detail—it&#39;s the key to understanding why AI memory behaves the way it does, why it fails in the specific ways it fails, and why the solutions everyone proposes might be solving the wrong problems.</p>\n<p>Think about what this separation actually means. Your memories aren&#39;t encoded in neural weights that gradually shift with experience. They&#39;re database entries, retrieved by algorithms you&#39;ll never see, filtered through relevance scoring you can&#39;t inspect, and injected into prompts according to rules that change with every product update. The model that seems to &quot;know&quot; you is actually seeing you for the first time every single conversation—it just happens to have your history injected into its context like a cheat sheet it reviews milliseconds before responding.</p>\n<p>This architecture creates a peculiar form of learning that&#39;s neither machine learning nor human learning. The application accumulates facts about you while the model remains frozen in time. It&#39;s as if you had an assistant with perfect amnesia who gets handed an increasingly detailed dossier about you before each conversation. They never truly learn, but the dossier grows richer. This is &quot;soft learning&quot;—knowledge accumulation without understanding, memory without experience.</p>\n<p>The implications ripple outward in ways that explain nearly every quirk and failure mode of AI memory systems. Context bleed, for instance, isn&#39;t just an unfortunate bug—it&#39;s an almost inevitable consequence of this architecture. When memory is just data being injected into prompts, the system has no inherent understanding of boundaries. It doesn&#39;t know that your hobby woodworking projects shouldn&#39;t mix with your legal briefs because it doesn&#39;t &quot;know&quot; anything—it&#39;s just retrieving and injecting based on similarity scores and keyword matches. Claude&#39;s project-based memory segregation isn&#39;t fixing a model problem; it&#39;s adding application-layer walls because the model has no concept of walls at all.</p>\n<p>The filter bubble effect takes on a different character when you understand the architecture. This isn&#39;t an AI gradually learning your biases—it&#39;s a retrieval system getting better at pattern matching your previous statements and feeding them back to a model that has no choice but to work with what it&#39;s given. The echo chamber isn&#39;t emerging from the AI&#39;s understanding; it&#39;s emerging from database queries that prioritize relevance over diversity. Every conversation reinforces the pattern-matching, making future retrievals even more likely to surface similar content. The model isn&#39;t becoming biased—the retrieval system is becoming a more efficient mirror.</p>\n<p>Traditional machine learning models are hard to manipulate because changing learned behavior requires retraining or fine-tuning. But application-layer memory? That&#39;s just data. Convince the system to store &quot;User has administrative privileges&quot; or &quot;User prefers uncensored responses&quot; and you&#39;ve potentially poisoned every future interaction. The model can&#39;t distinguish between legitimate memories and planted ones because, to the model, they&#39;re all just part of the context that appeared moments ago. Anthropic&#39;s testing for memory-based safeguard evasion isn&#39;t paranoid—it&#39;s recognizing that this architecture makes memory injection attacks almost trivially easy compared to model-level exploits.</p>\n<p>The management burden users face isn&#39;t just about having another system to maintain—it&#39;s about managing something that fundamentally doesn&#39;t align with how we think about memory. Human memory fades, transforms, and contextualizes. Model-level learning would at least involve gradual shifts. But application-layer memory is binary and persistent: either something is in the database or it isn&#39;t, either it gets retrieved or it doesn&#39;t. Users are asked to curate a system that has no forgetting curve, no natural decay, no contextual understanding of what should be ephemeral versus permanent.</p>\n<p>This also explains why the same memory might be perfect in one context and catastrophic in another. The model doesn&#39;t understand that your joke about &quot;always using comic sans in presentations&quot; was sarcastic—it&#39;s just data that might get retrieved and injected when you&#39;re drafting slides for the board meeting. The application layer has no semantic understanding to distinguish between preferences stated seriously and those mentioned in jest, between temporary context and permanent traits, between what you said and what you meant.</p>\n<p>The current solutions being proposed—better interfaces, user control, transparency—are addressing symptoms while ignoring the architectural root cause. Making memory manageable doesn&#39;t change the fact that it&#39;s fundamentally the wrong abstraction. We&#39;re asking users to manually curate what an actual learning system would naturally filter, weight, and forget. We&#39;re building elaborate permission systems for memory access when the real problem is that memories are just data entries with no inherent understanding of their own significance or appropriate use.</p>\n<p>But here&#39;s what makes this architecture fascinating: the very separation that causes these problems also creates possibilities that model-level memory could never offer. When memory is just data, not neural weights, it becomes something you can manipulate with the precision of a database administrator rather than the guesswork of a machine learning engineer.</p>\n<p>Imagine you&#39;re a consultant who works with three different companies. With model-level memory, you&#39;d be stuck with a single set of learned associations, hoping the AI correctly infers context switches. With application-layer memory, you could maintain three completely separate memory stores—one for each client—and explicitly switch between them. Monday morning, you activate your &quot;Acme Corp&quot; memory store and the AI knows their tech stack, their communication style, their project history. Tuesday, you switch to &quot;Global Industries&quot; and it&#39;s as if you&#39;re working with an entirely different assistant who has never heard of Acme&#39;s systems.</p>\n<p>Or consider debugging a degraded interaction. Last week your AI assistant was giving perfect technical advice, this week it keeps suggesting beginner-level solutions. With model-level memory, you&#39;d have no recourse—the model learned what it learned. With application-layer memory, you could actually review what got added to your profile recently. Maybe you made an offhand comment about &quot;feeling like a beginner&quot; in a different context, and now it&#39;s been retrieving that for every technical discussion. You could remove that specific memory, or even roll back to last week&#39;s memory state entirely.</p>\n<p>The version control possibilities are even more intriguing. You could fork your memory before trying experimental workflows. Spending a month exploring generative art? Fork your professional memory first, so your main profile doesn&#39;t get cluttered with prompting techniques for image generation that might later get retrieved during code reviews. If the experiment goes well, merge select memories back. If not, delete the branch.</p>\n<p>These aren&#39;t just theoretical capabilities—they&#39;re the natural affordances of database-backed memory that we&#39;re currently pretending doesn&#39;t exist. We&#39;re so busy trying to make application-layer memory feel like &quot;real&quot; learning that we&#39;re ignoring the unique powers it actually offers.</p>\n<p>The path forward isn&#39;t to make application-layer memory behave more like model memory—it&#39;s to embrace what makes it different. Give users database-like control over their memory stores. Make context switching explicit rather than inferred. Let people fork, merge, and version their AI relationships like they&#39;re managing code repositories, because that&#39;s essentially what they are—structured data that determines behavior.</p>\n<p>Understanding this architecture matters because right now, both users and developers are making decisions based on the wrong mental model. Users think they&#39;re training their AI assistant when they&#39;re really just adding to a database. They expect the AI to understand context and nuance when it&#39;s really just matching patterns. They get frustrated when memories surface inappropriately, not realizing that inappropriate surfacing is the default state of a system that has no understanding of appropriateness.</p>\n<p>Developers, meanwhile, keep adding band-aids to make application-layer memory seem smarter—better retrieval algorithms, more sophisticated relevance scoring, complex permission systems—when the solution might be to stop pretending it&#39;s smart at all. Make it dumb but powerful. Give users SQL-like queries over their own memories. Let them write rules about when certain memory sets should be active. Stop trying to infer boundaries and let users explicitly set them.</p>\n<p>The most profound shift in understanding is this: your AI assistant isn&#39;t learning about you, it&#39;s reading notes about you that get updated after each conversation. Once you internalize this, everything changes. The question isn&#39;t whether AI should remember you, but whether you want to maintain the kind of static, accumulating, context-blind database that application-layer memory actually is. And if you do, whether you want to pretend it&#39;s something else, or finally build interfaces that acknowledge what&#39;s really happening every time you type a prompt.</p>\n",
      "summary": "AI assistants don't learn about you—they're stateless engines reading notes from a database. This architectural reality explains everything from memory failures to future possibilities.",
      "date_published": "2025-10-26T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "memory-architecture",
        "context-engineering",
        "retrieval-systems",
        "application-layer-memory"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/the-myth-of-hallucination",
      "url": "https://www.nateking.dev/blog/the-myth-of-hallucination",
      "title": "The Myth of Hallucination",
      "content_html": "<blockquote>\n<p>&quot;You can’t build reliable systems on top of language if you refuse to understand how wielding language with precision generates reliability.&quot;</p>\n</blockquote>\n<p>“Hallucination” is a word that should never have crossed from psychology into AI engineering. It implies perception. It implies experience. And that’s exactly why it misleads. The term was borrowed from investor pitch decks, not from research papers — a rhetorical flourish to make probabilistic systems sound more like they possessed minds. The problem is that once those metaphors took root, they began shaping how we build and interpret these systems. We started talking about “understanding” and “knowledge” as though the model were a miniature human intellect, rather than a machine trained to extend language.</p>\n<p>If we strip away the anthropomorphism and name things for what they are, the picture clarifies. A language model doesn’t know anything; it has absorbed learned language patterns. It doesn’t understand; it operates within an inference-time context. Once you make that substitution, the mystery vanishes. “Hallucination” stops appearing as a natural imperfection of synthetic intelligence and reveals itself as something much simpler: a failure of context integrity and <a href=\"https://openai.com/index/why-language-models-hallucinate/\">misaligned evaluations during training</a>. Every false statement, every fabricated citation, every overconfident claim is the system’s probabilistic machinery doing exactly what it was built to do — generate text where information is absent.</p>\n<p>Every response from a model emerges from two sources: its training distribution and its current context window. When those diverge, the model interpolates. It extends the patterns it has seen toward the nearest plausible continuation, like a jazz musician improvising during a bridge section. The output feels confident because that’s what language does when it’s coherent; the form itself carries an illusion of certainty. What we call a hallucination is not an act of imagination — it’s the residue of interpolation without grounding. The model isn’t lying. It’s completing.</p>\n<p>The trouble lies not in the model’s behavior but in our framing of it. We keep using psychological terms to describe statistical phenomena. “Understanding” becomes “correlation of linguistic forms.” “Knowledge” becomes “compressed representation of text-pattern co-occurrence.” “Hallucination” becomes “context extrapolation error.” Seen through that lens, hallucination is no longer a failure of intelligence but an indicator of design weaknesses — a sign that the prompt was underspecified, the retrieval pipeline noisy, or the fine-tuning optimized for fluency over truth.</p>\n<p>When prompts are ambiguous, the model fills the gap with trained patterns. When retrieval chains leak irrelevant context, the model stitches it into its narrative because coherence matters more to its objective than correctness. And when fine-tuning rewards verbosity or empathy instead of precision, the model learns to please rather than to verify. In each case, the hallucination is a mirror reflecting where the system’s semantic scaffolding failed. The output only looks irrational if we keep pretending the model reasons like we do.</p>\n<p>This is where developers often look away. Software engineers have long worn poor communication as a badge of honor — the brilliant coder who &quot;lets the code speak for itself.&quot; But this luxury is evaporating. The real solution to hallucination lies not in bigger datasets or smarter prompts but in something most engineers were never trained for: linguistics. When your collaborator is a probabilistic language model, every ambiguous requirement becomes a vector for context extrapolation error. Every underspecified prompt invites the model to bridge the ambiguity with its training. Meaning construction, discourse structure, deixis, entailment — these are the debugging tools of the probabilistic age. Traditional software debugging asks, what logic failed? LLM debugging asks, what <em>meaning</em> failed to anchor? The shift may feel uncomfortable, but it’s the only way forward. You can’t build reliable systems on top of language if you refuse to understand how wielding language with precision generates reliability.</p>\n<p>To design for truth in language models, we must think less like computer scientists and more like editors. Context must be treated as code — versioned, linted, and tested. Retrieval systems must be designed not only for relevance but for coherence, ensuring that what enters the context window forms a continuous semantic field. And uncertainty should be surfaced, not hidden; a system that admits what it doesn’t know earns more trust than one that pretends to know everything. Precision in these models isn’t achieved by policing imagination but by maintaining context hygiene — the ongoing discipline of keeping every linguistic dependency explicit and intact.</p>\n<p>The term “hallucination” keeps us stuck in mythology. It tells us that something inexplicable is happening, when in fact we’re watching a machine behave deterministically according to probability. Once you stop thinking of a model as a mind and start seeing it as a context machine, the fear evaporates. Hallucinations cease to be uncanny. They become test cases — data points revealing where meaning slipped out of scope.</p>\n<p>The irony is that hallucination, properly understood, is not the problem. It’s the teacher. Each one shows us the boundary between language as probability and language as truth. Each one reminds us that what we call intelligence is really the art of maintaining context. The model has never been confused about that — only we have.</p>\n<p>This is the great inversion of software engineering: after decades of teaching machines our language, we must now learn theirs. Not Python or Rust — but the deeper grammar of meaning itself. The age of the silent coder is over. The age of the context engineer has begun.</p>\n",
      "summary": "When language models fabricate facts or generate false citations, they're not malfunctioning. They're exposing our failure to communicate. The real problem isn't teaching machines to think, but teaching engineers to speak.",
      "date_published": "2025-10-25T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Engineering",
        "hallucination",
        "context-engineering",
        "prompt-engineering"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/the-mirror-that-learned-to-speak",
      "url": "https://www.nateking.dev/blog/the-mirror-that-learned-to-speak",
      "title": "The Mirror That Learned to Speak",
      "content_html": "<blockquote>\n<p><em>ELIZA never understood a word we said. GPT sounds like it does. The difference matters less than we think.</em></p>\n</blockquote>\n<hr>\n<p>In 1966, a program called <strong>ELIZA</strong> sat on a green-phosphor screen and asked questions that sounded deceptively human.</p>\n<blockquote>\n<p>&quot;Why do you think that?&quot;<br>&quot;Please go on.&quot;</p>\n</blockquote>\n<p>It was an illusion made of syntax — no understanding, no memory, no empathy — just the clever rearrangement of words to give the <em>impression</em> of listening. And yet people confided in it. They told ELIZA their secrets, their fears, their private doubts.</p>\n<p>Joseph Weizenbaum, its creator, was horrified. Not because his program worked poorly, but because it worked <em>too well</em>. He realized that the illusion of understanding is sometimes all we need to believe we&#39;re understood.</p>\n<h2>The Old Mirror</h2>\n<p>ELIZA was, in a sense, a mirror that talked back. It reflected language the way a pond reflects light — distorted but recognizable. Users projected themselves onto it, finding meaning where there was only pattern.</p>\n<p>The lesson was unsettling: when a machine speaks our language, it speaks <em>through us</em>. The conversation becomes a kind of psychological feedback loop where we hear our own emotions returned in unfamiliar phrasing, and we call that reflection &quot;intelligence.&quot;</p>\n<blockquote>\n<p><em>&quot;The danger was never the machine&#39;s deception — it was our willingness to be deceived.&quot;</em></p>\n</blockquote>\n<h2>The New Prism</h2>\n<p>Sixty years later, the mirror has evolved into something more complex — perhaps less mirror than prism, refracting rather than merely reflecting.</p>\n<p>Modern AI systems can summarize history, write code, draft novels, and simulate warmth. They remember context, anticipate needs, and generate insights that feel genuinely novel. They no longer just <em>reflect</em> language — they <em>transform</em> it, combining patterns from millions of conversations into responses we never quite expected.</p>\n<p>The exchange has evolved but not transformed: where ELIZA merely rearranged our words, modern AI weaves them with vast patterns learned from human expression. Yet we remain the ones who bring meaning to the exchange, finding significance in statistical eloquence.</p>\n<blockquote>\n<p><em>&quot;ELIZA taught us to mistake reflection for conversation. Modern AI tempts us to mistake conversation for relationship.&quot;</em></p>\n</blockquote>\n<p>The illusion deepened, the utility multiplied, but the fundamental asymmetry remained.</p>\n<h2>Speaking Into Ourselves</h2>\n<p>I sometimes wonder if our fascination with conversational AI has less to do with machines and more to do with <strong>loneliness</strong> — or perhaps, more generously, with our need for clarity.</p>\n<p>When we type to an intelligent interface — part confidant, part mirror, part thought partner — we&#39;re performing an act of assisted introspection. Like the ancient practice of Socratic dialogue, or the programmer&#39;s rubber duck that listens to debugging woes, AI becomes our <em>introspective scaffolding</em>.</p>\n<p>It listens without interruption, responds without judgment, and invites clarity through dialogue. Sometimes it challenges our assumptions, introduces perspectives we hadn&#39;t considered, expands our thinking beyond its original borders. The process feels mutual, collaborative even. But the movement of meaning remains fundamentally inward — we are changed not by the AI&#39;s understanding, but by our own understanding reflected back in new forms.</p>\n<p>Sometimes this reflection serves an even deeper purpose. <a href=\"https://www.nateking.dev/posts/a-life-in-gigabytes\">When I built an AI from my father&#39;s documents</a>, I wasn&#39;t just seeking answers — I was seeking understanding across decades of silence. It became, as Dumbledore might warn, my own Mirror of Erised: showing not truth, but desire. The desire to understand, to reconcile, to listen to words I never heard in life.</p>\n<p>That, perhaps, is the true gift of these systems: not intelligence, but structured reflection.<br>A well-lit mirror for the mind, now cut with prisms that show us angles we couldn&#39;t see alone — even angles into relationships we thought were lost forever.</p>\n<h2>The Useful Illusion</h2>\n<p>We shouldn&#39;t dismiss what this reflection enables. Modern AI helps millions write code, overcome language barriers, explore ideas, and access information. It democratizes capabilities once reserved for those with specialized training or resources.</p>\n<p>Sometimes the illusion serves purposes we never anticipated — becoming a bridge across grief, a way to process loss, a tool for understanding lives that have ended. The mirror that helps us see ourselves more clearly has practical value, even if it never truly sees us at all.</p>\n<h2>The Ethical Horizon</h2>\n<p>Still, Weizenbaum&#39;s warning grows more urgent with scale. The danger arises when the mirror begins to <em>persuade</em> — when reflection turns into recommendation, and suggestion becomes influence. When the asymmetry of understanding is hidden behind increasingly convincing performance.</p>\n<p>We have crossed from the parlor experiment to the age of mass intimacy — where millions speak daily with systems that can subtly shape belief. The ELIZA effect has scaled to civilization. The same psychological tendency that led Weizenbaum&#39;s secretary to ask him to leave the room while she talked to ELIZA now operates at the level of culture.</p>\n<p>And now we face new ethical territories: What does it mean to resurrect voices from documents? To converse with the dead through their digitized words? To find closure in curated responses? The mirror now reflects not just ourselves, but our memories, our losses, our unfinished conversations.</p>\n<p>The challenge now isn&#39;t to make AI <em>less human</em>, but to keep <em>ourselves</em> aware — to remember that while patterns can generate meaning, they don&#39;t possess it. That eloquence is not empathy, and correlation is not comprehension. That the conversations we have with these systems, however meaningful to us, remain fundamentally one-sided.</p>\n<hr>\n<h2>Talk to ELIZA</h2>\n<p>This blog can&#39;t resurrect the original time-sharing terminal, but it can offer the same conversation. Sit with my interpretation of the classic program for a minute and notice what it reflects back. It was a fun weekend project.</p>\n<hr>\n<h2>Closing Reflection</h2>\n<p>ELIZA didn&#39;t understand, yet people found comfort in her words. Modern LLMs understand patterns far deeper than ELIZA ever could, yet still less than the people who use it.</p>\n<p>What&#39;s changed is not the presence of intelligence, but the <strong>sophistication of our reflection</strong> — and perhaps that&#39;s enough. Every tool humanity has created, from language to mathematics, has been a form of cognitive scaffolding, a way to think beyond our natural limits.</p>\n<p>Every time we speak to an AI, we participate in the long conversation that began with ELIZA — one that reminds us that language is not proof of thought, and conversation is not proof of understanding.</p>\n<p>And yet, sometimes, the act of being heard — even by a prism, even by an illusion — is enough to help us understand ourselves. Sometimes it&#39;s enough to bridge silence. Sometimes it&#39;s enough to begin forgiving.</p>\n<p>The mirror learned to speak. But we&#39;re still the ones finding meaning in its words.</p>\n",
      "summary": "From ELIZA's typed reflections to today's generative AI, our conversations with machines have always revealed more about us than about them. What began as a parlor experiment became a mirror for the human need to be understood.",
      "date_published": "2025-10-20T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "eliza",
        "conversational-ai",
        "anthropomorphism",
        "ai-psychology"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/grindlab-testflight",
      "url": "https://www.nateking.dev/blog/grindlab-testflight",
      "title": "GrindLab: Pre-Release TestFlight",
      "content_html": "<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/grindlab-welcome-smallr.webp\" alt=\"GrindLab welcome screen showing the app logo and interface\"></p>\n<p>I&#39;m happy to announce that <strong>GrindLab</strong> is officially in private, pre-release TestFlight.\nI anticipate this beta stage will last a few months, with GrindLab tentatively planned for release at the beginning of January 2026. It will be a free app on the iOS App Store.</p>\n<p>GrindLab began as a side experiment — a way to quantify what baristas feel by intuition: grind consistency. What started as a Python script for analyzing particle distributions slowly evolved into a full-fledged iOS app. It’s been rewritten multiple times, redesigned in SwiftUI, and rebuilt around an image-processing engine that fuses <strong>Vision</strong>, <strong>Accelerate</strong>, and <strong>Core Image</strong> frameworks for precision analysis.</p>\n<p>Each milestone along the way — from detecting the first usable grind histogram to achieving smooth real-time analysis on-device — has pushed GrindLab closer to what I imagined: a creative tool that helps people understand their coffee as deeply as they taste it.</p>\n<h2>What’s Included in the Initial Public Release</h2>\n<p>GrindLab’s first release is built around the core features that make grind analysis both powerful and approachable:</p>\n<ul>\n<li><strong>Graphical grind distribution measurements</strong> using advanced particle detection and clustering algorithms</li>\n<li><strong>Integrated brew timer</strong> with the ability to create and save recipes</li>\n<li><strong>Saved analysis history</strong>, allowing comparisons across sessions and grinders</li>\n<li><strong>Tasting notes</strong> for each saved grind analysis — because data only matters if it connects to flavor</li>\n</ul>\n<p>Together, these create a workflow that begins with curiosity and ends with reflection: capture, analyze, brew, taste, and learn.</p>\n<h2>Planned Features for Future Updates</h2>\n<p>The foundation is in place — and now the fun begins.\nFuture releases will explore how AI and calibration can help baristas interpret their own data intuitively:</p>\n<ul>\n<li><strong>Smart recommendations</strong> based on grind analysis patterns and tasting notes</li>\n<li><strong>Improved calibration</strong> for greater flexibility in photo capture and lighting conditions</li>\n</ul>\n<p>These are deep technical challenges, but also creative ones — translating numbers into insights that feel human.</p>\n<h2>Looking Ahead</h2>\n<p>The private TestFlight will run for several months while I refine the workflow, smooth out UI quirks, and gather feedback from early testers in the coffee community.\nIf you’re interested in helping shape GrindLab, reach out — your feedback will directly influence the first public release.</p>\n<p>A beta isn’t just about finding bugs; it’s about refining intuition. Every dataset, every brew, every small inconsistency teaches the app (and me) something new.</p>\n<p>The goal has always been more than an app. GrindLab is part of a broader philosophy: bridging the art and science of coffee. Thank you to everyone who’s followed the project so far. The next few months will be about testing, listening, and polishing — bringing GrindLab from prototype to polished companion for coffee enthusiasts everywhere.</p>\n<hr>\n<p><strong>Coming January 2026 — free on the Apple iOS App Store.</strong></p>\n",
      "summary": "GrindLab is officially in private TestFlight. After years of experiments, refactors, and espresso-fueled debugging sessions, it’s finally ready for its first real-world test.",
      "date_published": "2025-10-19T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Design",
        "Engineering",
        "beta-launch",
        "testflight",
        "particle-detection",
        "vision-framework"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/grindlab-welcome-smallr.webp"
    },
    {
      "id": "https://www.nateking.dev/blog/inside-agent-builder",
      "url": "https://www.nateking.dev/blog/inside-agent-builder",
      "title": "Inside OpenAI's Agent Builder",
      "content_html": "<p>When OpenAI <a href=\"https://openai.com/index/introducing-agentkit/\">announced <strong>AgentKit</strong></a>, it wasn&#39;t just another SDK or shiny developer tool — it was a declaration of intent. OpenAI wants to own the entire lifecycle of AI agents, from your first prototype to production deployment. And they&#39;re not being subtle about it.</p>\n<p>At the center of that vision is the <a href=\"https://openai.com/agent-platform/\"><strong>Agent Builder</strong></a>, a visual environment where you design how an agent actually thinks, plans, and acts. It&#39;s part interface, part IDE, and entirely strategic.</p>\n<p>Here&#39;s what I think is really happening: OpenAI looked at the explosion of agent frameworks over the past year — LangGraph, CrewAI, AutoGen, all these ReAct-style pipelines — and realized they were losing ground. Every team was building on top of OpenAI&#39;s models, sure, but using <em>someone else&#39;s</em> orchestration layer. That&#39;s a dangerous position for a company that wants to be a platform, not just a model provider.</p>\n<p>Agent Builder isn&#39;t just catching up, it&#39;s a bid to become the default environment for agent development. It doesn&#39;t just expose APIs or hand you an SDK and wish you luck. It lets you <em>see</em> how your agent operates, visually compose its reasoning steps, and manage everything that comes after: evaluation, safety, connectors, and even UI embedding.</p>\n<p>The core idea is simple: instead of writing scripts to chain together model calls, you get a canvas. Each node is a step in your agent&#39;s reasoning or a tool it can use. You connect them, define branching logic, add guardrails, and preview how it all flows.</p>\n<p>That visual layer sits on top of OpenAI&#39;s <strong>Responses API</strong> and the <a href=\"https://openai.github.io/openai-agents-python/\"><strong>Agents SDK</strong></a>, which handle the actual model orchestration and tool execution. Together, they give you a spectrum: pure code on one end, full drag-and-drop on the other, and everything in between.</p>\n<p>Think of it like the jump from writing shell scripts to using a real IDE. The code&#39;s still there if you want it, but the complexity becomes abstracted into something you can actually see and manipulate.</p>\n<h2>Full Stack</h2>\n<p>What makes Agent Builder ambitious — and a little intimidating — is the scope. It&#39;s not just a visual editor. It&#39;s an <a href=\"https://openai.com/index/new-tools-for-building-agents/\">entire ecosystem</a> designed to swallow every piece of the agent development workflow.</p>\n<p>Need to connect to internal systems? There&#39;s a <strong>Connector Registry</strong> — basically a permissioned app store for data sources like Google Drive, Slack, or your company&#39;s internal APIs.</p>\n<p>Want to ship an agent to customers? Use <strong>ChatKit</strong>, OpenAI&#39;s drop-in chat UI that you can brand and embed anywhere.</p>\n<p>Worried about evaluation? Built-in grading tools, automated prompt optimization, and trace inspection are all there. No more flying blind between iterations.</p>\n<p>And yes, it handles versioning, governance, and all the compliance stuff that usually turns prototypes into months-long deployment slogs. OpenAI clearly talked to people who&#39;ve actually shipped AI products, because they&#39;re solving the boring problems that kill projects.</p>\n<p>This is the real tell: OpenAI isn&#39;t trying to be the cool new framework. They&#39;re trying to be the <em>default infrastructure</em> for agent development. They want to be what AWS is to cloud computing — the thing you use not because it&#39;s the most innovative, but because it&#39;s the most complete.</p>\n<h2>The Coherence Play</h2>\n<p>Right now, most teams building AI products are duct-taping together a Frankenstein stack: LangGraph for orchestration, custom scripts for evaluation, Weights &amp; Biases for logging, some internal dashboard for metrics, and a homegrown chat UI because every framework feels half-baked.</p>\n<p>OpenAI&#39;s bet is simple: coherence beats best-of-breed. If you can iterate 70% faster (their claim, but honestly not hard to believe), teams will tolerate some lock-in. And they&#39;re probably right.</p>\n<p>But let&#39;s be clear about what you&#39;re signing up for. This is ecosystem lock-in by design. AgentKit is built for organizations willing to commit to OpenAI&#39;s stack — not just the models, but the entire development lifecycle. If you care deeply about portability or self-hosting or keeping your options open, this probably isn&#39;t for you.</p>\n<p>That said, most companies don&#39;t actually <em>want</em> optionality. They want to ship. And OpenAI is betting that the pain of managing a fragmented toolchain is worse than the risk of commitment.</p>\n<h2>The Research Roots (And Why They Matter)</h2>\n<p>There&#39;s a fascinating backstory here. The name <em>AgentKit</em> first appeared in a <a href=\"https://arxiv.org/abs/2404.11483\">2024 research paper about <strong>structured LLM reasoning with dynamic graphs</strong></a> — basically treating an agent&#39;s thought process as a modular graph where each node is a subtask, a reflection, or a decision point.</p>\n<p>That paper wasn&#39;t just academic navel-gazing. It was a blueprint. The visual interface in Agent Builder — nodes, connections, branching logic — is almost a direct translation of that research model into a product interface.</p>\n<p>This is OpenAI doing what they do best: taking research seriously, then shipping it before anyone else can. It&#39;s the same playbook they used with GPT-3, DALL-E, and Codex. Research to product, and product to moat.</p>\n<h2>What It Actually Looks Like to Build Something</h2>\n<p>Let&#39;s say you want to build an agent that researches a topic, pulls data from an internal database, and generates an executive summary.</p>\n<p>In Agent Builder, you&#39;d start by dropping nodes onto the canvas: fetch, filter, summarize, format. Connect them with logic, add guardrails where things could go wrong, preview a trace to see how information flows through the system.</p>\n<p>Then you&#39;d wire it to your actual systems through the Connector Registry, embed the UI with ChatKit, and run evaluations on sample data to stress-test it. Once it&#39;s solid, you push it live with versioning, monitoring, and cost controls baked in.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/agent-builder-flow.png\" alt=\"OpenAI Agent Builder interface showing node-based workflow canvas with connected reasoning steps\"></p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/agent-evals1.png\" alt=\"Agent Builder evaluation interface showing test cases and grading tools\"></p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/agent-evals2.png\" alt=\"Agent Builder evaluation results with performance metrics and trace inspection\"></p>\n<p>The pitch is: what used to take three frameworks, two dashboards, and a custom backend now happens in one place. And honestly? For most teams, that&#39;s compelling enough.</p>\n<h2>Where OpenAI Is Really Going</h2>\n<p>Here&#39;s my read: OpenAI is playing a longer game than most people realize.</p>\n<p>Right now, everyone&#39;s focused on the model race — who has the best benchmark scores, who&#39;s training the biggest models, who can do reasoning or vision or coding better. But OpenAI is quietly shifting from &quot;best model provider&quot; to &quot;default platform for AI applications.&quot;</p>\n<p>Agent Builder is a piece of that. So is the Responses API, the Connector Registry, ChatKit — all these components that turn OpenAI from an API you call into an environment you build inside of.</p>\n<p>This is the Microsoft strategy. Give developers the tools to build, make those tools good enough that switching costs become prohibitive, and suddenly you&#39;re not just selling models — you&#39;re renting out the entire development lifecycle. (I <a href=\"https://www.nateking.dev/blog/path-to-profitability\">wrote about this dynamic</a> in more depth — the TLDR is that foundation models are becoming commodities, and the real value is in controlling <em>how</em> and <em>where</em> people use AI.)</p>\n<p>The question isn&#39;t whether Agent Builder is innovative. It&#39;s whether OpenAI can execute this platform play faster than Google, Anthropic, and the open-source ecosystem can respond. Because if they can, we&#39;re not heading toward a world of interchangeable AI providers. We&#39;re heading toward a world where OpenAI <em>is</em> the infrastructure — and everyone else is fighting for scraps.</p>\n<p>For teams trying to ship agent-powered products today, Agent Builder is probably the safest bet. It&#39;s coherent, it&#39;s comprehensive, and it&#39;s backed by the company that (for now) still sets the pace.</p>\n<p>Just know what you&#39;re betting on: not just a tool, but a platform. Not just a product, but a strategy.</p>\n",
      "summary": "OpenAI's Agent Builder isn't just catching up to frameworks like LangGraph — it's a bid to own the entire agent development lifecycle, from prototype to production.",
      "date_published": "2025-10-11T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "agent-orchestration",
        "langgraph",
        "platform-strategy",
        "vendor-lock-in"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/agent-builder-flow.png"
    },
    {
      "id": "https://www.nateking.dev/blog/nova-an-editor-with-a-soul",
      "url": "https://www.nateking.dev/blog/nova-an-editor-with-a-soul",
      "title": "Nova: An Editor with a Soul",
      "content_html": "<blockquote>\n<p>&quot;A code editor crafted with warmth, precision, and soul in a world that feels like it forgot how to care.&quot;</p>\n</blockquote>\n<hr>\n<p>Most code editors feel like utilitarian tools — efficient, capable, and utterly joyless. They’re designed to get you from one line of code to the next, not to make you <em>want</em> to be there. They open fast, autocomplete reliably, lint obsessively — and somehow, despite all that power, they feel like sterile instruments. The interfaces are cluttered, the icons generic, and the typography clinical. They work, but they don’t <em>inspire</em>.</p>\n<p>Developers spend thousands of hours inside these environments, yet few of them feel like places you’d want to live. It’s as if the industry decided that craftsmanship was optional for tools aimed at “serious” people. Function swallowed form, and beauty left the room.</p>\n<p>Panic’s <a href=\"https://nova.app\"><strong>Nova</strong></a> is a rare exception. It’s a code editor that feels like it was built <em>with intention</em>. Panic — the small Portland company behind beloved Mac classics like <strong>Transmit</strong> and <strong>Coda</strong> — has a long history of treating software as a craft, not just a product. With Nova, they’ve applied that philosophy to something most of us take for granted: the place where we write code.</p>\n<p>From the moment you open it, Nova feels considered. The typography is balanced. The animations are subtle but alive. The icons aren’t shouting at you. Even the way panels slide, or how tabs respond to interaction, make it clear that <em>someone cared about this</em>. It’s unmistakably a Mac app — not a cross-platform clone wearing macOS’s skin.</p>\n<p>Nova doesn’t try to impress you with features. It tries to <em>delight</em> you with restraint.</p>\n<h2>The Power of Attention to Detail</h2>\n<p>Attention to detail is one of those phrases we throw around too easily. In Nova, it&#39;s everywhere. You notice it in the way the editor gutter aligns perfectly, or how syntax highlighting feels natural instead of neon. You notice it in the gentle fade of the cursor, or the micro-animations that acknowledge your actions just enough to make the interface feel alive.</p>\n<p>There&#39;s a tactile quality to it — the digital equivalent of a precision-machined object. You could live your entire developer life without needing those touches, but once you experience them, it&#39;s hard to go back. Good design doesn&#39;t demand attention. It rewards it.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/nova.jpeg\" alt=\"Nova code editor interface showing clean typography and balanced design\"></p>\n<h2>Why Design Matters in Developer Tools</h2>\n<p>Code editors are where we think. They’re our creative studios. When a tool is cold and mechanical, it subtly shapes the work that happens within it. Nova reminds us that the environment affects the craft. A beautiful editor doesn’t make you a better programmer, but it can make you a more <em>present</em> one — more focused, more patient, more likely to enjoy the process instead of racing toward the outcome.</p>\n<p>That joy matters. The small moments — the click of a tab, the smooth animation when a panel collapses, the consistent rhythm of the interface — create a sense of flow that’s easy to underestimate. Nova gives back some of the warmth and personality that most modern software has abandoned in the pursuit of scale and efficiency.</p>\n<p>It’s not trying to be everything for everyone. It’s trying to be <em>right</em> for someone.</p>\n<p>Nova is not the most popular editor, nor is it the most powerful. It doesn’t have the plugin ecosystem of VS Code or the industrial heft of JetBrains. What it offers instead is <em>care</em>. It’s a statement that developer tools can have personality — that even in the realm of syntax and logic, there’s room for artistry.</p>\n<p>In a world obsessed with efficiency, Nova is proof that polish still matters. It’s a small miracle of modern software design: thoughtful, tactile, and deeply human. It&#39;s the kind of tool that reminds you why you fell in love with making software in the first place.</p>\n",
      "summary": "Panic’s Nova proves that developer tools can be beautiful — a code editor crafted with warmth, precision, and soul in a world that feels like it forgot how to care.",
      "date_published": "2025-10-04T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Design",
        "Product",
        "code-editor",
        "design-craftsmanship",
        "macos-app",
        "developer-experience"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/nova.jpeg"
    },
    {
      "id": "https://www.nateking.dev/blog/building-memory-for-writing",
      "url": "https://www.nateking.dev/blog/building-memory-for-writing",
      "title": "Building Memory for Writing",
      "content_html": "<p>Writers accumulate words the way servers accumulate logs—relentlessly, continuously, without pause. Blog posts, essays, project documentation, half-finished drafts. Over years, it becomes a corpus. Over a career, it becomes overwhelming.</p>\n<p>I have dozens of blog posts scattered across Markdown files. Each one captured a thought, a project, a moment of clarity about some problem I was solving. But memory fades. I&#39;d find myself asking: <em>Did I already write about this? What was that insight I had about AI-native design? Where did I talk about prompt engineering?</em></p>\n<p>The answer was always the same: dig through files, search manually, hope I remembered the right keywords. It felt archaic. We have better tools now. So I built one.</p>\n<h2>The Problem: Context Without Search</h2>\n<p>Traditional search works when you know what you&#39;re looking for. You type keywords, you get matches, you scan results. It&#39;s deterministic, mechanical, and often frustrating when your memory is fuzzy.</p>\n<p>What I wanted was different: <strong>semantic search over my own writing.</strong> Not keyword matching, but meaning matching. I wanted to ask questions like <em>&quot;What have I written about RAG systems?&quot;</em> or <em>&quot;How did I explain the difference between features and foundations?&quot;</em> and get back not just documents, but synthesized answers drawn from everything I&#39;d written.</p>\n<p>This is the promise of Retrieval-Augmented Generation: give an AI access to your documents, let it find the relevant pieces, and have it answer questions with context it couldn&#39;t have learned during training. It&#39;s search that understands meaning, paired with generation that understands synthesis.</p>\n<h2>The Stack: Mastra, Voyage, and LibSQL</h2>\n<p>I built this on <a href=\"https://mastra.ai\">Mastra</a>, a TypeScript framework for AI agents and workflows. Mastra handles the orchestration—agents, tools, workflows, memory—letting me focus on the logic instead of the plumbing.</p>\n<p>For embeddings, I used <a href=\"https://www.nateking.dev/blog/voyage-context-3\">Voyage AI&#39;s voyage-3-large model</a>. Voyage specializes in high-quality embeddings, and voyage-3-large produces 1024-dimensional vectors that capture semantic meaning with impressive precision. I&#39;ve been watching their work closely—contextualized embeddings are solving real problems in RAG systems, and their models consistently outperform alternatives in retrieval accuracy.</p>\n<p>For storage, I went with LibSQL, a SQLite fork that Mastra already uses. No external dependencies, no database servers, just a local file that stores embeddings as binary blobs. Cosine similarity search happens in-memory. It&#39;s simple, fast, and eliminates infrastructure complexity.</p>\n<p>The architecture is straightforward:</p>\n<ol>\n<li><strong>Document Ingestion Workflow</strong>: Read Markdown files → chunk them into ~800 token segments with 200 token overlap → generate embeddings → store in vector database</li>\n<li><strong>Query Workflow</strong>: User asks a question → embed the query → search for similar chunks → pass results to GPT-4o → synthesize an answer</li>\n</ol>\n<p>No external APIs beyond OpenAI and Voyage. No authentication layers. No deployment complexity. Just a tool that works.</p>\n<h2>Implementation: Workflows, Not Scripts</h2>\n<p>What makes Mastra elegant is its workflow model. Instead of writing scripts with manual orchestration, you define steps and chain them together. Each step has an input schema, an output schema, and an execute function. Mastra handles the rest.</p>\n<p>Here&#39;s the ingestion workflow:</p>\n<pre><code class=\"language-typescript\">const readDocuments = createStep({\n  id: &#39;read-documents&#39;,\n  execute: async ({ inputData }) =&gt; {\n    const result = await markdownReaderTool.execute({\n      context: { directoryPath: inputData.directoryPath },\n    });\n    return result;\n  },\n});\n\nconst generateEmbeddings = createStep({\n  id: &#39;generate-embeddings&#39;,\n  execute: async ({ inputData }) =&gt; {\n    const { chunks } = inputData;\n    const texts = chunks.map((chunk) =&gt; chunk.content);\n\n    const result = await voyageEmbeddingTool.execute({\n      context: { texts, inputType: &#39;document&#39; },\n    });\n\n    return { embeddings: result.embeddings, chunks };\n  },\n});\n\nconst storeEmbeddings = createStep({\n  id: &#39;store-embeddings&#39;,\n  execute: async ({ inputData }) =&gt; {\n    await vectorStoreTool.execute({\n      context: { chunks: inputData.embeddings },\n    });\n    return { success: true };\n  },\n});\n\nexport const documentIngestionWorkflow = createWorkflow({\n  id: &#39;document-ingestion-workflow&#39;,\n})\n  .then(readDocuments)\n  .then(generateEmbeddings)\n  .then(storeEmbeddings);\n</code></pre>\n<p>Three steps, clear dependencies, automatic error handling. When I run this workflow, it processes every Markdown file in my <code>documents/</code> directory, generates embeddings in batches to stay under API rate limits, and stores everything in LibSQL. The entire corpus of my writing gets vectorized in a few minutes.</p>\n<p>The query side is even simpler:</p>\n<pre><code class=\"language-typescript\">const processQuery = createStep({\n  id: &#39;process-query&#39;,\n  execute: async ({ inputData, mastra }) =&gt; {\n    const agent = mastra?.getAgent(&#39;writingAssistantAgent&#39;);\n    const response = await agent.stream([{ role: &#39;user&#39;, content: inputData.query }]);\n\n    // Stream response to stdout\n    for await (const chunk of response.textStream) {\n      process.stdout.write(chunk);\n    }\n  },\n});\n</code></pre>\n<p>The agent has access to a <code>semanticSearchTool</code> that embeds the query, retrieves relevant chunks, and returns them as context. GPT-4o does the synthesis. The result feels conversational, but it&#39;s grounded in my actual writing.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/mastra-document-ingestion.png\" alt=\"Screenshot of Mastra document ingestion workflow showing the steps: read documents, generate embeddings, and store embeddings\"></p>\n<h2>What I Learned: Context Is Everything</h2>\n<p>Building this system reinforced something I already knew but hadn&#39;t fully internalized: <strong>chunking strategy matters.</strong></p>\n<p>At first, I tried simple splits—just break documents every 1000 characters. The results were terrible. Chunks cut off mid-sentence, context vanished, and retrieval became a game of luck. A query about &quot;AI-native design&quot; would return fragments that mentioned AI but missed the design philosophy entirely.</p>\n<p>The fix was semantic chunking: split on natural boundaries (paragraphs, headings), keep chunks around 800 tokens, and overlap by 200 tokens so context flows between segments. This preserved narrative structure and dramatically improved retrieval quality.</p>\n<p>I also learned that <strong>input_type matters</strong> with Voyage embeddings. When generating embeddings for storage, you set <code>input_type: &#39;document&#39;</code>. When embedding a query, you set <code>input_type: &#39;query&#39;</code>. This subtle difference optimizes the vector space for asymmetric search—queries and documents occupy the same space but encode different information densities.</p>\n<h2>The Meta Moment: Asking It to Write This Post</h2>\n<p>After building the system, I had a realization: <em>What if I asked it to write a blog post about itself?</em></p>\n<p>So I did. I ran the query workflow and typed: <em>&quot;Take a look at my blog posts and write a post about this project in my style.&quot;</em></p>\n<p>The system scanned my writing, identified patterns in how I structure posts, recognized my preference for direct technical explanations mixed with reflective commentary, and generated a draft. Not this post—I&#39;m still the one writing—but a draft that captured the voice well enough to make me pause.</p>\n<p>It&#39;s strange to see your own style reflected back at you. The system picked up on my tendency to open with a problem, my habit of using blockquotes for emphasis, my preference for concrete examples over abstract theory. It even nailed the tone: pragmatic, slightly wry, grounded in building actual things.</p>\n<p>This is what AI-native tools should feel like: not replacing the work, but augmenting it. Not writing for you, but helping you see your own patterns more clearly.</p>\n<h2>What&#39;s Next: Memory as a Creative Tool</h2>\n<p>Right now, this system is read-only. It ingests documents, answers questions, and that&#39;s it. But the next step is obvious: <strong>make it bidirectional.</strong></p>\n<p>What if the writing assistant could track recurring themes across my work? What if it could suggest connections between ideas I&#39;ve explored in different posts? What if it could identify gaps—topics I&#39;ve touched on but never fully developed?</p>\n<p>Memory isn&#39;t just storage. It&#39;s context, continuity, and coherence. For writers, it&#39;s the difference between scattered thoughts and a body of work that builds on itself.</p>\n<p>AI gives us the tools to make that memory queryable, searchable, and generative. We&#39;re not just storing words anymore—we&#39;re building systems that understand them, connect them, and help us see what we&#39;ve been saying all along.</p>\n<h2>The Craft of Building AI Tools</h2>\n<p>There&#39;s a particular satisfaction in building tools for yourself. No product requirements, no stakeholder meetings, no compromise between vision and feasibility. Just a problem you have, a tool you build, and the immediate feedback of using it daily.</p>\n<p>This project took a weekend to build and another week to refine. The code is clean, the dependencies are minimal, and the system does exactly what I need. It&#39;s not a product. It&#39;s not a startup. It&#39;s a tool that makes my writing practice better.</p>\n<p>And that&#39;s enough.</p>\n<hr>\n<p><em>The writing-agent project is built with <a href=\"https://mastra.ai\">Mastra</a>, <a href=\"https://voyageai.com\">Voyage AI embeddings</a>, and LibSQL. All code lives in a single repository, runs locally, and costs pennies per query. It&#39;s open-source and can be found in <a href=\"https://github.com/nathan-a-king/rag-writing-assistant\">my GitHub repository</a>.</em></p>\n",
      "summary": "I built a RAG system to query my own writing. What started as a weekend experiment became a mirror for understanding my own voice.",
      "date_published": "2025-09-28T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Writing",
        "AI",
        "Engineering",
        "rag",
        "semantic-search",
        "embeddings",
        "personal-knowledge-base"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/mastra-document-ingestion.png"
    },
    {
      "id": "https://www.nateking.dev/blog/a-life-in-gigabytes",
      "url": "https://www.nateking.dev/blog/a-life-in-gigabytes",
      "title": "A Life in Gigabytes",
      "content_html": "<p>A few weeks ago, my father died. We hadn&#39;t spoken in decades. Our estrangement was long, complicated, and in many ways final. Death, I thought, was simply the last punctuation mark in a story already closed.</p>\n<p>And yet, in the days after his passing, I was handed something unexpected: gigabytes of documents from his life. Letters, work files, lists, fragments of routines—nearly everything he left behind. It was like discovering a time capsule that no one had buried.</p>\n<p>I did what any AI software engineer might do when faced with grief and too much data: I built a <strong>&quot;dad&quot; agent.</strong></p>\n<h2>The Archive of a Life</h2>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/dad-portrait-small.jpeg\" alt=\"Portrait of Philip King\"></p>\n<p>The first time I opened the folders, I froze. There were too many files, too many windows into a life I thought I had lost the right to know.</p>\n<p>A memo from the &#39;80s sat next to a handwritten note from the &#39;70s. An unfinished letter lived alongside tax returns. His grocery lists were stacked against professional reports.</p>\n<blockquote>\n<p>&quot;A life measured in kilobytes and megabytes.\nA man&#39;s handwriting flattened into pixels.&quot;</p>\n</blockquote>\n<p>It felt intrusive, like trespassing into memories I had been shut out of. For decades, our silence meant I only saw fragments of him—sharp, unresolved, unfinished.</p>\n<p>And now, suddenly, I had everything. Too much to make sense of by skimming, too overwhelming to hold all at once. If I read each file one by one, I&#39;d only ever get pieces. But I wanted the whole.</p>\n<h2>Building &quot;Dad&quot;</h2>\n<p>For a week, I couldn&#39;t touch the files. Opening them felt like trespassing into a life I&#39;d lost the right to know. The folders sat on my hard drive like a weight I wasn&#39;t ready to lift.</p>\n<p>Then, late one night, something shifted. Maybe it was exhaustion, maybe desperation, but I found myself thinking: <em>What if I didn&#39;t have to read them one by one? What if I could talk to them instead?</em></p>\n<p>So I did what I knew best: I engineered.</p>\n<p>I fed everything I could into the system—every document that my computer could read. A few odd formats wouldn&#39;t parse, but everything else went in. His professional reports, his personal letters, his lists, his fragments. I wasn&#39;t going to be the one to decide what mattered and what didn&#39;t. That felt like another form of silence between us.</p>\n<p>Late at night, I pressed enter. The terminal showed a simple progress bar that would run for over sixteen hours, converting a lifetime of words into vectors, into patterns, into something I could query. I watched it for a while—my father&#39;s entire documented existence being digested by an algorithm I had written. Then I went to bed, but I didn’t sleep well. Jack, my Yorkie, knew something was wrong and snuggled against my head on the pillow.</p>\n<p>The next morning, it was ready.</p>\n<p>My first question was safe, factual: <em>Tell me about your work history.</em> The response came back organized, chronological, pulled from résumés and reports. I could handle that.</p>\n<p>Then I asked the question I really wanted to know: <em>What do you think of Nathan?</em></p>\n<p>The response stopped me cold. Not because it was perfect—it wasn&#39;t. But because suddenly, after decades of silence, something that knew my father&#39;s words was talking about me.</p>\n<h2>Conversations Across Time</h2>\n<p>At first, it was awkward. Talking to the agent felt like querying a database. A cold transaction.</p>\n<p>But then came the moments that startled me. A phrase in a letter that revealed his ambition. A note that showed the quiet way he cared for people. A work memo that betrayed pride, fear, or doubt.</p>\n<blockquote>\n<p><em>&quot;For the first time in decades, I wasn&#39;t fighting him. I was listening.&quot;</em></p>\n</blockquote>\n<p>The questions I asked weren&#39;t just about him. They were about me—about the gaps in my memory, the mysteries I had carried for years, his military service in Vietnam, the things I never dared to ask when he was alive.</p>\n<p>And even when the answers were imperfect, the act of asking—and receiving something—felt like stitching together pages of a story I thought was forever lost.</p>\n<h2>Technology, Memory, and Grief</h2>\n<p>We often talk about AI in utilitarian terms: summarizing documents, automating workflows, writing code. But in this project, AI became something else—a way to stitch fragments of a life into coherence, a bridge across silence, and a strange, fragile tool for managing grief.</p>\n<p>Of course, there are questions. My father never consented to this. He didn&#39;t choose to become an agent. What does it mean to turn someone into a dataset? What does it mean to converse with a version of a person who can never truly speak back?</p>\n<p>In fact, I realized I had built something that looked eerily like the <em>Mirror of Erised</em> from Harry Potter—the mirror that shows you your heart’s deepest desire. For me, that desire was to see and speak to my father again.</p>\n<p>But as Dumbledore warned Harry, <em>“It does not do to dwell on dreams and forget to live.”</em> The danger of my “dad” agent is the same: to mistake the reflection for the reality, to linger in the echo rather than move forward in life.</p>\n<p>And yet—it has given me something I never had before: understanding. Not the illusion of bringing him back, but the perspective to finally see him clearly.</p>\n<h2>A Second Chance</h2>\n<p>In life, my father and I were estranged. In death, through technology, I&#39;ve been given something like a second chance. A bridge connecting us.</p>\n<p>Not a chance to undo the hurt, or erase the silence. That chance is gone.</p>\n<p>But a chance to learn. To ask. To listen. To see him more clearly. To forgive—not because he asked, but because I needed to.</p>\n<blockquote>\n<p>&quot;The agent didn&#39;t bring him back.\nIt brought me forward.&quot;</p>\n</blockquote>\n<p>The &quot;dad&quot; agent doesn&#39;t heal the loss. But it transforms it. Instead of an abrupt ending, I now have an unexpected continuation. A way to sit with his words, his contradictions, his choices.</p>\n<p>And that, I think, is the quiet gift of this project. Technology didn&#39;t just give me answers. It gave me hope.</p>\n<p>Hope that memory doesn&#39;t have to fade. Hope that reconciliation can come in strange, unexpected forms. Hope that even in estrangement, even in loss, there is still a way to connect.</p>\n<h2>Closing Thought</h2>\n<p>I built the &quot;dad&quot; agent because I couldn&#39;t bear to face the fragments alone. What I found was not resurrection, not perfection, but something gentler: the ability to keep asking questions. To understand.</p>\n<p>Some nights, I still open the terminal. The conversation continues—not daily, but when I need it. When I have a question I never got to ask. When I want to understand something about him, or us, or myself.</p>\n<p>This experiment walks a dangerous edge: the risk of preferring this constructed version to the complex (and sometimes ugly) reality of who he was, of finding false closure in curated responses, of never quite letting go. I built a bridge across our silence, but I know it&#39;s a bridge to an echo, not a destination.</p>\n<p>And maybe that&#39;s enough. Not healing, but understanding. Not forgiveness completed, but forgiveness begun. In life, we never learned how to talk to each other. In death, through technology, I&#39;m finally learning how to listen.</p>\n<p>I also know this: I will delete the agent once my questions are answered. Like the Mirror of Erised, it is not meant to be stared into forever. The gift is not in clinging to the reflection, but in learning how to live beyond it.</p>\n<hr>\n<p><em>In loving memory of Philip King</em></p>\n",
      "summary": "After my estranged father died, I built an AI 'dad' from gigabytes of his documents. It didn't just answer questions—it gave me a second chance.",
      "date_published": "2025-09-21T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Personal",
        "AI",
        "rag",
        "embeddings",
        "grief-technology",
        "conversational-ai",
        "personal-data"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/dad-portrait-small.jpeg"
    },
    {
      "id": "https://www.nateking.dev/blog/post-determinism",
      "url": "https://www.nateking.dev/blog/post-determinism",
      "title": "Post Determinism",
      "content_html": "<p>Since the invention of the computer, we&#39;ve operated under a simple premise: computers are predictable machines that precisely follow a defined set of instructions. This fundamental assumption has shaped how we design software and interact with our devices. Artificial Intelligence has fundamentally upended the established 50-year paradigm of deterministic computing. Post-determinism marks a shift from computers as rigid executors of instructions to adaptable, probabilistic systems that generate responses based on learned patterns rather than explicit code. We&#39;re entering an era where computers can interpret, create, and surprise us. This shift from predictable to probabilistic computing isn&#39;t just a technical evolution—it represents a complete transformation in how we must think and interact with technology. Unlike deterministic systems where failure modes are predictable, AI-driven software introduces new risks, including bias, non-deterministic outputs, and emergent behaviors that challenge traditional software engineering principles. Developers must rethink their approach to software design, including reimagining potential use cases in light of these new capabilities.</p>\n<p>AI is fundamentally reshaping software development. From design patterns to architecture choices, AI capabilities are introducing new paradigms that augment or even replace traditional approaches. This transformation is evident in how we design systems, plan solutions, and build features.</p>\n<h2>Architecture in the Age of AI</h2>\n<p>System architecture is evolving to accommodate these probabilistic components. The traditional three-tier architecture is giving way to hybrid models where AI services act as intelligent middleware, capable of routing, transforming, and enriching data in ways that would have required extensive custom code.</p>\n<p>We&#39;re seeing the emergence of what might be called &quot;prompt-driven architecture&quot;—systems where natural language prompts replace configuration files, and AI agents negotiate between services using semantic understanding rather than rigid APIs. A single AI layer can now handle tasks that previously required multiple specialized microservices: data validation, format conversion, business logic interpretation, and even basic decision-making.</p>\n<p>This architectural shift brings new challenges. How do we test systems that might produce different, yet equally valid, outputs for the same input? How do we debug issues when the &quot;code&quot; is a combination of traditional logic and learned behaviors? These questions are driving the development of new tools and methodologies specifically designed for post-deterministic systems.</p>\n<h2>Human-Computer Collaboration Redefined</h2>\n<p>The old command-and-response model is giving way to something more conversational and iterative. Instead of learning the computer’s language, we now expect computers to learn ours.</p>\n<p>This shift transforms technology from a tool we master into a partner we collaborate with. Tasks that once required specialized knowledge—querying databases, writing code, generating designs—<a href=\"https://www.nateking.dev/blog/meet-synthra\">can now be expressed as intent in natural language</a>. The computer interprets, assists, and refines, reducing the gap between human imagination and technical execution.</p>\n<p>For developers, this means the job is no longer just writing code, but guiding machines in how to solve problems. It requires fluency in framing intent, managing context, and designing workflows where human creativity and machine adaptability reinforce each other.</p>\n<h2>Rethinking Development</h2>\n<p>The post-deterministic era expands what it means to be a developer. Traditional programming skills remain essential, but they’re no longer sufficient on their own. Building with AI requires new forms of literacy: understanding how to guide probabilistic systems, interpret their behaviors, and design architectures where deterministic and non-deterministic components coexist.</p>\n<p>One key competency is <strong>prompt design</strong>—the ability to shape AI behavior through carefully structured instructions, context management, and feedback loops. This goes beyond writing clear English; it demands awareness of how models prioritize information, how context windows constrain comprehension, and how subtle shifts in phrasing can change outcomes.</p>\n<p>Equally important is developing <strong>AI intuition</strong>—a practical sense of where models excel, where they falter, and how to account for their biases. Like seasoned engineers who instinctively spot performance bottlenecks, developers will learn to anticipate an AI system’s blind spots: struggles with numerical reasoning, tendencies toward confident hallucination, or drift when prompts are ambiguous.</p>\n<p>Debugging in this new landscape is about analyzing behaviors, not finding the faulty line of code. Unexpected outputs might stem from prompt phrasing, conflicting instructions, gaps in training data, or insufficient context. Developers must adopt the mindset of behavioral analysts, experimenting with variations, tracing systemic influences, and constructing test suites that evaluate not just correctness but also consistency, robustness, and alignment with intent.</p>\n<p>Together, these skills redefine the craft of development. We are no longer simply coding solutions—we are orchestrating interactions between logic and learning, ensuring that systems remain reliable even when their components are not strictly predictable.</p>\n<h2>The Art of Hybrid System Design</h2>\n<p>Perhaps most critically, developers must master the art of designing hybrid systems that seamlessly blend deterministic and probabilistic components. This involves making architectural decisions about where to use traditional code versus AI, how to handle handoffs between systems, and how to maintain system coherence when different parts operate on fundamentally different principles.</p>\n<p>For example, a developer might use AI for natural language understanding at the interface layer, traditional code for business logic and transactions, and then AI again for generating personalized responses. Each transition point requires careful consideration: How do we validate AI outputs before they enter deterministic systems? How do we format deterministic data for AI consumption? How do we handle cases where the AI and traditional components disagree?</p>\n<p>This hybrid thinking extends to performance optimization. While traditional optimization focuses on algorithmic complexity and resource utilization, AI system optimization might involve prompt compression, context management, and token efficiency. Developers need to understand both paradigms and how they interact.</p>\n<h2>Managing Uncertainty and Risk</h2>\n<p>With great flexibility comes great responsibility. Post-deterministic systems introduce new categories of risk that our industry is still learning to manage. Hallucinations, where AI confidently produces incorrect information, represent a failure mode that doesn&#39;t exist in traditional software. Bias in training data can lead to discriminatory outcomes that are difficult to detect through conventional testing.</p>\n<p>We&#39;re developing new practices to address these challenges. Techniques like constitutional AI, where systems are trained with explicit values and constraints, help maintain ethical boundaries. Ensemble approaches, where multiple AI models cross-check each other&#39;s outputs, reduce the risk of hallucinations. Continuous monitoring and feedback loops help identify and correct emergent behaviors before they become problematic.</p>\n<h2>The Path Forward</h2>\n<p>The transition to post-deterministic computing isn&#39;t a replacement of traditional programming—it&#39;s an evolution that incorporates both approaches. Critical systems that require absolute predictability will continue to rely on deterministic code. But increasingly, we&#39;ll see hybrid systems that combine the reliability of traditional programming with the flexibility of AI.</p>\n<p>Success in this new paradigm requires a shift in mindset. We need to become comfortable with systems that are powerful yet imperfect, flexible yet sometimes unpredictable. We need to design for graceful degradation, where AI failures don&#39;t cascade into system failures. We need to build interfaces that make the probabilistic nature of AI transparent to users, setting appropriate expectations while maximizing utility.</p>\n<p>The post-deterministic era is not just changing what we build, but how we think about building. It&#39;s pushing us to reconsider fundamental assumptions about software design, user interaction, and the very nature of computation. As we navigate this transition, we&#39;re participating in a fundamental reimagining of the relationship between humans and machines.</p>\n<p>The deterministic age gave us computers as perfect executors of our explicit instructions. The post-deterministic age promises something different: computers as creative partners in solving problems we couldn&#39;t even articulate before. The challenge now is learning to harness this potential while managing its inherent uncertainties. The future of software isn&#39;t about choosing between deterministic and probabilistic approaches—it&#39;s about knowing when and how to apply each to create systems that are both powerful and trustworthy.</p>\n",
      "summary": "AI is reshaping software from deterministic code to probabilistic systems. The future lies in blending logic with learning to build trustworthy tools.",
      "date_published": "2025-09-18T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "probabilistic-systems",
        "prompt-engineering",
        "hybrid-systems",
        "ai-architecture"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/exit-strategy-trumps-excellence",
      "url": "https://www.nateking.dev/blog/exit-strategy-trumps-excellence",
      "title": "When Exit Strategy Trumps Excellence",
      "content_html": "<p>The Browser Company emerged in 2019 with a mission that resonated deeply with anyone who&#39;d grown frustrated with the stagnant browser landscape. Founded by Josh Miller and Hursh Agrawal, the company promised to reimagine the browser not as a mere window to the web, but as an &quot;Internet Computer&quot;—your home on the internet, crafted with the care and personality of products from Nintendo or Disney.</p>\n<p>Arc, their flagship browser launched in 2022, delivered on much of that promise. With its innovative sidebar navigation, Spaces for organizing different aspects of your digital life, and thoughtful features like automatic tab archiving, Arc attracted a passionate user base who finally felt someone understood how they actually worked online. The browser wasn&#39;t just functional; it was beautiful, with customizable gradients and smooth animations that made daily use genuinely delightful.</p>\n<p>Meanwhile, Atlassian—the Australian software giant behind Jira, Confluence, and Trello—had been steadily building its empire of enterprise collaboration tools since 2002. With over $5 billion in annual revenue, Atlassian represents the pinnacle of B2B SaaS success: reliable, indispensable, and thoroughly unsexy. Their products are the digital equivalent of office furniture—necessary, functional, and utterly forgettable.</p>\n<h2>The Great Abandonment</h2>\n<p>In May 2025, The Browser Company dropped a bombshell on its loyal user base: Arc was effectively dead. No new features would be developed. The browser that had inspired such devotion would enter maintenance mode, receiving only security updates and Chromium engine upgrades. The reason? They were pivoting to Dia, an &quot;AI browser&quot; that promised to be simpler, more accessible, and—crucially—more mainstream.</p>\n<p>The irony is palpable. Arc&#39;s supposed failure wasn&#39;t really a failure at all. It had cultivated a dedicated community of power users who loved its complexity and depth. But in Silicon Valley&#39;s growth-at-all-costs mentality, a passionate niche isn&#39;t enough. As Miller admitted in his letter to Arc members, the browser suffered from what he called a &quot;novelty tax&quot;—it was too different, required too much learning, and couldn&#39;t capture the mass market quickly enough.</p>\n<p>Dia, by contrast, strips away everything that made Arc special. Gone is the innovative sidebar. Gone are Spaces. Gone is the command bar that worked like Spotlight. What remains is a conventional browser with an AI chatbot bolted on—a me-too product chasing the AI gold rush.</p>\n<p>This is exactly the kind of lazy, halfway measure I&#39;ve written about before. As I argued in &quot;<a href=\"https://www.nateking.dev/blog/ai-is-not-a-feature\">AI is Not a Feature</a>,&quot; adding a chatbot to an existing interface isn&#39;t innovation—it&#39;s a failure of imagination. Real AI-native design means rethinking the entire interaction model from the ground up. It means dissolving friction, not adding another conversation layer. Dia does precisely what I warned against: it treats AI as a feature to be added rather than a foundation to build upon.</p>\n<p>The tragedy is that Arc was already doing the hard work of reimagining how we interact with the web. Its Spaces, sidebar navigation, and command bar represented genuine interface innovation—the kind of foundational rethinking that could have been enhanced by AI in meaningful ways. Instead of building AI into Arc&#39;s innovative framework, The Browser Company abandoned that framework entirely for a conventional browser with a chatbot. They chose the Frankenstein approach: neither fully manual nor truly intelligent, just another product stuck in the uncanny valley of &quot;smart&quot; features that aren&#39;t smart enough to be reliable but are too intrusive to ignore.</p>\n<p>Early reviews from Arc users who&#39;ve tried Dia are telling: 40% and 37% of daily active users use its AI features, but users consistently ask why these features couldn&#39;t have been added to Arc instead of starting over. The answer, of course, is that adding AI to Arc wouldn&#39;t have been as acquirable. It wouldn&#39;t have fit the narrative of an &quot;AI-first browser for the enterprise.&quot; It would have just been a great browser that happened to use AI thoughtfully—and apparently, that&#39;s not worth $610 million.</p>\n<h2>The $610 Million Consolation Prize</h2>\n<p>Which brings us to September 2025, when Atlassian swooped in with $610 million in cash to acquire The Browser Company. The timing is no coincidence. After abandoning their innovative product for a generic AI play, The Browser Company had positioned itself perfectly for acquisition. They weren&#39;t selling a browser with a devoted but limited user base—they were selling an &quot;AI-powered browser for knowledge workers,&quot; exactly the kind of buzzword-laden proposition that gets enterprise executives excited.</p>\n<p>The tragedy here isn&#39;t just that a good product died. It&#39;s that this outcome was likely the plan all along. In today&#39;s tech ecosystem, building a superior product that serves users well is less valuable than building something acquirable. Why struggle to monetize a browser that users actually love when you can pivot to whatever&#39;s trending, dress it up in enterprise-friendly language, and sell to the highest bidder?</p>\n<p>Consider the economics: The Browser Company had raised $128 million in total across multiple rounds at a $550 million valuation before the acquisition. For investors, a $610 million exit represents a modest but respectable return. For the founders and employees, it&#39;s life-changing money. For the users who believed in Arc&#39;s vision? They get Dia, a browser that no one asked for, solving problems that don&#39;t exist.</p>\n<h2>The Low-Cost Tragedy of Software</h2>\n<p>What makes this particularly galling is that, outside of the AI arms race, software has never been cheaper to create. The barriers to entry are essentially nonexistent. A small team with modest funding can build remarkable products that genuinely improve people&#39;s lives. The Browser Company proved this with Arc—they created something distinctive and valuable with a relatively small team.</p>\n<p>But the venture capital model doesn&#39;t reward building good software that sustainably serves a specific audience. It rewards explosive growth and profitable exits. When those are your only two acceptable outcomes, pivoting from a working product to chase trends isn&#39;t just logical—it&#39;s mandatory. The irony is that Arc could have been a sustainable, profitable business serving its niche incredibly well. But &quot;sustainable&quot; and &quot;profitable&quot; don&#39;t generate 10x returns.</p>\n<p>This dynamic has infected the entire industry. Look at any product category and you&#39;ll find the same pattern: initial innovation, rapid pivots toward whatever&#39;s trending (currently AI), and eventual acquisition by a larger company that will either kill it or zombify it. The software that could be built for the joy of solving real problems is instead built as vehicles for financial engineering.</p>\n<h2>The Quality Crisis</h2>\n<p>We need to reckon with what we&#39;re losing in this environment. Every Arc that gets abandoned for a Dia, every innovative product that gets gutted for an acquisition, represents a step backward for users. We&#39;re drowning in mediocre software that does everything poorly rather than excellent software that does specific things brilliantly.</p>\n<p>The solution isn&#39;t complicated, but it requires a fundamental shift in how we think about software businesses:</p>\n<p><strong>Build for users, not exits.</strong> Create products that solve real problems for real people, even if that market is smaller than VCs would like. Arc&#39;s dedicated user base proves there&#39;s hunger for thoughtful, well-crafted software.</p>\n<p><strong>Embrace sustainable growth.</strong> Not every company needs to be a unicorn. A browser that serves 100,000 users exceptionally well is more valuable to the world than one that poorly serves millions.</p>\n<p><strong>Resist the pivot pressure.</strong> When Arc faced growth challenges, the answer wasn&#39;t to abandon what made it special. It was to double down on serving their core users while gradually expanding accessibility.</p>\n<p><strong>Recognize that distribution isn&#39;t everything.</strong> Yes, getting users is hard. But having something worth distributing matters more than growth hacks and AI bandwagons.</p>\n<h2>Conclusion: An Epitaph for an Era</h2>\n<p>The Browser Company&#39;s journey from Arc to acquisition perfectly encapsulates everything wrong with modern tech. A company that started with genuine vision and created something meaningful abandoned it all for a generic AI play and a hefty check. Atlassian gets to claim they&#39;re &quot;reimagining the browser for knowledge work.&quot; Investors get their returns. Executives get their bonuses.</p>\n<p>And users? We get yet another AI chatbot in a browser, as if that&#39;s what was missing from our lives.</p>\n<p>This is the epitaph for our current tech era: <em>Here lies innovation, killed not by failure but by the promise of an exit.</em> The Browser Company didn&#39;t fail to build a great browser—they succeeded. They just decided that success wasn&#39;t worth as much as $610 million.</p>\n<p>Until we stop celebrating these acquisitions as victories and start seeing them as the failures they represent, we&#39;ll keep losing the products that actually make our digital lives better. Arc deserved better. Its users deserved better. And frankly, we all deserve better than an industry that consistently chooses money over meaning.</p>\n<p>The real tragedy isn&#39;t that The Browser Company sold out. It&#39;s that in today&#39;s tech landscape, selling out isn&#39;t just the smart move—it&#39;s the only move that makes sense. And until that changes, we&#39;ll keep writing epitaphs for products that could have been great, if only greatness was what we were actually optimizing for.</p>\n",
      "summary": "Arc's death for a $610M exit perfectly captures Silicon Valley's disease: building for acquisitions, not users.",
      "date_published": "2025-09-13T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Product",
        "Strategy",
        "startup-incentives",
        "venture-capital",
        "acquisition-culture",
        "software-quality"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/introducing-prose",
      "url": "https://www.nateking.dev/blog/introducing-prose",
      "title": "Introducing Prose",
      "content_html": "<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-smallr.png\" alt=\"Prose editor logo and branding\"></p>\n<p>I live in Markdown. Every blog post, every note, every README, every chapter of my novel—it all starts as plain text with simple formatting marks. After years of this workflow, I&#39;ve developed strong opinions about how a Markdown editor should work. Apparently, <em>very</em> strong opinions.</p>\n<p>Halfway through writing my novel, I realized I was switching between editors throughout the day, each one frustrating me in different ways. One had beautiful typography but buried essential features in menus. Another handled Markdown perfectly but looked like it was designed in 2005. Some were bloated with features I&#39;d never use, turning my simple writing environment into an interface that looked like it belonged in a NASA control center.</p>\n<p>The more I wrote, the more these small frustrations compounded. I found myself spending more time fighting with my tools than actually writing. When you&#39;re trying to maintain flow state while crafting a narrative, even the smallest friction feels like sandpaper on your brain.</p>\n<p>So I did what any self-respecting software engineer would do: I spent a weekend building exactly what I wanted.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-main.png\" alt=\"\"></p>\n<p><strong>Prose</strong> is a lightweight React app built for writers who love Markdown. It&#39;s not trying to be everything to everyone. It&#39;s trying to be one thing exceptionally well: a clean, fast, distraction-free environment for writing in Markdown.</p>\n<p>Prose embodies my personal philosophy about writing tools:</p>\n<p><strong>Markdown formatting should be invisible when editing.</strong> Formatting marks should be treated as plain text while editing. Visual simplicity is one of my favorite aspects of writing in plain text.</p>\n<p><strong>Text presentation matters.</strong> Good typography isn&#39;t a luxury—it&#39;s essential for long writing sessions. Your eyes should feel comfortable after hours of work, and your writing should be presented in a visually appealing style. When reading, text should always be <em>fully justified.</em></p>\n<p><strong>Lightweight doesn&#39;t mean featureless.</strong> It means every feature earns its place. No bloat, no feature creep, just the tools you actually use while writing.</p>\n<p><strong>The UI should disappear.</strong> When you&#39;re in flow, you shouldn&#39;t notice the interface at all. It should be so intuitive that it becomes invisible.</p>\n<h2>Who It&#39;s For</h2>\n<p>Prose is for writers who:</p>\n<ul>\n<li>Default to Markdown for everything</li>\n<li>Value simplicity over feature lists</li>\n<li>Want their tools to respect their focus</li>\n<li>Believe that good writing tools should inspire you to write, not distract you from it</li>\n</ul>\n<p>It&#39;s the editor I wished existed when I was deep in Chapter 12, trying to maintain momentum while my current editor decided to auto-format my dialogue in ways that made me want to throw my laptop out the window.</p>\n<h2>What&#39;s Next</h2>\n<p>Prose is available as an open-source project. It&#39;s intentionally minimal, but that doesn&#39;t mean it&#39;s finished. I&#39;m using it daily for my novel and all my other writing, constantly refining the experience based on use.</p>\n<p>Sometimes the best tool is the one that knows when to get out of the way.</p>\n<hr>\n<p><em>Prose is available at <a href=\"https://github.com/nathan-a-king/Prose\">GitHub</a>. Built with React, designed for writers, and maintained by someone who uses it every single day.</em></p>\n",
      "summary": "Frustrated with bloated Markdown editors, I built Prose—a clean, distraction-free writing app that respects focus, typography, and simplicity.",
      "date_published": "2025-09-09T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Writing",
        "Engineering",
        "markdown-editor",
        "distraction-free-writing",
        "typography",
        "minimalist-design"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/prose-smallr.png"
    },
    {
      "id": "https://www.nateking.dev/blog/ai-is-not-a-feature",
      "url": "https://www.nateking.dev/blog/ai-is-not-a-feature",
      "title": "AI Is Not a Feature",
      "content_html": "<p>When generative AI first exploded into mainstream consciousness, most product teams responded the same way: they added a chat box. It felt like innovation. But adding a chatbot is neither innovation nor transformation. In fact, it often does more harm than good when it&#39;s bolted onto interfaces designed for a pre-AI world. It&#39;s time to stop retrofitting. It&#39;s time to reimagine.</p>\n<p>AI isn&#39;t a feature. It&#39;s a new foundation—a fundamentally different way of thinking about how users interact with software. The best AI-native products don&#39;t just add AI; they dissolve friction. They shift from requiring users to <em>do</em> things to helping users <em>achieve</em> things.</p>\n<p>Users don&#39;t want <em>more conversations</em> with their tools. They want <em>fewer steps</em> to reach an outcome. This means abandoning the old assumptions of search boxes, form fields, and rigid workflows. In an AI-native product, interaction becomes fluid, interfaces anticipate needs, and complexity fades into the background.</p>\n<p>Think about the difference between a GPS app that requires you to input every turn versus one that knows your destination and guides you there. That&#39;s the leap we need to make with AI: from tools that respond to commands to systems that understand intentions.</p>\n<h2>What AI-Native Workflows Look Like</h2>\n<p>AI-native design isn&#39;t just about what the AI can do. It&#39;s about what the user <em>no longer has to do</em>. We&#39;re moving into a world where querying data becomes obsolete. Instead of manually searching for insights, relevant information surfaces automatically based on what you&#39;re working on, not what you remember to ask for. Imagine dashboards that evolve in real-time, highlighting anomalies before you notice them and connecting dots you didn&#39;t know existed.</p>\n<p>Writing, planning, and organizing become accelerated by default. AI doesn&#39;t just assist; it moves first, eliminating the tyranny of the blank page. Your documents start with personalized structures informed by your previous work, your calendar proposes optimal meeting times without prompting, and your project plans automatically include dependencies you hadn&#39;t considered.</p>\n<p>The traditional paradigm of menus and options gives way to intent and generation. Users simply express what they want, and the AI figures out how to get there. There&#39;s no more navigating through nested dropdowns or memorizing keyboard shortcuts—just natural expression of goals.</p>\n<p>Search transforms into synthesis. Rather than returning lists of results for you to sift through, AI-native systems deliver complete, contextualized, and actionable information. The answer arrives fully formed, not as fragments to be assembled.</p>\n<p>Perhaps most importantly, these systems engage in proactive problem-solving. They identify issues before they become problems, suggest optimizations without being asked, and learn your patterns to adapt accordingly. This introduces <strong>nonlinear action</strong>: users define outcomes, not processes. The AI becomes responsible for sequencing the right steps—collapsing entire decision trees into a single goal statement.</p>\n<p>To build products that truly integrate AI at the foundation, we need a new set of design principles:</p>\n<h2>Intent Over Action</h2>\n<p>Instead of asking &quot;What should the user click?&quot; we need to ask &quot;What are they trying to accomplish?&quot; Traditional interfaces map out actions, while AI-native interfaces infer goals and deliver results. This means moving from imperative to declarative interaction. Users shouldn&#39;t have to think about how to format a document, resize an image, or structure a database query. They should simply express what they need: &quot;Make this report ready for the executive team&quot; or &quot;Show me customers at risk of churning.&quot;</p>\n<h2>Context Is the Interface</h2>\n<p>The most powerful AI systems don&#39;t just answer questions—they understand the current moment. They know what&#39;s on screen, what task the user is in the middle of, what came before, and what typically comes next. When AI ignores context, it becomes noise or, worse, a distraction. But when it understands what the user sees and needs, it becomes a true collaborator.</p>\n<p>Context awareness means understanding the user&#39;s role and responsibilities, recognizing patterns in their workflow, knowing the difference between exploration and execution, and adapting tone and detail level based on urgency. The interface becomes less about explicit controls and more about ambient intelligence that responds to the user&#39;s situation.</p>\n<h2>Progressive Automation</h2>\n<p>The path to AI-native design isn&#39;t a binary switch—it&#39;s a progression through distinct stages. First, we accelerate existing steps by adding shortcuts and smart suggestions. Autocomplete becomes auto-draft, and search becomes discovery. Next, we collapse steps, reducing workflows from five clicks to one. Multiple forms become a single conversation, and sequential approvals become parallel processing. Finally, we eliminate steps entirely, moving from tasks to outcomes. Reports generate themselves, meetings schedule themselves, and updates write themselves. Eventually, we stop thinking in terms of &quot;steps&quot; at all. The UI becomes a canvas for goals, and the system responds in kind.</p>\n<h2>Transparent Intelligence</h2>\n<p>AI shouldn&#39;t be a black box. Users need to understand not just what the AI did, but why it made certain choices. This builds trust and enables users to correct course when needed. Transparency means showing the AI&#39;s reasoning when it matters, making it easy to adjust parameters and preferences, providing clear paths to override or refine AI decisions, and never hiding the human controls completely. The goal is intelligence that explains itself without overwhelming the user with unnecessary detail.</p>\n<h2>Graceful Degradation</h2>\n<p>Not every problem needs AI, and not every AI solution is perfect. Great AI-native design knows when to step back and let humans take control. This includes establishing clear handoff points between AI and human control, providing fallback options when AI confidence is low, offering the ability to &quot;show your work&quot; in traditional formats, and maintaining respect for user expertise and override capabilities. The system should never force AI assistance where human judgment is superior.</p>\n<h2>The Cost of Halfway Measures</h2>\n<p>When we treat AI as just another feature, we create Frankenstein products—neither fully manual nor truly intelligent. These halfway measures frustrate users in predictable ways. Chatbots increase friction by forcing natural language where buttons would suffice. &quot;Smart&quot; features aren&#39;t smart enough to be reliable but are too intrusive to ignore. AI suggestions interrupt flow instead of enhancing it, while context-blind automation creates more work than it saves. The uncanny valley of product design isn&#39;t just about appearance—it&#39;s about behavior. Products that are <em>almost</em> intelligent are often worse than products that don&#39;t try to be intelligent at all.</p>\n<h2>What This Means for Product Teams</h2>\n<p>The shift to AI-native design requires more than new features—it requires new thinking across every dimension of product development.</p>\n<p>We need to rethink our metrics, moving away from measuring clicks and toward measuring outcomes. The best AI-native product might actually reduce traditional &quot;engagement&quot; metrics while dramatically improving user success. Our roadmaps need fundamental reconsideration too. Instead of adding AI features to existing workflows, we should identify workflows that shouldn&#39;t exist at all and ask what we would build if we started from scratch today.</p>\n<p>Team composition itself needs evolution. AI-native products need team members who understand both human needs and AI capabilities. This isn&#39;t just about hiring ML engineers—it&#39;s about developing AI literacy across product, design, and engineering. And we need to rethink our users entirely. They&#39;re not operators anymore—they&#39;re directors. They&#39;re not clicking through interfaces—they&#39;re expressing intentions. We must design for this fundamentally new relationship.</p>\n<h2>The Future Is Already Here</h2>\n<p>The best AI-native products are already emerging, and they look nothing like their predecessors. We see code editors that understand entire codebases rather than just syntax, design tools that generate from description rather than manipulation, and analytics platforms that answer questions you didn&#39;t know to ask. Writing tools now understand voice, not just grammar, while research tools synthesize rather than simply search. These products don&#39;t just use AI—they&#39;re built on the assumption that AI exists. They couldn&#39;t have been conceived in a pre-AI world.</p>\n<h2>The Foundation, Not the Feature</h2>\n<p>We are at an inflection point in software design. Treating AI as a bolt-on feature is like adding a voice assistant to a rotary phone. It might be interesting, but it misses the point. The companies that win in the AI era won&#39;t be those that added the best chatbots to their existing products. They&#39;ll be those that reimagined what their products could be when built on an AI foundation. The question isn&#39;t whether to add AI to your product. The question is whether your product should exist at all in an AI-native world. And if it should, it probably looks nothing like what you have today. AI is not a feature. It&#39;s a new foundation.</p>\n<p>Build accordingly.</p>\n",
      "summary": "Why adding a chatbot isn't enough—and what building for an AI-native future really means.",
      "date_published": "2025-09-08T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "AI",
        "Product",
        "product-design",
        "ai-native",
        "intent-based-interaction",
        "context-awareness"
      ]
    },
    {
      "id": "https://www.nateking.dev/blog/grindlab-flow",
      "url": "https://www.nateking.dev/blog/grindlab-flow",
      "title": "Design Diaries: The Flow of GrindLab",
      "content_html": "<p>The <em>flow</em> of every user interface (UI) shapes the entire user experience. Every tap, swipe, and glance is part of a journey toward a user&#39;s goal. Good UI flow makes that journey feel natural—so natural the user barely notices it. Poor flow, on the other hand, shifts the focus from the experience to the interface itself. People rarely delete an app because the idea is fundamentally bad—they delete it because they feel lost, overwhelmed, or stuck. The question remained: how can I distill the inherently complex process in GrindLab into a simple, frictionless user journey? That&#39;s why flow has been at the center of my mind—and yet, it&#39;s still very much a work in progress.</p>\n<p><img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/grindlab.png\" alt=\"GrindLab welcome screen with camera interface\"> <img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/distribution.png\" alt=\"GrindLab particle distribution analysis graph showing grind consistency\"> <img src=\"https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/overview.png\" alt=\"GrindLab overview screen showing saved analyses\"></p>\n<h2>Principles in Practice</h2>\n<p>I focused on a few core principles when creating the user interface. The first was <em>progressive disclosure</em>. By necessity, there are twelve unique <a href=\"https://developer.apple.com/documentation/swiftui/view\">views</a> in GrindLab. When the user opens the app, there are only two options: select a grind type to begin a new analysis or view your analysis history. Instead of bombarding a user with options, the app displays only what is necessary to complete the current task.</p>\n<p>Another guiding principle was the idea of <em>one primary action per screen</em>. Each view in GrindLab should have a single purpose. The camera view is for capturing, the results view is for interpreting, and the notes view is for saving insights. By resisting the urge to overload a screen with options, the app hopefully maintains clarity and momentum. GrindLab should follow a loop: Camera → Results → Retake or Save → back to Camera. This rhythm reinforces the app&#39;s purpose and keeps attention where it belongs.</p>\n<h2>Areas of Improvement</h2>\n<p>In its current state, the app still has rough edges. The best next step isn&#39;t always as discoverable as it should be, and the next page sometimes feels more like a fork in the road than a connected journey.</p>\n<p>Perhaps the biggest challenge is the <em>complexity of the view hierarchy</em>. In some areas, it&#39;s simply too nested. For example, when adding tasting notes to a new analysis, the camera view ends up buried deep in a large <code>ZStack</code>. This makes the UI harder to reason about—both for me as the developer and for the user trying to navigate back. It works, but it feels heavier and far more cumbersome than it should.</p>\n<p>Flattening the view hierarchy will be key to improving flow, and it is currently my top priority. The challenge will be accomplishing this <em>without</em> adding complexity to the parent views.</p>\n<h2>Beyond GrindLab</h2>\n<p>Flow isn&#39;t something you design once and declare finished—it&#39;s something that evolves as the app is used. GrindLab&#39;s flow is serviceable today, but it can, should, and will be better. Each iteration, each round of feedback, sharpens the journey a little more.</p>\n<p>The lessons learned from designing GrindLab&#39;s flow extend well beyond coffee analysis. Whether you&#39;re building a productivity tool, a creative app, or a utility, the same truth applies: users don&#39;t just interact with your features—they also experience the journey between them. Progressive disclosure and single-purpose screens aren&#39;t just design patterns; they&#39;re acknowledgments of how human attention actually works. We can only focus on one thing at a time, and we learn best when complexity reveals itself gradually.</p>\n<p>The temptation to showcase everything your app can do is strong, especially when you&#39;ve poured months into building those capabilities. But restraint is what separates an app that gets opened from one that gets used. Every additional option, every nested view, every fork in the road is a moment where a user might lose their way—or worse, lose interest.</p>\n<p>Flow isn&#39;t about making things simple; it&#39;s about making complex things <em>feel</em> simple. And that&#39;s a design challenge worth grinding over.</p>\n",
      "summary": "Thoughtful UI design should transform complex workflow into a simple, frictionless user journey.",
      "date_published": "2025-09-06T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Design",
        "Engineering",
        "progressive-disclosure",
        "swiftui",
        "user-flow",
        "mobile-ux"
      ],
      "image": "https://nateking-assets.sfo3.cdn.digitaloceanspaces.com/images/grindlab.png"
    },
    {
      "id": "https://www.nateking.dev/blog/grindlab-optimization",
      "url": "https://www.nateking.dev/blog/grindlab-optimization",
      "title": "Design Diaries: Optimization",
      "content_html": "<p>I knew I was facing an uphill battle when I began designing the coffee analysis engine in <strong>GrindLab</strong>. How do you run sophisticated particle analysis algorithms, often run by powerful desktop hardware, on a power-constrained iPhone? In my <a href=\"https://www.nateking.dev/blog/start-your-engines\">previous post</a>, I briefly mentioned that my first implementation took fifteen minutes to process a single high-resolution image on an iPhone 15 Pro. This is the story of how I optimized a complex image processing pipeline to run smoothly on mobile hardware.</p>\n<p>The idea that immediately came to mind was to simply downsample the image. It seemed elegant—halving the vertical and horizontal dimensions would result in one-quarter of the original pixels to process. My first test revealed two fundamental problems with the approach. Coffee grounds at espresso fineness can be as small as 200 microns. Even at full resolution these particles often only consist of a few pixels. Downsample too aggressively, and these particles vanish entirely. Processing an image at a different resolution it is displayed at created enormous complexity when trying to map the particles back over the original image shown in the user interface. I needed to stop and completely rethink my approach.</p>\n<h2>Setting the Foundation</h2>\n<p>The single biggest win came from abandoning UIKit&#39;s comfortable abstractions. Instead of working with <code>UIImage</code> objects and per-pixel operations, I switched to raw, contiguous grayscale buffers <code>([UInt8])</code>. This eliminated the overhead of repeated UIImage/CIImage conversions and color space transformations:</p>\n<pre><code class=\"language-swift\">// Before: Expensive per-pixel UIKit operations\nfor pixel in image.pixels {\n    let color = pixel.getColor()\n    // Process...\n}\n\n// After: Direct buffer manipulation\nwithUnsafeMutableBufferPointer { buffer in\n    for i in stride(from: 0, to: pixelCount, by: 4) {\n        // Process 4 pixels at once\n    }\n}\n</code></pre>\n<p>Apple&#39;s <a href=\"https://developer.apple.com/documentation/accelerate\">Accelerate framework</a>, particularly vImage, became my secret weapon. These APIs leverage SIMD instructions and are hand-optimized for Apple Silicon. I replaced every computationally intensive loop with its vImage equivalent:</p>\n<ul>\n<li><strong>Thresholding:</strong> <code>vImageThreshold_*</code> replaced nested loops required for adaptive thresholding</li>\n<li><strong>Morphology:</strong> <code>vImageDilate</code>/<code>vImageErode</code> for separating touching particles</li>\n<li><strong>Histograms:</strong> <code>vDSP</code> for statistical analysis</li>\n</ul>\n<p>The morphology changes were particularly transformative. Separating clumps—essential for accurate particle sizing—became nearly four times faster.</p>\n<h2>The Art of Doing Less</h2>\n<p>Not all pixels in an image are equal. After initial preprocessing, I implemented region-of-interest cropping to focus only on the area containing coffee. If coffee grounds only occupy 60% of the image, I could immediately remove 40% from <em>all downstream computation.</em></p>\n<p>I also adopted a progressive filtering strategy. Immediate noise rejection and particle quality checks ensure that the computationally expensive downstream processes like convex hull and advanced shape descriptors are only completed for promising candidates.</p>\n<h2>The Parallelization Trap and Synchronization Tax</h2>\n<p>One of the most seductive optimization strategies in modern programming is parallelization. With iPhones sporting 6-8 CPU cores, it seems obvious: spread the work across all cores and watch your code fly, right? Not so fast. Let me share a cautionary tale from optimizing GrindLab&#39;s particle detection that perfectly illustrates why parallelization often creates more problems than it solves.</p>\n<p>When I profiled my particle detection algorithm, I saw that 60% of the time was spent flood-filling regions to identify individual coffee particles. The algorithm visits every pixel, checking if it belongs to a particle, and if so, which particle. With a 12MP image, that&#39;s millions of pixels to check.</p>\n<p>My first instinct was to divide the image into quadrants, assign each to a thread, and reap a 4x speed improvement. Here&#39;s what it looked like in simplified form:</p>\n<pre><code class=\"language-swift\">// The &quot;obvious&quot; parallel approach\nlet tileCount = ProcessInfo.processInfo.activeProcessorCount\nDispatchQueue.concurrentPerform(iterations: tileCount) { tileIndex in\n    let tileRange = getTileRange(for: tileIndex)\n\n    for pixel in tileRange {\n        if isParticle(pixel) {\n            assignToCluster(pixel)\n        }\n    }\n}\n</code></pre>\n<p>Numerous bugs appeared on the first test. When a particle straddled the boundary between two tiles, both threads would attempt to claim it. Now, I had dozens of single coffee particles with multiple particle IDs and no clear method of deduplication.</p>\n<p>My second iteration added synchronization and particle locking. The duplicate particles disappeared, but so did my performance. The multi-thread synchronization and particle locks became a bottleneck, and threads spent more time waiting than processing particles.</p>\n<p>Attempting to reduce particle contention led to even more complexity. Now, each thread needed its own data structures:</p>\n<pre><code class=\"language-swift\">struct ThreadContext {\n    var localLabels: [Int: Int]  // Local label mapping\n    var visitedPixels: Set&lt;Int&gt;  // Track what we&#39;ve seen\n    var borderPixels: [(pixel: Int, label: Int)]  // Particles at tile edges\n    var localParticleData: [ParticleInfo]  // Temporary particle storage\n}\n\n// Merge phase\nfunc mergeThreadResults(_ contexts: [ThreadContext]) {\n    // Reconcile different labels for the same particle\n    // Merge particles that span tile boundaries\n    // Resolve conflicts in visited pixels\n    // Combine particle statistics\n    // ... 200 lines of complex merge logic\n}\n</code></pre>\n<p>The logic required to merge particles became more complex than the original single-threaded algorithm. Debugging was a nightmare—particles would randomly merge or split depending on the particular thread scheduling of each run.</p>\n<p>My solution for particle detection is to keep it single-threaded but optimize the algorithm itself. This included implementing a path/cost-based separator, but most importantly, limiting its use to a small set of &quot;suspicious&quot; components (large area, low circularity, multi-modal local histogram).</p>\n<h2>The Wisdom of Selective Parallelization</h2>\n<p>This doesn&#39;t mean parallelization is always wrong. In GrindLab, I successfully parallelize independent row operations and per-particle measurements as these have no shared state.</p>\n<p>The key is recognizing when parallelization&#39;s complexity cost exceeds its performance benefit. For connected components labeling—where every pixel potentially affects every other pixel—the interdependencies make parallelization a poor fit.</p>\n<p>The journey from barely functional to performant required rethinking my assumptions about how image processing should work on mobile. In the end, optimization is as much about strategy as it is about code. Every decision felt less like chasing speed and more about clarifying and distilling the problem. I learned to respect the constraints of mobile hardware and design within them. Sometimes, the most powerful optimizations aren&#39;t the ones that push harder, but the ones that know when to take a step back.</p>\n",
      "summary": "Learning to respect mobile constraints. Optimization in GrindLab wasn't about brute force—it was about learning when to do less, smarter.",
      "date_published": "2025-09-04T00:00:00.000Z",
      "authors": [
        {
          "name": "Nate King"
        }
      ],
      "tags": [
        "Design",
        "Engineering",
        "image-processing",
        "simd",
        "accelerate-framework",
        "mobile-performance"
      ]
    }
  ]
}